📄 ssl_engine_kernel.c
字号:
return FORBIDDEN; } ssl_log(r->server, SSL_LOG_INFO, "Awaiting re-negotiation handshake"); SSL_set_state(ssl, SSL_ST_ACCEPT); SSL_do_handshake(ssl); if (SSL_get_state(ssl) != SSL_ST_OK) { ssl_log(r->server, SSL_LOG_ERROR, "Re-negotiation handshake failed: Not accepted by client!?"); return FORBIDDEN; } } /* * Remember the peer certificate's DN */ if ((cert = SSL_get_peer_certificate(ssl)) != NULL) { cp = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); ap_ctx_set(r->connection->client->ctx, "ssl::client::dn", ap_pstrdup(r->connection->pool, cp)); OPENSSL_free(cp); X509_free(cert); } /* * Finally check for acceptable renegotiation results */ if (dc->nVerifyClient != SSL_CVERIFY_NONE) { if ( dc->nVerifyClient == SSL_CVERIFY_REQUIRE && SSL_get_verify_result(ssl) != X509_V_OK ) { ssl_log(r->server, SSL_LOG_ERROR, "Re-negotiation handshake failed: Client verification failed"); return FORBIDDEN; } cert = SSL_get_peer_certificate(ssl); if ( dc->nVerifyClient == SSL_CVERIFY_REQUIRE && cert == NULL) { ssl_log(r->server, SSL_LOG_ERROR, "Re-negotiation handshake failed: Client certificate missing"); return FORBIDDEN; } if (cert != NULL) X509_free(cert); } /* * Also check that SSLCipherSuite has been enforced as expected */ if (skCipher != NULL) { pCipher = SSL_get_current_cipher(ssl); if (sk_SSL_CIPHER_find(skCipher, pCipher) < 0) { ssl_log(r->server, SSL_LOG_ERROR, "SSL cipher suite not renegotiated: " "access to %s denied using cipher %s", r->filename, SSL_CIPHER_get_name(pCipher)); return FORBIDDEN; } } } /* * Under old OpenSSL we had to change the X509_STORE inside the * SSL_CTX instead inside the SSL structure, so we have to reconfigure it * to the old values. This should be changed with forthcoming OpenSSL * versions when better functionality is avaiable. */#ifdef SSL_EXPERIMENTAL_PERDIRCA if (renegotiate && reconfigured_locations) { if (!SSL_CTX_load_verify_locations(ctx, sc->szCACertificateFile, sc->szCACertificatePath)) { ssl_log(r->server, SSL_LOG_ERROR|SSL_ADD_SSLERR, "Unable to reconfigure verify locations " "to per-server configuration parameters"); return FORBIDDEN; } }#endif /* SSL_EXPERIMENTAL_PERDIRCA */ /* * Check SSLRequire boolean expressions */ apRequirement = dc->aRequirement; pRequirements = (ssl_require_t *)apRequirement->elts; for (i = 0; i < apRequirement->nelts; i++) { pRequirement = &pRequirements[i]; ok = ssl_expr_exec(r, pRequirement->mpExpr); if (ok < 0) { cp = ap_psprintf(r->pool, "Failed to execute SSL requirement expression: %s", ssl_expr_get_error()); ap_log_reason(cp, r->filename, r); /* remember forbidden access for strict require option */ ap_table_setn(r->notes, "ssl-access-forbidden", (void *)1); return FORBIDDEN; } if (ok != 1) { ssl_log(r->server, SSL_LOG_INFO, "Access to %s denied for %s (requirement expression not fulfilled)", r->filename, r->connection->remote_ip); ssl_log(r->server, SSL_LOG_INFO, "Failed expression: %s", pRequirement->cpExpr); ap_log_reason("SSL requirement expression not fulfilled " "(see SSL logfile for more details)", r->filename, r); /* remember forbidden access for strict require option */ ap_table_setn(r->notes, "ssl-access-forbidden", (void *)1); return FORBIDDEN; } } /* * Else access is granted from our point of view (except vendor * handlers override). But we have to return DECLINED here instead * of OK, because mod_auth and other modules still might want to * deny access. */ rc = DECLINED;#ifdef SSL_VENDOR ap_hook_use("ap::mod_ssl::vendor::access_handler", AP_HOOK_SIG2(int,ptr), AP_HOOK_DECLINE(DECLINED), &rc, r);#endif return rc;}/* * Auth Handler: * Fake a Basic authentication from the X509 client certificate. * * This must be run fairly early on to prevent a real authentication from * occuring, in particular it must be run before anything else that * authenticates a user. This means that the Module statement for this * module should be LAST in the Configuration file. */int ssl_hook_Auth(request_rec *r){ SSLSrvConfigRec *sc = mySrvConfig(r->server); SSLDirConfigRec *dc = myDirConfig(r); char *clientdn; const char *cpAL; const char *cpUN; const char *cpPW; /* * Additionally forbid access (again) * when strict require option is used. */ if ( (dc->nOptions & SSL_OPT_STRICTREQUIRE) && (ap_table_get(r->notes, "ssl-access-forbidden") != NULL)) return FORBIDDEN; /* * Make sure the user is not able to fake the client certificate * based authentication by just entering an X.509 Subject DN * ("/XX=YYY/XX=YYY/..") as the username and "password" as the * password. */ if ( ap_is_initial_req(r) && (cpAL = ap_table_get(r->headers_in, "Authorization")) != NULL) { if (strcEQ(ap_getword(r->pool, &cpAL, ' '), "Basic")) { while (*cpAL == ' ' || *cpAL == '\t') cpAL++; cpAL = ap_pbase64decode(r->pool, cpAL); cpUN = ap_getword_nulls(r->pool, &cpAL, ':'); cpPW = cpAL; if (cpUN[0] == '/' && strEQ(cpPW, "password")) { ssl_log(r->server, SSL_LOG_WARN, "real Basic Authentication with DN \"%s\" and fake password attempted", cpUN); return FORBIDDEN; } } } /* * We decline operation in various situations... */ if (!sc->bEnabled) return DECLINED; if (ap_ctx_get(r->connection->client->ctx, "ssl") == NULL) return DECLINED; if (!(dc->nOptions & SSL_OPT_FAKEBASICAUTH)) return DECLINED; if (r->connection->user) return DECLINED; if ((clientdn = (char *)ap_ctx_get(r->connection->client->ctx, "ssl::client::dn")) == NULL) return DECLINED; /* * Fake a password - which one would be immaterial, as, it seems, an empty * password in the users file would match ALL incoming passwords, if only * we were using the standard crypt library routine. Unfortunately, OpenSSL * "fixes" a "bug" in crypt and thus prevents blank passwords from * working. (IMHO what they really fix is a bug in the users of the code * - failing to program correctly for shadow passwords). We need, * therefore, to provide a password. This password can be matched by * adding the string "xxj31ZMTZzkVA" as the password in the user file. * This is just the crypted variant of the word "password" ;-) */ cpAL = ap_pstrcat(r->pool, "Basic ", ap_pbase64encode(r->pool, ap_pstrcat(r->pool, clientdn, ":password", NULL)), NULL); ap_table_set(r->headers_in, "Authorization", cpAL); ssl_log(r->server, SSL_LOG_INFO, "Faking HTTP Basic Auth header: \"Authorization: %s\"", cpAL); return DECLINED;}int ssl_hook_UserCheck(request_rec *r){ SSLDirConfigRec *dc = myDirConfig(r); /* * Additionally forbid access (again) * when strict require option is used. */ if ( (dc->nOptions & SSL_OPT_STRICTREQUIRE) && (ap_table_get(r->notes, "ssl-access-forbidden") != NULL)) return FORBIDDEN; return DECLINED;}/* * Fixup Handler */static const char *ssl_hook_Fixup_vars[] = { "SSL_VERSION_INTERFACE", "SSL_VERSION_LIBRARY", "SSL_PROTOCOL", "SSL_CIPHER", "SSL_CIPHER_EXPORT", "SSL_CIPHER_USEKEYSIZE", "SSL_CIPHER_ALGKEYSIZE", "SSL_CLIENT_VERIFY", "SSL_CLIENT_M_VERSION", "SSL_CLIENT_M_SERIAL", "SSL_CLIENT_V_START", "SSL_CLIENT_V_END", "SSL_CLIENT_S_DN", "SSL_CLIENT_S_DN_C", "SSL_CLIENT_S_DN_ST", "SSL_CLIENT_S_DN_L", "SSL_CLIENT_S_DN_O", "SSL_CLIENT_S_DN_OU", "SSL_CLIENT_S_DN_CN", "SSL_CLIENT_S_DN_T", "SSL_CLIENT_S_DN_I", "SSL_CLIENT_S_DN_G", "SSL_CLIENT_S_DN_S", "SSL_CLIENT_S_DN_D", "SSL_CLIENT_S_DN_UID", "SSL_CLIENT_S_DN_Email", "SSL_CLIENT_I_DN", "SSL_CLIENT_I_DN_C", "SSL_CLIENT_I_DN_ST", "SSL_CLIENT_I_DN_L", "SSL_CLIENT_I_DN_O", "SSL_CLIENT_I_DN_OU", "SSL_CLIENT_I_DN_CN", "SSL_CLIENT_I_DN_T", "SSL_CLIENT_I_DN_I", "SSL_CLIENT_I_DN_G", "SSL_CLIENT_I_DN_S", "SSL_CLIENT_I_DN_D", "SSL_CLIENT_I_DN_UID", "SSL_CLIENT_I_DN_Email", "SSL_CLIENT_A_KEY", "SSL_CLIENT_A_SIG", "SSL_SERVER_M_VERSION", "SSL_SERVER_M_SERIAL", "SSL_SERVER_V_START", "SSL_SERVER_V_END", "SSL_SERVER_S_DN", "SSL_SERVER_S_DN_C", "SSL_SERVER_S_DN_ST", "SSL_SERVER_S_DN_L", "SSL_SERVER_S_DN_O", "SSL_SERVER_S_DN_OU", "SSL_SERVER_S_DN_CN", "SSL_SERVER_S_DN_T", "SSL_SERVER_S_DN_I", "SSL_SERVER_S_DN_G", "SSL_SERVER_S_DN_S", "SSL_SERVER_S_DN_D", "SSL_SERVER_S_DN_UID", "SSL_SERVER_S_DN_Email", "SSL_SERVER_I_DN", "SSL_SERVER_I_DN_C", "SSL_SERVER_I_DN_ST", "SSL_SERVER_I_DN_L", "SSL_SERVER_I_DN_O", "SSL_SERVER_I_DN_OU", "SSL_SERVER_I_DN_CN", "SSL_SERVER_I_DN_T", "SSL_SERVER_I_DN_I", "SSL_SERVER_I_DN_G", "SSL_SERVER_I_DN_S", "SSL_SERVER_I_DN_D", "SSL_SERVER_I_DN_UID", "SSL_SERVER_I_DN_Email", "SSL_SERVER_A_KEY", "SSL_SERVER_A_SIG", "SSL_SESSION_ID", NULL};int ssl_hook_Fixup(request_rec *r){ SSLSrvConfigRec *sc = mySrvConfig(r->server); SSLDirConfigRec *dc = myDirConfig(r); table *e = r->subprocess_env; char *var; char *val; STACK_OF(X509) *sk; SSL *ssl; int i; /* * Check to see if SSL is on */ if (!sc->bEnabled) return DECLINED; if ((ssl = ap_ctx_get(r->connection->client->ctx, "ssl")) == NULL) return DECLINED; /* * Annotate the SSI/CGI environment with standard SSL information */ /* the always present HTTPS (=HTTP over SSL) flag! */ ap_table_set(e, "HTTPS", "on"); /* standard SSL environment variables */ if (dc->nOptions & SSL_OPT_STDENVVARS) { for (i = 0; ssl_hook_Fixup_vars[i] != NULL; i++) { var = (char *)ssl_hook_Fixup_vars[i]; val = ssl_var_lookup(r->pool, r->server, r->connection, r, var); if (!strIsEmpty(val)) ap_table_set(e, var, val); } } /* * On-demand bloat up the SSI/CGI environment with certificate data */ if (dc->nOptions & SSL_OPT_EXPORTCERTDATA) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -