comparison src/http/modules/ngx_http_ssl_module.c @ 7462:be2af41d3620

SSL: variables support in ssl_certificate and ssl_certificate_key. To evaluate variables, a request is created in the certificate callback, and then freed. To do this without side effects on the stub_status counters and connection state, an additional function was introduced, ngx_http_alloc_request(). Only works with OpenSSL 1.0.2+, since there is no SSL_CTX_set_cert_cb() in older versions.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 25 Feb 2019 16:42:05 +0300
parents ba971deb4b44
children 180df83473a4
comparison
equal deleted inserted replaced
7461:a68799465b19 7462:be2af41d3620
38 38
39 static ngx_int_t ngx_http_ssl_add_variables(ngx_conf_t *cf); 39 static ngx_int_t ngx_http_ssl_add_variables(ngx_conf_t *cf);
40 static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf); 40 static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf);
41 static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, 41 static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf,
42 void *parent, void *child); 42 void *parent, void *child);
43
44 static ngx_int_t ngx_http_ssl_compile_certificates(ngx_conf_t *cf,
45 ngx_http_ssl_srv_conf_t *conf);
43 46
44 static char *ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, 47 static char *ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd,
45 void *conf); 48 void *conf);
46 static char *ngx_http_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, 49 static char *ngx_http_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
47 void *conf); 50 void *conf);
548 551
549 /* 552 /*
550 * set by ngx_pcalloc(): 553 * set by ngx_pcalloc():
551 * 554 *
552 * sscf->protocols = 0; 555 * sscf->protocols = 0;
556 * sscf->certificate_values = NULL;
553 * sscf->dhparam = { 0, NULL }; 557 * sscf->dhparam = { 0, NULL };
554 * sscf->ecdh_curve = { 0, NULL }; 558 * sscf->ecdh_curve = { 0, NULL };
555 * sscf->client_certificate = { 0, NULL }; 559 * sscf->client_certificate = { 0, NULL };
556 * sscf->trusted_certificate = { 0, NULL }; 560 * sscf->trusted_certificate = { 0, NULL };
557 * sscf->crl = { 0, NULL }; 561 * sscf->crl = { 0, NULL };
725 } 729 }
726 730
727 cln->handler = ngx_ssl_cleanup_ctx; 731 cln->handler = ngx_ssl_cleanup_ctx;
728 cln->data = &conf->ssl; 732 cln->data = &conf->ssl;
729 733
730 if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, 734 if (ngx_http_ssl_compile_certificates(cf, conf) != NGX_OK) {
731 conf->certificate_keys, conf->passwords) 735 return NGX_CONF_ERROR;
732 != NGX_OK) 736 }
733 { 737
734 return NGX_CONF_ERROR; 738 if (conf->certificate_values) {
739
740 #ifdef SSL_R_CERT_CB_ERROR
741
742 /* install callback to lookup certificates */
743
744 SSL_CTX_set_cert_cb(conf->ssl.ctx, ngx_http_ssl_certificate, NULL);
745
746 #else
747 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
748 "variables in "
749 "\"ssl_certificate\" and \"ssl_certificate_key\" "
750 "directives are not supported on this platform");
751 return NGX_CONF_ERROR;
752 #endif
753
754 } else {
755
756 /* configure certificates */
757
758 if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates,
759 conf->certificate_keys, conf->passwords)
760 != NGX_OK)
761 {
762 return NGX_CONF_ERROR;
763 }
735 } 764 }
736 765
737 if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, 766 if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers,
738 conf->prefer_server_ciphers) 767 conf->prefer_server_ciphers)
739 != NGX_OK) 768 != NGX_OK)
826 if (ngx_ssl_early_data(cf, &conf->ssl, conf->early_data) != NGX_OK) { 855 if (ngx_ssl_early_data(cf, &conf->ssl, conf->early_data) != NGX_OK) {
827 return NGX_CONF_ERROR; 856 return NGX_CONF_ERROR;
828 } 857 }
829 858
830 return NGX_CONF_OK; 859 return NGX_CONF_OK;
860 }
861
862
863 static ngx_int_t
864 ngx_http_ssl_compile_certificates(ngx_conf_t *cf,
865 ngx_http_ssl_srv_conf_t *conf)
866 {
867 ngx_str_t *cert, *key;
868 ngx_uint_t i, nelts;
869 ngx_http_complex_value_t *cv;
870 ngx_http_compile_complex_value_t ccv;
871
872 cert = conf->certificates->elts;
873 key = conf->certificate_keys->elts;
874 nelts = conf->certificates->nelts;
875
876 for (i = 0; i < nelts; i++) {
877
878 if (ngx_http_script_variables_count(&cert[i])) {
879 goto found;
880 }
881
882 if (ngx_http_script_variables_count(&key[i])) {
883 goto found;
884 }
885 }
886
887 return NGX_OK;
888
889 found:
890
891 conf->certificate_values = ngx_array_create(cf->pool, nelts,
892 sizeof(ngx_http_complex_value_t));
893 if (conf->certificate_values == NULL) {
894 return NGX_ERROR;
895 }
896
897 conf->certificate_key_values = ngx_array_create(cf->pool, nelts,
898 sizeof(ngx_http_complex_value_t));
899 if (conf->certificate_key_values == NULL) {
900 return NGX_ERROR;
901 }
902
903 for (i = 0; i < nelts; i++) {
904
905 cv = ngx_array_push(conf->certificate_values);
906 if (cv == NULL) {
907 return NGX_ERROR;
908 }
909
910 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
911
912 ccv.cf = cf;
913 ccv.value = &cert[i];
914 ccv.complex_value = cv;
915 ccv.zero = 1;
916
917 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
918 return NGX_ERROR;
919 }
920
921 cv = ngx_array_push(conf->certificate_key_values);
922 if (cv == NULL) {
923 return NGX_ERROR;
924 }
925
926 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
927
928 ccv.cf = cf;
929 ccv.value = &key[i];
930 ccv.complex_value = cv;
931 ccv.zero = 1;
932
933 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
934 return NGX_ERROR;
935 }
936 }
937
938 return NGX_OK;
831 } 939 }
832 940
833 941
834 static char * 942 static char *
835 ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 943 ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)