Beispiel #1
0
/*
 *  Format an authentication response. This is typically a 401 response code.
 */
static void formatAuthResponse(MaConn *conn, MaAuth *auth, int code, char *msg, char *logMsg)
{
    MaRequest       *req;
#if BLD_FEATURE_AUTH_DIGEST
    char            *qopClass, *nonceStr, *etag;
#endif

    req = conn->request;
    if (logMsg == 0) {
        logMsg = msg;
    }

    mprLog(conn, 3, "formatAuthResponse: code %d, %s\n", code, logMsg);

    if (auth->type == MA_AUTH_BASIC) {
        maSetHeader(conn, 0, "WWW-Authenticate", "Basic realm=\"%s\"", auth->requiredRealm);

#if BLD_FEATURE_AUTH_DIGEST
    } else if (auth->type == MA_AUTH_DIGEST) {

        qopClass = auth->qop;

        /*
         *  Use the etag as our opaque string
         */
        etag = conn->response->etag;
        if (etag == 0) {
            etag = "";
        }
        if (etag[0] == '"') {
            etag = mprStrdup(req, etag);
            etag = mprStrTrim(etag, "\"");
        }
        mprCalcDigestNonce(req, &nonceStr, conn->host->secret, etag, auth->requiredRealm);

        if (strcmp(qopClass, "auth") == 0) {
            maSetHeader(conn, 0, "WWW-Authenticate", "Digest realm=\"%s\", domain=\"%s\", "
                "qop=\"auth\", nonce=\"%s\", opaque=\"%s\", algorithm=\"MD5\", stale=\"FALSE\"", 
                auth->requiredRealm, conn->host->name, nonceStr, etag);

        } else if (strcmp(qopClass, "auth-int") == 0) {
            maSetHeader(conn, 0, "WWW-Authenticate", "Digest realm=\"%s\", domain=\"%s\", "
                "qop=\"auth\", nonce=\"%s\", opaque=\"%s\", algorithm=\"MD5\", stale=\"FALSE\"", 
                auth->requiredRealm, conn->host->name, nonceStr, etag);

        } else {
            maSetHeader(conn, 0, "WWW-Authenticate", "Digest realm=\"%s\", nonce=\"%s\"", auth->requiredRealm, nonceStr);
        }
        mprFree(nonceStr);
#endif
    }

    maFailRequest(conn, code, "Authentication Error: %s", msg);
}
Beispiel #2
0
int MaSslModule::parseConfig(char *key, char *value, MaServer *server, 
	MaHost *host, MaAuth *auth, MaDir *dir, MaLocation *location)
{
	MaSslConfig	*config;
	char		pathBuf[MPR_MAX_FNAME], prefix[MPR_MAX_FNAME];
	char		*tok, *word, *enable, *provider;
	int			protoMask, mask;

	mprStrcpy(prefix, sizeof(prefix), key);
	prefix[3] = '\0';
	if (mprStrCmpAnyCase(prefix, "SSL") != 0) {
		return 0;
	}

	if (mprStrCmpAnyCase(key, "SSLEngine") == 0) {
		enable = mprStrTok(value, " \t", &tok);
		provider = mprStrTok(0, " \t", &tok);
		if (mprStrCmpAnyCase(value, "on") == 0) {
			if (sslProvider == 0) {
				mprError(MPR_L, MPR_LOG, "Missing an SSL Provider\n");
				return MPR_ERR_BAD_SYNTAX;
			}
			config = (MaSslConfig*) sslConfigTable->lookup(host->getName());
			if (config == 0) {
				config = sslProvider->newConfig(host);
				mprAssert(config);
				sslConfigTable->insert(config);
			}
			host->setSecure(1);
			host->server->setSslListeners(host, config);
		}
		return 1;
	}

	config = (MaSslConfig*) sslConfigTable->lookup(host->getName());
	if (config == 0) {
		mprError(MPR_L, MPR_LOG, "Missing SSLEngine directive\n");
		return MPR_ERR_BAD_SYNTAX;
	}

	if (host->makePath(pathBuf, sizeof(pathBuf), mprStrTrim(value, '\"')) 
			== 0) {
		mprError(MPR_L, MPR_LOG, "SSL path is too long");
		return MPR_ERR_BAD_SYNTAX;
    }

	if (mprStrCmpAnyCase(key, "SSLCACertificatePath") == 0) {
		config->setCaPath(pathBuf);
		return 1;

	} else if (mprStrCmpAnyCase(key, "SSLCACertificateFile") == 0) {
		config->setCaFile(pathBuf);
		return 1;

	} else if (mprStrCmpAnyCase(key, "SSLCertificateFile") == 0) {
		config->setCertFile(pathBuf);
		return 1;

	} else if (mprStrCmpAnyCase(key, "SSLCertificateKeyFile") == 0) {
		config->setKeyFile(pathBuf);
		return 1;

	} else if (mprStrCmpAnyCase(key, "SSLCipherSuite") == 0) {
		config->setCipherSuite(value);
		return 1;

	} else if (mprStrCmpAnyCase(key, "SSLVerifyClient") == 0) {
		if (mprStrCmpAnyCase(value, "require") == 0) {
			config->setVerifyClient(1);
		} else if (mprStrCmpAnyCase(value, "none") == 0) {
			config->setVerifyClient(0);
		} else {
			return -1;
		}
		return 1;

	} else if (mprStrCmpAnyCase(key, "SSLProtocol") == 0) {
		protoMask = 0;
		word = mprStrTok(value, " \t", &tok);
		while (word) {
			mask = -1;
			if (*word == '-') {
				word++;
				mask = 0;
			} else if (*word == '+') {
				word++;
			}
			if (mprStrCmpAnyCase(word, "SSLv2") == 0) {
				protoMask &= ~(MPR_HTTP_PROTO_SSLV2 & ~mask);
				protoMask |= (MPR_HTTP_PROTO_SSLV2 & mask);

			} else if (mprStrCmpAnyCase(word, "SSLv3") == 0) {
				protoMask &= ~(MPR_HTTP_PROTO_SSLV3 & ~mask);
				protoMask |= (MPR_HTTP_PROTO_SSLV3 & mask);

			} else if (mprStrCmpAnyCase(word, "TLSv1") == 0) {
				protoMask &= ~(MPR_HTTP_PROTO_TLSV1 & ~mask);
				protoMask |= (MPR_HTTP_PROTO_TLSV1 & mask);

			} else if (mprStrCmpAnyCase(word, "ALL") == 0) {
				protoMask &= ~(MPR_HTTP_PROTO_ALL & ~mask);
				protoMask |= (MPR_HTTP_PROTO_ALL & mask);
			}
			word = mprStrTok(0, " \t", &tok);
		}
		config->setSslProto(protoMask);
		return 1;
	}
	return 0;
}
Beispiel #3
0
/*
 *  Parse the appweb.conf directives for authorization
 */
static int parseAuth(MaHttp *http, cchar *key, char *value, MaConfigState *state)
{
    MaServer    *server;
    MaHost      *host;
    MaAuth      *auth;
    MaAcl       acl;
    char        *path, *names, *tok, *type, *aclSpec;

    server = state->server;
    host = state->host;
    auth = state->auth;

    if (mprStrcmpAnyCase(key, "AuthGroupFile") == 0) {
        path = maMakePath(host, mprStrTrim(value, "\""));
        if (maReadGroupFile(server, auth, path) < 0) {
            mprError(http, "Can't open AuthGroupFile %s", path);
            return MPR_ERR_BAD_SYNTAX;
        }
        mprFree(path);
        return 1;

    } else if (mprStrcmpAnyCase(key, "AuthMethod") == 0) {
        value = mprStrTrim(value, "\"");
        if (mprStrcmpAnyCase(value, "pam") == 0) {
            auth->method = MA_AUTH_METHOD_PAM;
            return 1;

        } else if (mprStrcmpAnyCase(value, "file") == 0) {
            auth->method = MA_AUTH_METHOD_FILE;
            return 1;

        } else {
            return MPR_ERR_BAD_SYNTAX;
        }

    } else if (mprStrcmpAnyCase(key, "AuthName") == 0) {
        maSetAuthRealm(auth, mprStrTrim(value, "\""));
        return 1;
        
    } else if (mprStrcmpAnyCase(key, "AuthType") == 0) {
        value = mprStrTrim(value, "\"");
        if (mprStrcmpAnyCase(value, "Basic") == 0) {
            auth->type = MA_AUTH_BASIC;

        } else if (mprStrcmpAnyCase(value, "None") == 0) {
            auth->type = 0;

#if BLD_FEATURE_AUTH_DIGEST
        } else if (mprStrcmpAnyCase(value, "Digest") == 0) {
            auth->type = MA_AUTH_DIGEST;
#endif

        } else {
            mprError(http, "Unsupported authorization protocol");
            return MPR_ERR_BAD_SYNTAX;
        }
        return 1;
        
    } else if (mprStrcmpAnyCase(key, "AuthUserFile") == 0) {
        path = maMakePath(host, mprStrTrim(value, "\""));
        if (maReadUserFile(server, auth, path) < 0) {
            mprError(http, "Can't open AuthUserFile %s", path);
            return MPR_ERR_BAD_SYNTAX;
        }
        mprFree(path);
        return 1;

#if BLD_FEATURE_AUTH_DIGEST
    } else if (mprStrcmpAnyCase(key, "AuthDigestQop") == 0) {
        value = mprStrTrim(value, "\"");
        mprStrLower(value);
        if (strcmp(value, "none") != 0 && strcmp(value, "auth") != 0 && strcmp(value, "auth-int") != 0) {
            return MPR_ERR_BAD_SYNTAX;
        }
        maSetAuthQop(auth, value);
        return 1;

    } else if (mprStrcmpAnyCase(key, "AuthDigestAlgorithm") == 0) {
        return 1;

    } else if (mprStrcmpAnyCase(key, "AuthDigestDomain") == 0) {
        return 1;

    } else if (mprStrcmpAnyCase(key, "AuthDigestNonceLifetime") == 0) {
        return 1;

#endif
    } else if (mprStrcmpAnyCase(key, "Require") == 0) {
        if (maGetConfigValue(http, &type, value, &tok, 1) < 0) {
            return MPR_ERR_BAD_SYNTAX;
        }
        if (mprStrcmpAnyCase(type, "acl") == 0) {
            aclSpec = mprStrTrim(tok, "\"");
            acl = maParseAcl(auth, aclSpec);
            maSetRequiredAcl(auth, acl);

        } else if (mprStrcmpAnyCase(type, "valid-user") == 0) {
            maSetAuthAnyValidUser(auth);

        } else {
            names = mprStrTrim(tok, "\"");
            if (mprStrcmpAnyCase(type, "user") == 0) {
                maSetAuthRequiredUsers(auth, names);

            } else if (mprStrcmpAnyCase(type, "group") == 0) {
                maSetAuthRequiredGroups(auth, names);

            } else {
                mprError(http, "Bad Require syntax: %s", type);
                return MPR_ERR_BAD_SYNTAX;
            }
        }
        return 1;
    }
    return 0;
}
Beispiel #4
0
static int parseEjs(MaHttp *http, cchar *key, char *value, MaConfigState *state)
{
    MaLocation      *location;
    MaServer        *server;
    MaHost          *host;
    char            *prefix, *path;
    int             flags;
    
    host = state->host;
    server = state->server;
    location = state->location;
    
    flags = location->flags & (MA_LOC_BROWSER | MA_LOC_AUTO_SESSION);

#if UNUSED
    MaStage         *ejsHandler;
    EjsWebControl   *web;
    if (mprStrcmpAnyCase(key, "Ejs") == 0) {
        path = mprStrTrim(value, "\"");
        mprCleanFilename(http, path);
        if (!mprAccess(http, path, X_OK)) {
            mprError(http, "Can't access Ejs path %s", path);
            return MPR_ERR_BAD_SYNTAX;
        }
        if ((ejsHandler = maLookupStage(http, "ejsHandler")) == 0) {
            mprError(http, "Ejscript module is not loaded");
            return MPR_ERR_BAD_SYNTAX;
        }
        web = (EjsWebControl*) ejsHandler->stageData;
        web->ejsLibDir = path;

    } else 
#endif
    if (mprStrcmpAnyCase(key, "EjsApp") == 0) {
        if (mprStrcmpAnyCase(value, "on") == 0) {
            location->flags |= MA_LOC_APP;
        } else {
            location->flags &= ~MA_LOC_APP;
        }
        return 1;

    } else if (mprStrcmpAnyCase(key, "EjsAppDir") == 0) {
        if (mprStrcmpAnyCase(value, "on") == 0) {
            location->flags |= MA_LOC_APP_DIR;
        } else {
            location->flags &= ~MA_LOC_APP_DIR;
        }
        return 1;

    } else if (mprStrcmpAnyCase(key, "EjsAppAlias") == 0) {
        if (maSplitConfigValue(server, &prefix, &path, value, 1) < 0 || path == 0 || prefix == 0) {
            return MPR_ERR_BAD_SYNTAX;
        }
        location = maCreateLocationAlias(http, state, prefix, path, "ejsHandler", MA_LOC_APP | flags);
        if (location == 0) {
            return MPR_ERR_BAD_SYNTAX;
        }
        return 1;

    } else if (mprStrcmpAnyCase(key, "EjsAppDirAlias") == 0) {
        if (maSplitConfigValue(server, &prefix, &path, value, 1) < 0 || path == 0 || prefix == 0) {
            return MPR_ERR_BAD_SYNTAX;
        }
        location = maCreateLocationAlias(http, state, prefix, path, "ejsHandler", MA_LOC_APP_DIR | flags);
        if (location == 0) {
            return MPR_ERR_BAD_SYNTAX;
        }
        return 1;

    } else if (mprStrcmpAnyCase(key, "EjsErrors") == 0) {
        if (mprStrcmpAnyCase(value, "browser") == 0) {
            location->flags |= MA_LOC_BROWSER;
        } else {
            location->flags &= ~MA_LOC_BROWSER;
        }
        return 1;

    } else if (mprStrcmpAnyCase(key, "EjsSessionTimeout") == 0) {
        if (value == 0) {
            return MPR_ERR_BAD_SYNTAX;
        }
        if (! mprGetDebugMode(http)) {
            location->sessionTimeout = atoi(mprStrTrim(value, "\""));
        }
        return 1;

    } else if (mprStrcmpAnyCase(key, "EjsSession") == 0) {
        if (mprStrcmpAnyCase(value, "on") == 0) {
            location->flags |= MA_LOC_AUTO_SESSION;
        } else {
            location->flags &= ~MA_LOC_AUTO_SESSION;
        }
        return 1;
    }

    return 0;
}
Beispiel #5
0
/*
 *  When we come here, we've already matched either a location block or an extension
 */
