- Timestamp:
- Apr 21, 2005, 8:26:57 PM (18 years ago)
- Branches:
- asyncio, debian/master, debian/stretch-backports, jessie-backports, master, msva, proxy-ticket, upstream
- Children:
- 316bd8c
- Parents:
- 31645b2
- Location:
- src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/gnutls_io.c
r31645b2 re924ddd 359 359 int errcode; 360 360 if (ctxt->status != 0) { 361 return 0;361 return -1; 362 362 } 363 363 364 364 tryagain: 365 366 ret = gnutls_handshake(ctxt->session); 365 do { 366 ret = gnutls_handshake(ctxt->session); 367 } while (ret == GNUTLS_E_AGAIN); 368 367 369 if (ret < 0) { 368 370 if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED … … 393 395 /* all done with the handshake */ 394 396 ctxt->status = 1; 395 return ret;397 return 0; 396 398 } 397 399 } … … 412 414 ctxt->status = 0; 413 415 414 gnutls_do_handshake(ctxt); 415 416 if (ctxt->status == 1) { 417 return 0; 418 } 419 else { 420 return -1; 421 } 416 rv = gnutls_do_handshake(ctxt); 417 418 return rv; 422 419 } 423 420 -
src/mod_gnutls.c
r31645b2 re924ddd 17 17 18 18 #include "mod_gnutls.h" 19 #include "http_vhost.h" 19 20 20 21 extern server_rec *ap_server_conf; … … 112 113 { 113 114 int rv; 115 int data_len; 114 116 server_rec *s; 115 117 gnutls_dh_params_t dh_params; … … 216 218 exit(-1); 217 219 } 218 { 219 int rv; 220 int data_len = 255; 221 char crt_name[255]; 222 for (rv = 0; rv < data_len; rv++) { 223 crt_name[rv] = '\0'; 224 } 225 rv = gnutls_x509_crt_get_dn_by_oid(sc->cert_x509, 226 GNUTLS_OID_X520_COMMON_NAME, 0, 0, 227 crt_name, &data_len); 228 220 221 rv = gnutls_x509_crt_get_dn_by_oid(sc->cert_x509, 222 GNUTLS_OID_X520_COMMON_NAME, 0, 0, 223 NULL, &data_len); 224 225 if (data_len < 1) { 226 sc->enabled = GNUTLS_ENABLED_FALSE; 227 sc->cert_cn = NULL; 228 continue; 229 } 230 231 sc->cert_cn = apr_palloc(p, data_len); 232 rv = gnutls_x509_crt_get_dn_by_oid(sc->cert_x509, 233 GNUTLS_OID_X520_COMMON_NAME, 0, 0, 234 sc->cert_cn, &data_len); 229 235 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 230 236 s, 231 "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X sc: 0x%08X", crt_name, rv,237 "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X sc: 0x%08X", sc->cert_cn, rv, 232 238 gnutls_pk_algorithm_get_name(gnutls_x509_privkey_get_pk_algorithm(sc->privkey_x509)), 233 239 (unsigned int)s, (unsigned int)sc); 234 }235 240 } 236 241 } … … 288 293 } 289 294 295 static void mod_gnutls_changed_servers(mod_gnutls_handle_t *ctxt) 296 { 297 gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE, ctxt->sc->certs); 298 gnutls_certificate_server_set_request(ctxt->session, ctxt->sc->client_verify_mode); 299 } 300 290 301 #define MAX_HOST_LEN 255 302 303 #if USING_2_1_RECENT 304 typedef struct 305 { 306 mod_gnutls_handle_t *ctxt; 307 gnutls_retr_st* ret; 308 const char* sni_name; 309 } vhost_cb_rec; 310 311 int vhost_cb (void* baton, conn_rec* conn, server_rec* s) 312 { 313 mod_gnutls_srvconf_rec *tsc; 314 vhost_cb_rec* x = baton; 315 316 tsc = (mod_gnutls_srvconf_rec *) ap_get_module_config(s->module_config, 317 &gnutls_module); 318 319 if (tsc->enabled != GNUTLS_ENABLED_TRUE || tsc->cert_cn == NULL) { 320 return 0; 321 } 322 323 /* The CN can contain a * -- this will match those too. */ 324 if (ap_strcasecmp_match(x->sni_name, tsc->cert_cn) == 0) { 325 /* found a match */ 326 x->ret->cert.x509 = &tsc->cert_x509; 327 x->ret->key.x509 = tsc->privkey_x509; 328 #if MOD_GNUTLS_DEBUG 329 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 330 x->ctxt->c->base_server, 331 "GnuTLS: Virtual Host CB: " 332 "'%s' == '%s'", tsc->cert_cn, x->sni_name); 333 #endif 334 /* Because we actually change the server used here, we need to reset 335 * things like ClientVerify. 336 */ 337 x->ctxt->sc = tsc; 338 mod_gnutls_changed_servers(x->ctxt); 339 return 1; 340 } 341 return 0; 342 } 343 #endif 344 291 345 static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st* ret) 292 346 { … … 295 349 int data_len = MAX_HOST_LEN; 296 350 char sni_name[MAX_HOST_LEN]; 297 char crt_name[MAX_HOST_LEN];298 351 mod_gnutls_handle_t *ctxt; 299 mod_gnutls_srvconf_rec *tsc; 352 #if USING_2_1_RECENT 353 vhost_cb_rec cbx; 354 #else 300 355 server_rec* s; 356 mod_gnutls_srvconf_rec *tsc; 357 #endif 301 358 302 359 ctxt = gnutls_transport_get_ptr(session); … … 334 391 * for this IP/Port combo. Trust that the core did the 'right' thing. 335 392 */ 393 #if USING_2_1_RECENT 394 cbx.ctxt = ctxt; 395 cbx.ret = ret; 396 cbx.sni_name = sni_name; 397 398 rv = ap_vhost_iterate_given_conn(ctxt->c, vhost_cb, &cbx); 399 if (rv == 1) { 400 return 0; 401 } 402 #else 336 403 for (s = ap_server_conf; s; s = s->next) { 337 404 … … 341 408 continue; 342 409 } 343 344 data_len = MAX_HOST_LEN; 345 rv = gnutls_x509_crt_get_dn_by_oid(tsc->cert_x509, 346 GNUTLS_OID_X520_COMMON_NAME, 0, 0, 347 crt_name, &data_len); 410 #if MOD_GNUTLS_DEBUG 348 411 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 349 412 ctxt->c->base_server, 350 "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X s->n: 0x%08X sc: 0x%08X", crt_name, rv,413 "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X s->n: 0x%08X sc: 0x%08X", tsc->cert_cn, rv, 351 414 gnutls_pk_algorithm_get_name(gnutls_x509_privkey_get_pk_algorithm(ctxt->sc->privkey_x509)), 352 415 (unsigned int)s, (unsigned int)s->next, (unsigned int)tsc); 353 354 if (rv != 0) { 355 continue; 356 } 357 416 #endif 358 417 /* The CN can contain a * -- this will match those too. */ 359 if (ap_strcasecmp_match(sni_name, crt_name) == 0) {418 if (ap_strcasecmp_match(sni_name, tsc->cert_cn) == 0) { 360 419 /* found a match */ 361 420 ret->cert.x509 = &tsc->cert_x509; … … 365 424 ctxt->c->base_server, 366 425 "GnuTLS: Virtual Host: " 367 "'%s' == '%s'", crt_name, sni_name); 368 #endif 426 "'%s' == '%s'", tsc->cert_cn, sni_name); 427 #endif 428 ctxt->sc = tsc; 429 mod_gnutls_changed_servers(ctxt); 369 430 return 0; 370 431 } 371 432 } 372 433 #endif 373 434 374 435 /** … … 377 438 */ 378 439 use_default_crt: 379 data_len = MAX_HOST_LEN;380 rv = gnutls_x509_crt_get_dn_by_oid(ctxt->sc->cert_x509,381 GNUTLS_OID_X520_COMMON_NAME, 0, 0,382 crt_name, &data_len);383 384 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,385 ctxt->c->base_server,386 "GnuTLS: x509 cn: %s/%d pk: %s", crt_name, rv,387 gnutls_pk_algorithm_get_name(gnutls_x509_privkey_get_pk_algorithm(ctxt->sc->privkey_x509)));388 389 440 ret->cert.x509 = &ctxt->sc->cert_x509; 390 441 ret->key.x509 = ctxt->sc->privkey_x509; … … 428 479 gnutls_certificate_type_set_priority(ctxt->session, sc->cert_types); 429 480 430 gnutls_credentials_set(ctxt->session, GNUTLS_CRD_CERTIFICATE, sc->certs);431 432 gnutls_certificate_server_set_request(ctxt->session, sc->client_verify_mode);433 434 481 mod_gnutls_cache_session_init(ctxt); 435 482 436 /* TODO: Finish Support for Server Name Indication */437 483 gnutls_certificate_server_set_retrieve_function(sc->certs, cert_retrieve_fn); 484 485 mod_gnutls_changed_servers(ctxt); 438 486 return ctxt; 439 487 } … … 575 623 } 576 624 577 //apr_pool_destroy(spool);625 apr_pool_destroy(spool); 578 626 return NULL; 579 627 } … … 606 654 gnutls_strerror(ret)); 607 655 } 608 //apr_pool_destroy(spool);656 apr_pool_destroy(spool); 609 657 return NULL; 610 658 } … … 674 722 const char *arg) 675 723 { 676 gnutls_certificate_request_t mode;677 678 if (strcasecmp("none", arg) == 0 724 int mode; 725 726 if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) { 679 727 mode = GNUTLS_CERT_IGNORE; 680 728 } … … 682 730 mode = GNUTLS_CERT_REQUEST; 683 731 } 684 else if (strcasecmp(" optional", arg) == 0) {732 else if (strcasecmp("require", arg) == 0) { 685 733 mode = GNUTLS_CERT_REQUIRE; 686 734 } … … 704 752 return NULL; 705 753 } 754 755 static const char *gnutls_set_client_ca_file(cmd_parms * parms, void *dummy, 756 const char *arg) 757 { 758 int rv; 759 const char* file; 760 mod_gnutls_srvconf_rec *sc = 761 (mod_gnutls_srvconf_rec *) ap_get_module_config(parms->server-> 762 module_config, 763 &gnutls_module); 764 file = ap_server_root_relative(parms->pool, arg); 765 rv = gnutls_certificate_set_x509_trust_file(sc->certs, 766 file, GNUTLS_X509_FMT_PEM); 767 768 if (rv < 0) { 769 return apr_psprintf(parms->pool, "GnuTLS: Failed to load " 770 "Client CA File '%s': (%d) %s", file, rv, 771 gnutls_strerror(rv)); 772 } 773 return NULL; 774 } 775 776 706 777 static const char *gnutls_set_enabled(cmd_parms * parms, void *dummy, 707 778 const char *arg) … … 729 800 RSRC_CONF|OR_AUTHCFG, 730 801 "Set Verification Requirements of the Client Certificate"), 802 AP_INIT_TAKE1("GnuTLSClientCAFile", gnutls_set_client_ca_file, 803 NULL, 804 RSRC_CONF, 805 "Set the CA File for Client Certificates"), 731 806 AP_INIT_TAKE1("GnuTLSCertificateFile", gnutls_set_cert_file, 732 807 NULL, … … 752 827 }; 753 828 754 /* TODO: CACertificateFile & Client Authentication755 * AP_INIT_TAKE1("GnuTLSCACertificateFile", ap_set_server_string_slot,756 * (void *) APR_OFFSETOF(gnutls_srvconf_rec, key_file), NULL,757 * RSRC_CONF,758 * "CA"),759 */760 761 829 int mod_gnutls_hook_authz(request_rec *r) 762 830 { 763 return OK;764 #if 0 831 int rv; 832 int status; 765 833 mod_gnutls_handle_t *ctxt; 766 834 mod_gnutls_dirconf_rec *dc = ap_get_module_config(r->per_dir_config, … … 769 837 ctxt = ap_get_module_config(r->connection->conn_config, &gnutls_module); 770 838 771 if (dc->client_verify_mode == -1 ||772 dc->client_verify_mode == GNUTLS_CERT_IGNORE ||773 ctxt->sc->client_verify_mode > dc->client_verify_mode) {839 if (dc->client_verify_mode == GNUTLS_CERT_IGNORE) { 840 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, 841 "GnuTLS: Ignoring Client Certificate!"); 774 842 return DECLINED; 775 843 } 776 844 777 gnutls_certificate_server_set_request(ctxt->session, dc->client_verify_mode); 778 if (mod_gnutls_rehandshake(ctxt) != 0) { 845 if (ctxt->sc->client_verify_mode < dc->client_verify_mode) { 846 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, 847 "GnuTLS: Attempting to rehandshake with peer. %d %d", 848 ctxt->sc->client_verify_mode, dc->client_verify_mode); 849 850 gnutls_certificate_server_set_request(ctxt->session, 851 dc->client_verify_mode); 852 853 if (mod_gnutls_rehandshake(ctxt) != 0) { 854 return HTTP_FORBIDDEN; 855 } 856 } 857 else if (ctxt->sc->client_verify_mode == GNUTLS_CERT_IGNORE) { 858 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 859 "GnuTLS: Peer is set to IGNORE"); 860 return DECLINED; 861 } 862 863 rv = gnutls_certificate_verify_peers2(ctxt->session, &status); 864 865 if (rv < 0) { 866 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 867 "GnuTLS: Failed to Verify Peer: (%d) %s", 868 rv, gnutls_strerror(rv)); 779 869 return HTTP_FORBIDDEN; 780 870 } 781 #endif 871 872 if (status < 0) { 873 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 874 "GnuTLS: Peer Status is invalid."); 875 return HTTP_FORBIDDEN; 876 } 877 878 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) { 879 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 880 "GnuTLS: Could not find Signer for Peer Certificate"); 881 } 882 883 if (status & GNUTLS_CERT_SIGNER_NOT_CA) { 884 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 885 "GnuTLS: Could not find CA for Peer Certificate"); 886 } 887 888 if (status & GNUTLS_CERT_INVALID) { 889 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 890 "GnuTLS: Peer Certificate is invalid."); 891 return HTTP_FORBIDDEN; 892 } 893 else if (status & GNUTLS_CERT_REVOKED) { 894 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 895 "GnuTLS: Peer Certificate is revoked."); 896 return HTTP_FORBIDDEN; 897 } 898 899 /* TODO: OpenPGP Certificates */ 900 if (gnutls_certificate_type_get(ctxt->session) != GNUTLS_CRT_X509) { 901 ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, 902 "GnuTLS: Only x509 is supported for client certificates"); 903 return HTTP_FORBIDDEN; 904 } 905 /* TODO: Further Verification. */ 906 ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, 907 "GnuTLS: Verified Peer."); 908 return OK; 782 909 } 783 910 … … 802 929 APR_HOOK_MIDDLE); 803 930 804 ap_hook_a uth_checker(mod_gnutls_hook_authz, NULL, NULL, APR_HOOK_MIDDLE);805 931 ap_hook_access_checker(mod_gnutls_hook_authz, NULL, NULL, APR_HOOK_REALLY_FIRST); 932 806 933 ap_hook_fixups(mod_gnutls_hook_fixups, NULL, NULL, APR_HOOK_REALLY_FIRST); 807 934
Note: See TracChangeset
for help on using the changeset viewer.