X-Git-Url: http://www.dolda2000.com/gitweb/?a=blobdiff_plain;f=src%2Fssl-gnutls.c;h=544a7101e0ef4ac902edfb722ed3a8f6ef1cff5c;hb=HEAD;hp=5a44214e76f0fd5f1eeef0ab1afa100e83b4503c;hpb=7a59f41f662586056914dd3371b49b0eaaf676b6;p=ashd.git diff --git a/src/ssl-gnutls.c b/src/ssl-gnutls.c index 5a44214..5a11f94 100644 --- a/src/ssl-gnutls.c +++ b/src/ssl-gnutls.c @@ -54,8 +54,7 @@ struct ncredbuf { }; struct sslport { - int fd; - int sport; + int fd, sport, clreq; gnutls_certificate_credentials_t creds; gnutls_priority_t ciphers; struct namedcreds **ncreds; @@ -272,6 +271,8 @@ static int initreq(struct conn *conn, struct hthead *req) struct sslconn *ssl = conn->pdata; struct sockaddr_storage sa; socklen_t salen; + gnutls_datum_t sessid; + char *esessid; headappheader(req, "X-Ash-Address", formathaddress((struct sockaddr *)&ssl->name, sizeof(sa))); if(ssl->name.ss_family == AF_INET) @@ -283,6 +284,43 @@ static int initreq(struct conn *conn, struct hthead *req) headappheader(req, "X-Ash-Server-Address", formathaddress((struct sockaddr *)&sa, sizeof(sa))); headappheader(req, "X-Ash-Server-Port", sprintf3("%i", ssl->port->sport)); headappheader(req, "X-Ash-Protocol", "https"); + if(gnutls_session_get_id2(ssl->sess, &sessid) == GNUTLS_E_SUCCESS) { + esessid = base64encode((void *)sessid.data, sessid.size); + headappheader(req, "X-Ash-TLS-Session", esessid); + free(esessid); + } + return(0); +} + +static int setcreds(gnutls_session_t sess) +{ + int i, o, u; + struct sslport *pd; + unsigned int ntype; + char nambuf[256]; + size_t namlen; + + pd = gnutls_session_get_ptr(sess); + for(i = 0; 1; i++) { + namlen = sizeof(nambuf); + if(gnutls_server_name_get(sess, nambuf, &namlen, &ntype, i) != 0) + break; + if(ntype != GNUTLS_NAME_DNS) + continue; + for(o = 0; pd->ncreds[o] != NULL; o++) { + for(u = 0; pd->ncreds[o]->names[u] != NULL; u++) { + if(!strcmp(pd->ncreds[o]->names[u], nambuf)) { + gnutls_credentials_set(sess, GNUTLS_CRD_CERTIFICATE, pd->ncreds[o]->creds); + if(pd->clreq) + gnutls_certificate_server_set_request(sess, GNUTLS_CERT_REQUEST); + return(0); + } + } + } + } + gnutls_credentials_set(sess, GNUTLS_CRD_CERTIFICATE, pd->creds); + if(pd->clreq) + gnutls_certificate_server_set_request(sess, GNUTLS_CERT_REQUEST); return(0); } @@ -295,34 +333,6 @@ static void servessl(struct muth *muth, va_list args) struct sslconn ssl; gnutls_session_t sess; int ret; - - int setcreds(gnutls_session_t sess) - { - int i, o, u; - unsigned int ntype; - char nambuf[256]; - size_t namlen; - - for(i = 0; 1; i++) { - namlen = sizeof(nambuf); - if(gnutls_server_name_get(sess, nambuf, &namlen, &ntype, i) != 0) - break; - if(ntype != GNUTLS_NAME_DNS) - continue; - for(o = 0; pd->ncreds[o] != NULL; o++) { - for(u = 0; pd->ncreds[o]->names[u] != NULL; u++) { - if(!strcmp(pd->ncreds[o]->names[u], nambuf)) { - gnutls_credentials_set(sess, GNUTLS_CRD_CERTIFICATE, pd->ncreds[o]->creds); - gnutls_certificate_server_set_request(sess, GNUTLS_CERT_REQUEST); - return(0); - } - } - } - } - gnutls_credentials_set(sess, GNUTLS_CRD_CERTIFICATE, pd->creds); - gnutls_certificate_server_set_request(sess, GNUTLS_CERT_REQUEST); - return(0); - } numconn++; fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); @@ -332,6 +342,7 @@ static void servessl(struct muth *muth, va_list args) gnutls_db_set_store_function(sess, sessdbstore); gnutls_db_set_remove_function(sess, sessdbdel); gnutls_db_set_ptr(sess, NULL); + gnutls_session_set_ptr(sess, pd); gnutls_handshake_set_post_client_hello_function(sess, setcreds); gnutls_transport_set_ptr(sess, (gnutls_transport_ptr_t)(intptr_t)fd); while((ret = gnutls_handshake(sess)) != 0) { @@ -438,7 +449,7 @@ static int readcrtchain(struct certbuffer *ret, struct charbuf *pem) for(i = 0, p = NULL; i < sizeof(headers) / sizeof(*headers); i++) { f = memmem(pem->b, pem->d, headers[i], strlen(headers[i])); - if((p == NULL) || (f < p)) + if((f != NULL) && ((p == NULL) || (f < p))) p = f; } if(p == NULL) @@ -453,7 +464,7 @@ static int readcrtchain(struct certbuffer *ret, struct charbuf *pem) bufadd(*ret, crt); for(i = 0, p2 = NULL; i < sizeof(headers) / sizeof(*headers); i++) { f = memmem(p + 1, pem->d - (p + 1 - pem->b), headers[i], strlen(headers[i])); - if((p2 == NULL) || (f < p2)) + if((f != NULL) && ((p2 == NULL) || (f < p2))) p2 = f; } } while((p = p2) != NULL); @@ -562,7 +573,7 @@ static void readncdir(struct ncredbuf *buf, char *dir, gnutls_x509_privkey_t def void handlegnussl(int argc, char **argp, char **argv) { - int i, ret, port, fd; + int i, ret, port, fd, clreq; gnutls_certificate_credentials_t creds; gnutls_priority_t ciphers; gnutls_x509_privkey_t defkey; @@ -573,6 +584,7 @@ void handlegnussl(int argc, char **argp, char **argv) init(); port = 443; + clreq = 0; bufinit(ncreds); bufinit(ncertf); bufinit(ncertd); @@ -639,6 +651,7 @@ void handlegnussl(int argc, char **argp, char **argv) exit(1); } } + clreq = 1; } else if(!strcmp(argp[i], "crl")) { if((ret = gnutls_certificate_set_x509_crl_file(creds, argv[i], GNUTLS_X509_FMT_PEM)) != 0) { flog(LOG_ERR, "ssl: could not load CRL file `%s': %s", argv[i], gnutls_strerror(ret)); @@ -650,6 +663,7 @@ void handlegnussl(int argc, char **argp, char **argv) exit(1); } } + clreq = 1; } else if(!strcmp(argp[i], "port")) { port = atoi(argv[i]); } else if(!strcmp(argp[i], "ncert")) { @@ -694,6 +708,7 @@ void handlegnussl(int argc, char **argp, char **argv) omalloc(pd); pd->fd = fd; pd->sport = port; + pd->clreq = clreq; pd->creds = creds; pd->ncreds = ncreds.b; pd->ciphers = ciphers;