static int run(request_rec *r) 
{
    EjsDirConfig        *dir;
    EjsServerConfig     *server;
    cchar               *ext;

    MaRequest       *req;
    MaResponse      *resp;
    MaConn          *conn;
    MaAlias         *alias;
    MaLocation      *location;
    EjsWeb          *web;
    cchar           *sep, *prefix;
    char            *urlBase, *dir, *app, *url, *cp;
    int             flags, locFlags;

    if (!r->handler || strcasecmp(r->handler, "ejs") != 0) {
        return DECLINED;
    }

    dir = getDir(r)
    server = getServer(r->XXX);

    //  EjsAlias should probably be creating a directory block. These flags should probably be in a directory
    if (loc->flags & (MA_LOC_APP | MA_LOC_APP_DIR)) {

        /*
         *  Send non-ejs content under web to another handler, typically the file handler.
         */
        if (strncmp(&req->url[loc->prefixLen], "web/", 4) == 0) {
            if (!(ext && strcmp(ext, "ejs") == 0)) {
                return DECLINED;
            }

        } else {
            if (ext && strcmp(ext, "ejs") == 0) {
                maFormatBody(conn, "Bad Request", "Can't serve *.ejs files outside web directory");
                maFailRequest(conn, MPR_HTTP_CODE_BAD_REQUEST, "Can't server *.ejs files outside web directory");
                return HTTP_XXX;
            }
        }
    }

    flags = 0;
    url = 0;

    locFlags = location->flags;
    
    if (locFlags & MA_LOC_APP) {
        app = mprStrTrim(mprStrdup(q, prefix), "/");
        url = &req->url[alias->prefixLen];
        dir = mprStrdup(resp, alias->filename);
        if (*url != '/') {
            url--;
        }
        urlBase = mprStrdup(resp, prefix);
        
    } else if (locFlags & MA_LOC_APP_DIR) {
        url = &req->url[alias->prefixLen];
        app = mprStrdup(resp, url);
        if ((cp = strchr(app, '/')) != 0) {
            url = mprStrdup(resp, cp);
            *cp = '\0';
        }
        sep = prefix[strlen(prefix) - 1] == '/' ? "" : "/";
        dir = mprStrcat(resp, &dir, alias->filename, sep, app, NULL);
        urlBase = mprStrcat(resp, prefix, sep, app, NULL);

    } else {
        app = 0;
        dir = mprStrdup(resp, alias->filename);
        url = &req->url[alias->prefixLen];
        flags |= EJS_WEB_FLAG_SOLO;
        if (*url != '/') {
            url--;
        }        
        urlBase = mprStrdup(resp, prefix);
    }
    mprStrTrim(urlBase, "/");
    mprStrTrim(dir, "/");
    
    if (location->flags & MA_LOC_BROWSER) {
        flags |= EJS_WEB_FLAG_BROWSER_ERRORS;
    }
    if (location->flags & MA_LOC_AUTO_SESSION) {
        flags |= EJS_WEB_FLAG_SESSION;
    }

    /*
     *  Var         Stand-Alone             App                         AppDir
     *  app         0                       carmen                      carmen
     *  dir         /Users/mob/....         /Users/mob/hg/carmen        /Users/mob/hg/carmen
     *  urlBase                             /xg/carmen                  /carmen
     *  url                                 stock                       stock
     */
    web = ejsCreateWebRequest(req, q->stage->stageData, conn, app, dir, urlBase, url, req->cookie, flags);
    if (web == 0) {
        maFailRequest(conn, MPR_HTTP_CODE_INTERNAL_SERVER_ERROR, "Can't create Ejs web object for %s", req->url);
        return;
    }
    q->queueData = web;
    maSetHeader(conn, 0, "Last-Modified", req->host->currentDate);
    maDontCacheResponse(conn);

    if (r->method_number != M_GET) {
        return HTTP_METHOD_NOT_ALLOWED;
    }

    if (ejsProcessWebRequest((EjsWeb*) r, &msg) < 0) {
        if (web->flags & EJS_WEB_FLAG_BROWSER_ERRORS) {
            maFormatBody(conn, "Request Failed", "%s", msg);
        }
        maFailRequest(conn, MPR_HTTP_CODE_BAD_GATEWAY, msg);
        mprFree(msg);
    }

    ap_set_content_type(r, "text/html");
    ap_rputs("<html><title>Hello World!</title><body><p>Hello World</p></body></html>\r\n", r);

#if 0
    if ((err = set_content_length(r, r->finfo.st_stize)) || (err = set_last_modified(r, r->finfo.st_mtime)))
        return err;
    if (r->finof.st_mode == 0) 
        return NOT_FOUND;
    fopen(r->filename, "r");

    if (!r->main) {
        /* Not internal redirect */
        apr_table_set(r->headers_out, "X-ejs", "Under construction");
    }
    register_timeout("send", r);
    send_http_header(r);
    if (!r->header_only)
        send_fd(f, r);
    pfclose(r->pool, f);
#endif

    return OK;
}
Beispiel #6
0
static int parseEjs(MaHttp *http, cchar *key, char *value, MaConfigState *state)
{
    MaLocation      *location;
    MaServer        *server;
    MaHost          *host;
    char            *prefix, *path;
    int             flags;
    
    host = state->host;
    server = state->server;
    location = state->location;
    
    flags = location->flags & (MA_LOC_BROWSER | MA_LOC_AUTO_SESSION);

    if (mprStrcmpAnyCase(key, "EjsApp") == 0) {
        if (mprStrcmpAnyCase(value, "on") == 0) {
            location->flags |= MA_LOC_APP;
        } else {
            location->flags &= ~MA_LOC_APP;
        }
        return 1;

    } else if (mprStrcmpAnyCase(key, "EjsAppDir") == 0) {
        if (mprStrcmpAnyCase(value, "on") == 0) {
            location->flags |= MA_LOC_APP_DIR;
        } else {
            location->flags &= ~MA_LOC_APP_DIR;
        }
        return 1;

    } else if (mprStrcmpAnyCase(key, "EjsAppAlias") == 0) {
        if (maSplitConfigValue(server, &prefix, &path, value, 1) < 0 || path == 0 || prefix == 0) {
            return MPR_ERR_BAD_SYNTAX;
        }
        location = maCreateLocationAlias(http, state, prefix, path, "ejsHandler", MA_LOC_APP | flags);
        if (location == 0) {
            return MPR_ERR_BAD_SYNTAX;
        }
        return 1;

    } else if (mprStrcmpAnyCase(key, "EjsAppDirAlias") == 0) {
        if (maSplitConfigValue(server, &prefix, &path, value, 1) < 0 || path == 0 || prefix == 0) {
            return MPR_ERR_BAD_SYNTAX;
        }
        location = maCreateLocationAlias(http, state, prefix, path, "ejsHandler", MA_LOC_APP_DIR | flags);
        if (location == 0) {
            return MPR_ERR_BAD_SYNTAX;
        }
        return 1;

    } else if (mprStrcmpAnyCase(key, "EjsErrors") == 0) {
        if (mprStrcmpAnyCase(value, "browser") == 0) {
            location->flags |= MA_LOC_BROWSER;
        } else {
            location->flags &= ~MA_LOC_BROWSER;
        }
        return 1;

    } else if (mprStrcmpAnyCase(key, "EjsSessionTimeout") == 0) {
        if (value == 0) {
            return MPR_ERR_BAD_SYNTAX;
        }
        if (! mprGetDebugMode(http)) {
            location->sessionTimeout = atoi(mprStrTrim(value, "\""));
        }
        return 1;

    } else if (mprStrcmpAnyCase(key, "EjsSession") == 0) {
        if (mprStrcmpAnyCase(value, "on") == 0) {
            location->flags |= MA_LOC_AUTO_SESSION;
        } else {
            location->flags &= ~MA_LOC_AUTO_SESSION;
        }
        return 1;
    }

    return 0;
}