Changeset c0fc11e in mod_gnutls
- Timestamp:
- Nov 5, 2018, 2:20:54 AM (2 years ago)
- Branches:
- asyncio, debian/master, master, proxy-ticket
- Children:
- d4c1a4e
- Parents:
- 7ff6c6c
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
include/mod_gnutls.h.in
r7ff6c6c rc0fc11e 403 403 void *mgs_config_dir_create(apr_pool_t *p, char *dir); 404 404 405 mgs_srvconf_rec* mgs_find_sni_server(gnutls_session_t session);406 407 405 const char *mgs_store_cred_path(cmd_parms * parms, 408 406 void *dummy __attribute__((unused)), -
src/gnutls_hooks.c
r7ff6c6c rc0fc11e 66 66 67 67 static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt); 68 /* use side==0 for server and side==1 for client */68 /** use side==0 for server and side==1 for client */ 69 69 static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side, size_t export_cert_size); 70 mgs_srvconf_rec* mgs_find_sni_server(mgs_handle_t *ctxt); 70 71 static int mgs_status_hook(request_rec *r, int flags); 71 72 #ifdef ENABLE_MSVA … … 303 304 304 305 /** 306 * (Re-)Load credentials and priorities for the connection. This is 307 * meant to be called after virtual host selection in the pre or post 308 * client hello hook. 309 */ 310 static int reload_session_credentials(mgs_handle_t *ctxt) 311 { 312 int ret = 0; 313 314 gnutls_certificate_server_set_request(ctxt->session, 315 ctxt->sc->client_verify_mode); 316 317 /* Set x509 credentials */ 318 gnutls_credentials_set(ctxt->session, 319 GNUTLS_CRD_CERTIFICATE, ctxt->sc->certs); 320 /* Set Anon credentials */ 321 gnutls_credentials_set(ctxt->session, GNUTLS_CRD_ANON, 322 ctxt->sc->anon_creds); 323 324 #ifdef ENABLE_SRP 325 /* Set SRP credentials */ 326 if (ctxt->sc->srp_tpasswd_conf_file != NULL && ctxt->sc->srp_tpasswd_file != NULL) { 327 gnutls_credentials_set(ctxt->session, GNUTLS_CRD_SRP, 328 ctxt->sc->srp_creds); 329 } 330 #endif 331 332 /* Enable session tickets */ 333 if (session_ticket_key.data != NULL && 334 ctxt->sc->tickets == GNUTLS_ENABLED_TRUE) 335 { 336 ret = gnutls_session_ticket_enable_server(ctxt->session, &session_ticket_key); 337 if (ret != GNUTLS_E_SUCCESS) 338 ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, ctxt->c, 339 "gnutls_session_ticket_enable_server failed: %s (%d)", 340 gnutls_strerror(ret), ret); 341 } 342 343 /* Update the priorities - to avoid negotiating a ciphersuite that is not 344 * enabled on this virtual server. Note that here we ignore the version 345 * negotiation. */ 346 ret = gnutls_priority_set(ctxt->session, ctxt->sc->priorities); 347 348 return ret; 349 } 350 351 352 353 /** 305 354 * Post client hello function for GnuTLS, used to configure the TLS 306 355 * server based on virtual host configuration. Uses SNI to select the … … 318 367 319 368 /* try to find a virtual host */ 320 mgs_srvconf_rec *tsc = mgs_find_sni_server( session);369 mgs_srvconf_rec *tsc = mgs_find_sni_server(ctxt); 321 370 if (tsc != NULL) 322 371 { … … 326 375 } 327 376 328 gnutls_certificate_server_set_request(session, ctxt->sc->client_verify_mode); 329 330 /* Set x509 credentials */ 331 gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, ctxt->sc->certs); 332 /* Set Anon credentials */ 333 gnutls_credentials_set(session, GNUTLS_CRD_ANON, ctxt->sc->anon_creds); 334 335 #ifdef ENABLE_SRP 336 /* Set SRP credentials */ 337 if (ctxt->sc->srp_tpasswd_conf_file != NULL && ctxt->sc->srp_tpasswd_file != NULL) { 338 gnutls_credentials_set(session, GNUTLS_CRD_SRP, ctxt->sc->srp_creds); 339 } 340 #endif 341 342 /* Enable session tickets */ 343 if (session_ticket_key.data != NULL && 344 ctxt->sc->tickets == GNUTLS_ENABLED_TRUE) 345 { 346 ret = gnutls_session_ticket_enable_server(ctxt->session, &session_ticket_key); 347 if (ret != GNUTLS_E_SUCCESS) 348 ap_log_cerror(APLOG_MARK, APLOG_ERR, APR_EGENERAL, ctxt->c, 349 "gnutls_session_ticket_enable_server failed: %s (%d)", 350 gnutls_strerror(ret), ret); 351 } 377 reload_session_credentials(ctxt); 352 378 353 379 ret = process_alpn_result(ctxt); 354 380 if (ret != GNUTLS_E_SUCCESS) 355 381 return ret; 356 357 /* Update the priorities - to avoid negotiating a ciphersuite that is not358 * enabled on this virtual server. Note that here we ignore the version359 * negotiation. */360 ret = gnutls_priority_set(session, ctxt->sc->priorities);361 382 362 383 /* actually it shouldn't fail since we have checked at startup */ … … 855 876 } 856 877 857 /** 858 * Default buffer size for SNI data, including the terminating NULL 859 * byte. The size matches what gnutls-cli uses initially. 860 */ 861 #define DEFAULT_SNI_HOST_LEN 256 878 862 879 863 880 typedef struct { … … 957 974 * hello function. 958 975 * 959 * @param session the GnuTLS session976 * @param ctxt the mod_gnutls connection handle 960 977 * 961 978 * @return either the matching mod_gnutls server config, or `NULL` 962 979 */ 963 mgs_srvconf_rec *mgs_find_sni_server( gnutls_session_t session)980 mgs_srvconf_rec *mgs_find_sni_server(mgs_handle_t *ctxt) 964 981 { 965 mgs_handle_t *ctxt = gnutls_session_get_ptr(session); 966 967 char *sni_name = apr_palloc(ctxt->c->pool, DEFAULT_SNI_HOST_LEN); 968 size_t sni_len = DEFAULT_SNI_HOST_LEN; 969 unsigned int sni_type; 970 971 /* Search for a DNS SNI element. Note that RFC 6066 prohibits more 972 * than one server name per type. */ 973 int sni_index = -1; 974 int rv = 0; 975 do { 976 /* The sni_index is incremented before each use, so if the 977 * loop terminates with a type match we will have the right 978 * one stored. */ 979 rv = gnutls_server_name_get(session, sni_name, 980 &sni_len, &sni_type, ++sni_index); 981 if (rv == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) 982 { 983 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, APR_EGENERAL, ctxt->c, 984 "%s: no DNS SNI found (last index: %d).", 985 __func__, sni_index); 986 return NULL; 987 } 988 } while (sni_type != GNUTLS_NAME_DNS); 989 /* The (rv == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) path inside 990 * the loop above returns, so if we reach this point we have a DNS 991 * SNI at the current index. */ 992 993 if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER) 994 { 995 /* Allocate a new buffer of the right size and retry */ 996 sni_name = apr_palloc(ctxt->c->pool, sni_len); 997 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, APR_SUCCESS, ctxt->c, 998 "%s: reallocated SNI data buffer for %" APR_SIZE_T_FMT 999 " bytes.", __func__, sni_len); 1000 rv = gnutls_server_name_get(session, sni_name, 1001 &sni_len, &sni_type, sni_index); 1002 } 1003 1004 /* Unless there's a bug in the GnuTLS API only GNUTLS_E_IDNA_ERROR 1005 * can occur here, but a catch all is safer and no more 1006 * complicated. */ 1007 if (rv != GNUTLS_E_SUCCESS) 1008 { 1009 ap_log_cerror(APLOG_MARK, APLOG_INFO, APR_EGENERAL, ctxt->c, 1010 "%s: error while getting SNI DNS data: '%s' (%d).", 1011 __func__, gnutls_strerror(rv), rv); 982 if (ctxt->sni_name == NULL) 983 { 984 const char *sni_name = mgs_server_name_get(ctxt); 985 if (sni_name != NULL) 986 ctxt->sni_name = sni_name; 1012 987 return NULL; 1013 988 } … … 1015 990 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, APR_SUCCESS, ctxt->c, 1016 991 "%s: client requested server '%s'.", 1017 __func__, sni_name); 1018 ctxt->sni_name = sni_name; 992 __func__, ctxt->sni_name); 1019 993 1020 994 /* Search for vhosts matching connection parameters and the … … 1024 998 .ctxt = ctxt, 1025 999 .sc = NULL, 1026 .sni_name = sni_name1000 .sni_name = ctxt->sni_name 1027 1001 }; 1028 rv = ap_vhost_iterate_given_conn(ctxt->c, vhost_cb, &cbx);1002 int rv = ap_vhost_iterate_given_conn(ctxt->c, vhost_cb, &cbx); 1029 1003 if (rv == 1) { 1030 1004 return cbx.sc; -
src/gnutls_sni.c
r7ff6c6c rc0fc11e 138 138 return 0; 139 139 } 140 141 142 143 /** 144 * Default buffer size for SNI data, including the terminating NULL 145 * byte. The size matches what gnutls-cli uses initially. 146 */ 147 #define DEFAULT_SNI_HOST_LEN 256 148 149 const char* mgs_server_name_get(mgs_handle_t *ctxt) 150 { 151 char *sni_name = apr_palloc(ctxt->c->pool, DEFAULT_SNI_HOST_LEN); 152 size_t sni_len = DEFAULT_SNI_HOST_LEN; 153 unsigned int sni_type; 154 155 /* Search for a DNS SNI element. Note that RFC 6066 prohibits more 156 * than one server name per type. */ 157 int sni_index = -1; 158 int rv = 0; 159 do { 160 /* The sni_index is incremented before each use, so if the 161 * loop terminates with a type match we will have the right 162 * one stored. */ 163 rv = gnutls_server_name_get(ctxt->session, sni_name, 164 &sni_len, &sni_type, ++sni_index); 165 if (rv == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) 166 { 167 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, APR_EGENERAL, ctxt->c, 168 "%s: no DNS SNI found (last index: %d).", 169 __func__, sni_index); 170 return NULL; 171 } 172 } while (sni_type != GNUTLS_NAME_DNS); 173 /* The (rv == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) path inside 174 * the loop above returns, so if we reach this point we have a DNS 175 * SNI at the current index. */ 176 177 if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER) 178 { 179 /* Allocate a new buffer of the right size and retry */ 180 sni_name = apr_palloc(ctxt->c->pool, sni_len); 181 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, APR_SUCCESS, ctxt->c, 182 "%s: reallocated SNI data buffer for %" APR_SIZE_T_FMT 183 " bytes.", __func__, sni_len); 184 rv = gnutls_server_name_get(ctxt->session, sni_name, 185 &sni_len, &sni_type, sni_index); 186 } 187 188 /* Unless there's a bug in the GnuTLS API only GNUTLS_E_IDNA_ERROR 189 * can occur here, but a catch all is safer and no more 190 * complicated. */ 191 if (rv != GNUTLS_E_SUCCESS) 192 { 193 ap_log_cerror(APLOG_MARK, APLOG_INFO, APR_EGENERAL, ctxt->c, 194 "%s: error while getting SNI DNS data: '%s' (%d).", 195 __func__, gnutls_strerror(rv), rv); 196 return NULL; 197 } 198 199 return sni_name; 200 } -
src/gnutls_sni.h
r7ff6c6c rc0fc11e 21 21 const unsigned char *data, unsigned size); 22 22 23 24 /** 25 * Wrapper for gnutls_server_name_get(): Retrieve SNI data from the 26 * TLS session associated with the connection, store it in a string 27 * allocated from the connection pool. 28 * 29 * Note that `ctxt->sni_name` is not automatically updated. 30 * 31 * @param ctxt the connection to read from 32 * 33 * @return the requested server name, or NULL. 34 */ 35 const char* mgs_server_name_get(mgs_handle_t *ctxt); 36 23 37 #endif /* __MOD_GNUTLS_SNI_H__ */
Note: See TracChangeset
for help on using the changeset viewer.