protected user Authenticate(DreamContext context, DreamMessage request, DekiUserLevel level)
        {
            user result = null;

            // get username and password
            string user;
            string password;

            if (!DreamUtil.GetAuthentication(context, request, out user, out password))
            {
                // anonymous access is always granted
                if (level == DekiUserLevel.Anonymous)
                {
                    // TODO (steveb): missing code
                    throw new NotImplementedException("return anonymous user");
                }
                else
                {
                    throw new DreamAbortException(DreamMessage.AccessDenied(AuthenticationRealm, "authentication failed"));
                }
            }

            // validate username and password
            result = MindTouch.Deki.user.GetUserByName(user);
            if (result == null)
            {
                throw new DreamAbortException(DreamMessage.AccessDenied(AuthenticationRealm, "authentication failed"));
            }
            if (!result.checkPassword(password))
            {
                throw new DreamAbortException(DreamMessage.AccessDenied(AuthenticationRealm, "authentication failed"));
            }
            if ((level == DekiUserLevel.Admin) && !result.isSysop())
            {
                throw new DreamAbortException(DreamMessage.AccessDenied(AuthenticationRealm, "authentication failed"));
            }
            return(result);
        }
Пример #2
0
        //--- Methods ---
        void IHttpHandler.ProcessRequest(HttpContext httpContext)
        {
            var          key     = new object();
            DreamMessage request = null;

            try {
                string verb       = httpContext.Request.HttpMethod;
                XUri   requestUri = HttpUtil.FromHttpContext(httpContext);
                _env.AddActivityDescription(key, string.Format("Incoming: {0} {1}", verb, requestUri));
                _log.DebugMethodCall("ProcessRequest", verb, requestUri);

                // create request message
                request = new DreamMessage(DreamStatus.Ok, new DreamHeaders(httpContext.Request.Headers), MimeType.New(httpContext.Request.ContentType), httpContext.Request.ContentLength, httpContext.Request.InputStream);
                DreamUtil.PrepareIncomingMessage(request, httpContext.Request.ContentEncoding, string.Format("{0}://{1}{2}", httpContext.Request.Url.Scheme, httpContext.Request.Url.Authority, httpContext.Request.ApplicationPath), httpContext.Request.UserHostAddress, httpContext.Request.UserAgent);

                // TODO (arnec): should this happen before PrepareIncomingMessage?
                request.Headers.DreamTransport = _handler.GetRequestBaseUri(httpContext.Request).ToString();

                // process message
                var response = _env.SubmitRequestAsync(verb, requestUri, httpContext.User, request, new Result <DreamMessage>(TimeSpan.MaxValue)).Block();
                request.Close();
                var item = response.HasException ? DreamMessage.InternalError(response.Exception) : response.Value;

                // set status
                if (_log.IsDebugEnabled)
                {
                    _log.DebugMethodCall("ProcessRequest[Status]", item.Status, String.Format("{0}{1}", httpContext.Request.Url.GetLeftPart(UriPartial.Authority), httpContext.Request.RawUrl).Replace("/index.aspx", "/"));
                }
                httpContext.Response.StatusCode = (int)item.Status;

                // remove internal headers
                item.Headers.DreamTransport = null;
                item.Headers.DreamPublicUri = null;

                // create stream for response (this will force the creation of the 'Content-Length' header as well)
                Stream stream = item.ToStream();

                // copy headers
                foreach (KeyValuePair <string, string> pair in item.Headers)
                {
                    _log.TraceMethodCall("ProcessRequest[Header]", pair.Key, pair.Value);
                    httpContext.Response.AppendHeader(pair.Key, pair.Value);
                }

                // add set-cookie headers to response
                if (item.HasCookies)
                {
                    foreach (DreamCookie cookie in item.Cookies)
                    {
                        httpContext.Response.AppendHeader(DreamHeaders.SET_COOKIE, cookie.ToSetCookieHeader());
                    }
                }

                // send message stream
                long size = item.ContentLength;
                if (((size == -1) || (size > 0)) && (stream != Stream.Null))
                {
                    stream.CopyTo(httpContext.Response.OutputStream, size, new Result <long>(TimeSpan.MaxValue)).Wait();
                }
                item.Close();
            } catch (Exception ex) {
                _log.ErrorExceptionMethodCall(ex, "CommonRequestHandler");
                if (request != null)
                {
                    request.Close();
                }
                if (httpContext != null)
                {
                    httpContext.Response.Close();
                }
            } finally {
                _env.RemoveActivityDescription(key);
            }
        }
Пример #3
0
        private void RequestHandler(IAsyncResult ar)
        {
            HttpListenerContext httpContext = null;
            Action <string>     activity    = null;
            HttpListener        listener    = (HttpListener)ar.AsyncState;

            // try to finish getting the current context
            try {
                httpContext = listener.EndGetContext(ar);
            } catch (Exception e) {
                _log.WarnExceptionFormat(e, "unable to finish acquiring the request context, unable to handle request");
            }

            // start listening for next request
            if (!listener.IsListening)
            {
                _log.Debug("dropping out of request handler, since the listener is no longer listening");
                return;
            }
            try {
                listener.BeginGetContext(RequestHandler, listener);
            } catch (Exception e) {
                _log.WarnExceptionFormat(e, "unable to re-aquire context, dropping out of request handler");
                return;
            }

            // if we didn't succeed in ending the GetContext call, drop out
            if (httpContext == null)
            {
                return;
            }
            DreamMessage request = null;

            try {
                // finish listening for current context
                string[] prefixes = new string[listener.Prefixes.Count];
                listener.Prefixes.CopyTo(prefixes, 0);
                XUri requestUri = HttpUtil.FromHttpContext(httpContext);
                _log.DebugMethodCall("RequestHandler", httpContext.Request.HttpMethod, requestUri);

                // create request message
                request = new DreamMessage(DreamStatus.Ok, new DreamHeaders(httpContext.Request.Headers), MimeType.New(httpContext.Request.ContentType), httpContext.Request.ContentLength64, httpContext.Request.InputStream);
                DreamUtil.PrepareIncomingMessage(request, httpContext.Request.ContentEncoding, prefixes[0], httpContext.Request.RemoteEndPoint.ToString(), httpContext.Request.UserAgent);
                requestUri = requestUri.AuthorizeDreamInParams(request, _dreamInParamAuthtoken);

                // check if the request was forwarded through Apache mod_proxy
                string hostname = requestUri.GetParam(DreamInParam.HOST, null) ?? request.Headers.ForwardedHost ?? request.Headers.Host ?? requestUri.HostPort;
                activity = new ActivityState(_env, httpContext.Request.HttpMethod, httpContext.Request.Url.ToString(), hostname).Message;
                activity("RequestHandler");

                // process message
                _env.UpdateInfoMessage(_sourceExternal, null);
                string verb = httpContext.Request.HttpMethod;
                _env.SubmitRequestAsync(verb, requestUri, httpContext.User, request, new Result <DreamMessage>(TimeSpan.MaxValue))
                .WhenDone(result => Coroutine.Invoke(ResponseHandler, request, result, httpContext, activity, new Result(TimeSpan.MaxValue)));
            } catch (Exception ex) {
                _log.ErrorExceptionMethodCall(ex, "RequestHandler");
                if (request != null)
                {
                    request.Close();
                }
                try {
                    DreamMessage response = DreamMessage.InternalError(ex);
                    httpContext.Response.StatusCode = (int)response.Status;
                    Stream stream = response.ToStream();
                    httpContext.Response.Headers.Clear();
                    foreach (KeyValuePair <string, string> pair in response.Headers)
                    {
                        HttpUtil.AddHeader(httpContext.Response, pair.Key, pair.Value);
                    }
                    httpContext.Response.KeepAlive = false;
                    long size = response.ContentLength;
                    if (((size == -1) || (size > 0)) && (stream != Stream.Null))
                    {
                        CopyStream(delegate { }, stream, httpContext.Response.OutputStream, size, new Result <long>(DreamHostService.MAX_REQUEST_TIME)).Block();
                    }
                    httpContext.Response.OutputStream.Flush();
                } catch {
                    httpContext.Response.StatusCode = (int)DreamStatus.InternalError;
                }
                httpContext.Response.Close();
                if (activity != null)
                {
                    activity(null);
                }
            }
        }
        private static void ReadWikiSettings(XDoc wikiInit)
        {
            string dbName = string.Empty, user = string.Empty, pwd = string.Empty, proxyKey = string.Empty, server = string.Empty;
            string serverPort = string.Empty, sitename = string.Empty, adminDbUser = string.Empty, adminDbPassword = string.Empty;

            string       baseDir = string.Empty, fullName = string.Empty;
            const string fileName      = "LocalSettings.php";
            const string adminFileName = "AdminSettings.php";

            // BUGBUGBUG (steveb): why is this hard coded?
            baseDir = wikiInit["deki-path"].AsText ?? (Environment.OSVersion.Platform != PlatformID.Unix ? @"C:\wiki\root" : @"/var/www/mks-wiki");

            fullName = System.IO.Path.Combine(baseDir, fileName);
            if (!System.IO.File.Exists(fullName))
            {
                LogUtils.LogWarning(_log, "ReadWikiSettings: File not found", fullName);
                return;
            }
            foreach (string line in DreamUtil.ReadAllLines(fullName, System.Text.Encoding.Default))
            {
                if (line.StartsWith("$IP"))
                {
                    baseDir = GetValueFromConfigLine(line);
                }
                if (line.StartsWith("$wgDBname"))
                {
                    dbName = GetValueFromConfigLine(line);
                }
                if (line.StartsWith("$wgDBuser"))
                {
                    user = GetValueFromConfigLine(line);
                }
                if (line.StartsWith("$wgDBpassword"))
                {
                    pwd = GetValueFromConfigLine(line);
                }
                if (line.StartsWith("$wgProxyKey"))
                {
                    proxyKey = GetValueFromConfigLine(line);
                }
                if (line.StartsWith("$wgDBserver"))
                {
                    server = GetValueFromConfigLine(line);
                }
                if (line.StartsWith("$wgSitename"))
                {
                    sitename = GetValueFromConfigLine(line);
                }
            }
            string fullAdminFileName = System.IO.Path.Combine(baseDir, adminFileName);

            if (System.IO.File.Exists(fullAdminFileName))
            {
                foreach (string line in DreamUtil.ReadAllLines(fullAdminFileName, System.Text.Encoding.Default))
                {
                    if (line.StartsWith("$wgDBadminuser"))
                    {
                        adminDbUser = GetValueFromConfigLine(line);
                    }
                    if (line.StartsWith("$wgDBadminpassword"))
                    {
                        adminDbPassword = GetValueFromConfigLine(line);
                    }
                }
            }
            if (wikiInit["deki-path"].IsEmpty)
            {
                wikiInit.Start("deki-path").Value(baseDir).End();
            }
            else
            {
                wikiInit["deki-path"].Value(baseDir);
            }
            wikiInit
            .Start("deki-dbserver").Value(server).End()
            .Start("deki-dbport").Value(serverPort).End()
            .Start("deki-dbname").Value(dbName).End()
            .Start("deki-dbuser").Value(user).End()
            .Start("deki-dbpassword").Attr("hidden", "true").Value(pwd).End()
            .Start("deki-proxykey").Value(proxyKey).End()
            .Start("deki-sitename").Value(sitename).End()

            .Start("admin-db-user").Attr("hidden", "true").Value(adminDbUser).End()
            .Start("admin-db-password").Attr("hidden", "true").Value(adminDbPassword).End()
            ;
        }