jabberd2
2.2.16
|
00001 /* 00002 * jabberd - Jabber Open Source Server 00003 * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, 00004 * Ryan Eatmon, Robert Norris 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA 00019 */ 00020 00026 #include "sx.h" 00027 #include <openssl/x509_vfy.h> 00028 00029 00030 /* code stolen from SSL_CTX_set_verify(3) */ 00031 static int _sx_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) 00032 { 00033 char buf[256]; 00034 X509 *err_cert; 00035 int err, depth; 00036 SSL *ssl; 00037 00038 err_cert = X509_STORE_CTX_get_current_cert(ctx); 00039 err = X509_STORE_CTX_get_error(ctx); 00040 depth = X509_STORE_CTX_get_error_depth(ctx); 00041 00042 /* 00043 * Ignore errors when we can't get CRLs in the certificate 00044 */ 00045 if (!preverify_ok && err == X509_V_ERR_UNABLE_TO_GET_CRL) { 00046 _sx_debug(ZONE, "ignoring verify error:num=%d:%s:depth=%d:%s\n", err, 00047 X509_verify_cert_error_string(err), depth, buf); 00048 preverify_ok = 1; 00049 } 00050 00051 /* 00052 * Retrieve the pointer to the SSL of the connection currently treated 00053 * and the application specific data stored into the SSL object. 00054 */ 00055 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); 00056 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256); 00057 00058 if (!preverify_ok) { 00059 _sx_debug(ZONE, "verify error:num=%d:%s:depth=%d:%s\n", err, 00060 X509_verify_cert_error_string(err), depth, buf); 00061 } 00062 else 00063 { 00064 _sx_debug(ZONE, "OK! depth=%d:%s", depth, buf); 00065 } 00066 00067 /* 00068 * At this point, err contains the last verification error. We can use 00069 * it for something special 00070 */ 00071 if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) 00072 { 00073 X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256); 00074 _sx_debug(ZONE, "issuer= %s\n", buf); 00075 } 00076 00077 return preverify_ok; 00078 } 00079 00080 static void _sx_ssl_starttls_notify_proceed(sx_t s, void *arg) { 00081 char *to = NULL; 00082 _sx_debug(ZONE, "preparing for starttls"); 00083 00084 /* store the destination so we can select an ssl context */ 00085 if(s->req_to != NULL) to = strdup(s->req_to); 00086 00087 _sx_reset(s); 00088 00089 /* restore destination */ 00090 if(s->req_to == NULL) 00091 s->req_to = to; 00092 else /* ? */ 00093 free(to); 00094 00095 /* start listening */ 00096 sx_server_init(s, s->flags | SX_SSL_WRAPPER); 00097 } 00098 00099 static int _sx_ssl_process(sx_t s, sx_plugin_t p, nad_t nad) { 00100 int flags; 00101 char *ns = NULL, *to = NULL, *from = NULL, *version = NULL; 00102 sx_error_t sxe; 00103 00104 /* not interested if we're a server and we never offered it */ 00105 if(s->type == type_SERVER && !(s->flags & SX_SSL_STARTTLS_OFFER)) 00106 return 1; 00107 00108 /* only want tls packets */ 00109 if(NAD_ENS(nad, 0) < 0 || NAD_NURI_L(nad, NAD_ENS(nad, 0)) != strlen(uri_TLS) || strncmp(NAD_NURI(nad, NAD_ENS(nad, 0)), uri_TLS, strlen(uri_TLS)) != 0) 00110 return 1; 00111 00112 /* starttls from client */ 00113 if(s->type == type_SERVER) { 00114 if(NAD_ENAME_L(nad, 0) == 8 && strncmp(NAD_ENAME(nad, 0), "starttls", 8) == 0) { 00115 nad_free(nad); 00116 00117 /* can't go on if we've been here before */ 00118 if(s->ssf > 0) { 00119 _sx_debug(ZONE, "starttls requested on already encrypted channel, dropping packet"); 00120 return 0; 00121 } 00122 00123 /* can't go on if we're on compressed stream */ 00124 if(s->compressed > 0) { 00125 _sx_debug(ZONE, "starttls requested on already compressed channel, dropping packet"); 00126 return 0; 00127 } 00128 00129 _sx_debug(ZONE, "starttls requested, setting up"); 00130 00131 /* go ahead */ 00132 jqueue_push(s->wbufq, _sx_buffer_new("<proceed xmlns='" uri_TLS "'/>", strlen(uri_TLS) + 19, _sx_ssl_starttls_notify_proceed, NULL), 0); 00133 s->want_write = 1; 00134 00135 /* handled the packet */ 00136 return 0; 00137 } 00138 } 00139 00140 else if(s->type == type_CLIENT) { 00141 /* kick off the handshake */ 00142 if(NAD_ENAME_L(nad, 0) == 7 && strncmp(NAD_ENAME(nad, 0), "proceed", 7) == 0) { 00143 nad_free(nad); 00144 00145 /* save interesting bits */ 00146 flags = s->flags; 00147 00148 if(s->ns != NULL) ns = strdup(s->ns); 00149 00150 if(s->req_to != NULL) to = strdup(s->req_to); 00151 if(s->req_from != NULL) from = strdup(s->req_from); 00152 if(s->req_version != NULL) version = strdup(s->req_version); 00153 00154 /* reset state */ 00155 _sx_reset(s); 00156 00157 _sx_debug(ZONE, "server ready for ssl, starting"); 00158 00159 /* second time round */ 00160 sx_client_init(s, flags | SX_SSL_WRAPPER, ns, to, from, version); 00161 00162 /* free bits */ 00163 if(ns != NULL) free(ns); 00164 if(to != NULL) free(to); 00165 if(from != NULL) free(from); 00166 if(version != NULL) free(version); 00167 00168 return 0; 00169 } 00170 00171 /* busted server */ 00172 if(NAD_ENAME_L(nad, 0) == 7 && strncmp(NAD_ENAME(nad, 0), "failure", 7) == 0) { 00173 nad_free(nad); 00174 00175 /* free the pemfile arg */ 00176 if(s->plugin_data[p->index] != NULL) { 00177 if( ((_sx_ssl_conn_t)s->plugin_data[p->index])->pemfile != NULL ) 00178 free(((_sx_ssl_conn_t)s->plugin_data[p->index])->pemfile); 00179 free(s->plugin_data[p->index]); 00180 s->plugin_data[p->index] = NULL; 00181 } 00182 00183 _sx_debug(ZONE, "server can't handle ssl, business as usual"); 00184 00185 _sx_gen_error(sxe, SX_ERR_STARTTLS_FAILURE, "STARTTLS failure", "Server was unable to prepare for the TLS handshake"); 00186 _sx_event(s, event_ERROR, (void *) &sxe); 00187 00188 return 0; 00189 } 00190 } 00191 00192 _sx_debug(ZONE, "unknown starttls namespace element '%.*s', dropping packet", NAD_ENAME_L(nad, 0), NAD_ENAME(nad, 0)); 00193 nad_free(nad); 00194 return 0; 00195 } 00196 00197 static void _sx_ssl_features(sx_t s, sx_plugin_t p, nad_t nad) { 00198 int ns; 00199 00200 /* if the session is already encrypted, or the app told us not to, 00201 * or session is compressed then we don't offer anything */ 00202 if(s->state > state_STREAM || s->ssf > 0 || !(s->flags & SX_SSL_STARTTLS_OFFER) || s->compressed) 00203 return; 00204 00205 _sx_debug(ZONE, "offering starttls"); 00206 00207 ns = nad_add_namespace(nad, uri_TLS, NULL); 00208 nad_append_elem(nad, ns, "starttls", 1); 00209 00210 if(s->flags & SX_SSL_STARTTLS_REQUIRE) 00211 nad_append_elem(nad, ns, "required", 2); 00212 } 00213 00214 /* Extract id-on-xmppAddr from the certificate */ 00215 static void _sx_ssl_get_external_id(sx_t s, _sx_ssl_conn_t sc) { 00216 X509 *cert; 00217 X509_NAME *name; 00218 X509_NAME_ENTRY *entry; 00219 // subjectAltName parsing 00220 X509_EXTENSION *extension; 00221 STACK_OF(GENERAL_NAME) *altnames; 00222 GENERAL_NAME *altname; 00223 OTHERNAME *othername; 00224 char * buff; 00225 // new object identifiers 00226 int id_on_xmppAddr_nid; 00227 ASN1_OBJECT *id_on_xmppAddr_obj; 00228 // iterators 00229 int i, j, count, id = 0, len; 00230 00231 /* If there's not peer cert, quit */ 00232 if ((cert = SSL_get_peer_certificate(sc->ssl) ) == NULL) 00233 return; 00234 _sx_debug(ZONE, "external_id: Got peer certificate"); 00235 00236 /* Allocate new id-on-xmppAddr object. See rfc3921bis 15.2.1.2 */ 00237 id_on_xmppAddr_nid = OBJ_create("1.3.6.1.5.5.7.8.5", "id-on-xmppAddr", "XMPP Address Identity"); 00238 id_on_xmppAddr_obj = OBJ_nid2obj(id_on_xmppAddr_nid); 00239 _sx_debug(ZONE, "external_id: Created id-on-xmppAddr SSL object"); 00240 00241 /* Iterate through all subjectAltName x509v3 extensions. Get id-on-xmppAddr and dDnsName */ 00242 for (i = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); 00243 i != -1; 00244 i = X509_get_ext_by_NID(cert, NID_subject_alt_name, i)) { 00245 // Get this subjectAltName x509v3 extension 00246 if ((extension = X509_get_ext(cert, i)) == NULL) { 00247 _sx_debug(ZONE, "external_id: Can't get subjectAltName. Possibly malformed cert."); 00248 goto end; 00249 } 00250 // Get the collection of AltNames 00251 if ((altnames = X509V3_EXT_d2i(extension)) == NULL) { 00252 _sx_debug(ZONE, "external_id: Can't get all AltNames. Possibly malformed cert."); 00253 goto end; 00254 } 00255 /* Iterate through all altNames and get id-on-xmppAddr and dNSName */ 00256 count = sk_GENERAL_NAME_num(altnames); 00257 for (j = 0; j < count; j++) { 00258 if ((altname = sk_GENERAL_NAME_value(altnames, j)) == NULL) { 00259 _sx_debug(ZONE, "external_id: Can't get AltName. Possibly malformed cert."); 00260 goto end; 00261 } 00262 /* Check if its otherName id-on-xmppAddr */ 00263 if (altname->type == GEN_OTHERNAME && 00264 OBJ_cmp(altname->d.otherName->type_id, id_on_xmppAddr_obj) == 0) { 00265 othername = altname->d.otherName; 00266 len = ASN1_STRING_to_UTF8((unsigned char **) &buff, othername->value->value.utf8string); 00267 if (len <= 0) 00268 continue; 00269 sc->external_id[id] = (char *) malloc(sizeof(char) * (len + 1)); 00270 memcpy(sc->external_id[id], buff, len); 00271 sc->external_id[id][len] = '\0'; // just to make sure 00272 _sx_debug(ZONE, "external_id: Found(%d) subjectAltName/id-on-xmppAddr: '%s'", id, sc->external_id[id]); 00273 id++; 00274 OPENSSL_free(buff); 00275 } else if (altname->type == GEN_DNS) { 00276 len = ASN1_STRING_length(altname->d.dNSName); 00277 sc->external_id[id] = (char *) malloc(sizeof(char) * (len + 1)); 00278 memcpy(sc->external_id[id], ASN1_STRING_data(altname->d.dNSName), len); 00279 sc->external_id[id][len] = '\0'; // just to make sure 00280 _sx_debug(ZONE, "external_id: Found(%d) subjectAltName/dNSName: '%s'", id, sc->external_id[id]); 00281 id++; 00282 } 00283 /* Check if we're not out of space */ 00284 if (id == SX_CONN_EXTERNAL_ID_MAX_COUNT) { 00285 sk_GENERAL_NAME_pop_free(altnames, GENERAL_NAME_free); 00286 goto end; 00287 } 00288 } 00289 00290 sk_GENERAL_NAME_pop_free(altnames, GENERAL_NAME_free); 00291 } 00292 /* Get CNs */ 00293 name = X509_get_subject_name(cert); 00294 for (i = X509_NAME_get_index_by_NID(name, NID_commonName, -1); 00295 i != -1; 00296 i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) { 00297 // Get the commonName entry 00298 if ((entry = X509_NAME_get_entry(name, i)) == NULL) { 00299 _sx_debug(ZONE, "external_id: Can't get commonName(%d). Possibly malformed cert. Continuing.", i); 00300 continue; 00301 } 00302 // Get the commonName as UTF8 string 00303 len = ASN1_STRING_to_UTF8((unsigned char **) &buff, X509_NAME_ENTRY_get_data(entry)); 00304 if (len <= 0) { 00305 continue; 00306 } 00307 sc->external_id[id] = (char *) malloc(sizeof(char) * (len + 1)); 00308 memcpy(sc->external_id[id], buff, len); 00309 sc->external_id[id][len] = '\0'; // just to make sure 00310 _sx_debug(ZONE, "external_id: Found(%d) commonName: '%s'", id, sc->external_id[id]); 00311 OPENSSL_free(buff); 00312 /* Check if we're not out of space */ 00313 if (id == SX_CONN_EXTERNAL_ID_MAX_COUNT) 00314 goto end; 00315 } 00316 00317 end: 00318 X509_free(cert); 00319 return; 00320 } 00321 00322 static int _sx_ssl_handshake(sx_t s, _sx_ssl_conn_t sc) { 00323 int ret, err; 00324 char *errstring; 00325 sx_error_t sxe; 00326 00327 /* work on establishing the channel */ 00328 while(!SSL_is_init_finished(sc->ssl)) { 00329 _sx_debug(ZONE, "secure channel not established, handshake in progress"); 00330 00331 /* we can't handshake if they want to read, but there's nothing to read */ 00332 if(sc->last_state == SX_SSL_STATE_WANT_READ && BIO_pending(sc->rbio) == 0) 00333 return 0; 00334 00335 /* more handshake */ 00336 if(s->type == type_CLIENT) 00337 ret = SSL_connect(sc->ssl); 00338 else 00339 ret = SSL_accept(sc->ssl); 00340 00341 /* check if we're done */ 00342 if(ret == 1) { 00343 _sx_debug(ZONE, "secure channel established"); 00344 sc->last_state = SX_SSL_STATE_NONE; 00345 00346 s->ssf = SSL_get_cipher_bits(sc->ssl, NULL); 00347 00348 _sx_debug(ZONE, "using cipher %s (%d bits)", SSL_get_cipher_name(sc->ssl), s->ssf); 00349 _sx_ssl_get_external_id(s, sc); 00350 00351 return 1; 00352 } 00353 00354 /* error checking */ 00355 else if(ret <= 0) { 00356 err = SSL_get_error(sc->ssl, ret); 00357 00358 if(err == SSL_ERROR_WANT_READ) 00359 sc->last_state = SX_SSL_STATE_WANT_READ; 00360 else if(err == SSL_ERROR_WANT_WRITE) 00361 sc->last_state = SX_SSL_STATE_WANT_WRITE; 00362 00363 else { 00364 /* fatal error */ 00365 sc->last_state = SX_SSL_STATE_ERROR; 00366 00367 errstring = ERR_error_string(ERR_get_error(), NULL); 00368 _sx_debug(ZONE, "openssl error: %s", errstring); 00369 00370 /* do not throw an error if in wrapper mode and pre-stream */ 00371 if(!(s->state < state_STREAM && s->flags & SX_SSL_WRAPPER)) { 00372 _sx_gen_error(sxe, SX_ERR_SSL, "SSL handshake error", errstring); 00373 _sx_event(s, event_ERROR, (void *) &sxe); 00374 sx_error(s, stream_err_UNDEFINED_CONDITION, errstring); 00375 } 00376 00377 sx_close(s); 00378 00379 /* !!! drop queue */ 00380 00381 return -1; 00382 } 00383 } 00384 } 00385 00386 return 1; 00387 } 00388 00389 static int _sx_ssl_wio(sx_t s, sx_plugin_t p, sx_buf_t buf) { 00390 _sx_ssl_conn_t sc = (_sx_ssl_conn_t) s->plugin_data[p->index]; 00391 int est, ret, err; 00392 sx_buf_t wbuf; 00393 char *errstring; 00394 sx_error_t sxe; 00395 00396 /* do not encrypt when error */ 00397 if(sc->last_state == SX_SSL_STATE_ERROR) 00398 return 1; 00399 00400 _sx_debug(ZONE, "in _sx_ssl_wio"); 00401 00402 /* queue the buffer */ 00403 if(buf->len > 0) { 00404 _sx_debug(ZONE, "queueing buffer for write"); 00405 00406 jqueue_push(sc->wq, _sx_buffer_new(buf->data, buf->len, buf->notify, buf->notify_arg), 0); 00407 _sx_buffer_clear(buf); 00408 buf->notify = NULL; 00409 buf->notify_arg = NULL; 00410 } 00411 00412 /* handshake */ 00413 est = _sx_ssl_handshake(s, sc); 00414 if(est < 0) 00415 return -2; /* fatal error */ 00416 00417 /* channel established, do some real writing */ 00418 wbuf = NULL; 00419 if(est > 0 && jqueue_size(sc->wq) > 0) { 00420 _sx_debug(ZONE, "preparing queued buffer for write"); 00421 00422 wbuf = jqueue_pull(sc->wq); 00423 00424 ret = SSL_write(sc->ssl, wbuf->data, wbuf->len); 00425 if(ret <= 0) { 00426 /* something's wrong */ 00427 _sx_debug(ZONE, "write failed, requeuing buffer"); 00428 00429 /* requeue the buffer */ 00430 jqueue_push(sc->wq, wbuf, (sc->wq->front != NULL) ? sc->wq->front->priority + 1 : 0); 00431 00432 /* error checking */ 00433 err = SSL_get_error(sc->ssl, ret); 00434 00435 if(err == SSL_ERROR_ZERO_RETURN) { 00436 /* ssl channel closed, we're done */ 00437 _sx_close(s); 00438 } 00439 00440 if(err == SSL_ERROR_WANT_READ) { 00441 /* we'll be renegotiating next time */ 00442 _sx_debug(ZONE, "renegotiation started"); 00443 sc->last_state = SX_SSL_STATE_WANT_READ; 00444 } 00445 00446 else { 00447 sc->last_state = SX_SSL_STATE_ERROR; 00448 00449 /* something very bad */ 00450 errstring = ERR_error_string(ERR_get_error(), NULL); 00451 _sx_debug(ZONE, "openssl error: %s", errstring); 00452 00453 /* do not throw an error if in wrapper mode and pre-stream */ 00454 if(!(s->state < state_STREAM && s->flags & SX_SSL_WRAPPER)) { 00455 _sx_gen_error(sxe, SX_ERR_SSL, "SSL handshake error", errstring); 00456 _sx_event(s, event_ERROR, (void *) &sxe); 00457 sx_error(s, stream_err_UNDEFINED_CONDITION, errstring); 00458 } 00459 00460 sx_close(s); 00461 00462 /* !!! drop queue */ 00463 00464 return -2; /* fatal */ 00465 } 00466 } 00467 } 00468 00469 /* prepare the buffer with stuff to write */ 00470 if(BIO_pending(sc->wbio) > 0) { 00471 int bytes_pending = BIO_pending(sc->wbio); 00472 assert(buf->len == 0); 00473 _sx_buffer_alloc_margin(buf, 0, bytes_pending); 00474 BIO_read(sc->wbio, buf->data, bytes_pending); 00475 buf->len += bytes_pending; 00476 00477 /* restore notify and clean up */ 00478 if(wbuf != NULL) { 00479 buf->notify = wbuf->notify; 00480 buf->notify_arg = wbuf->notify_arg; 00481 _sx_buffer_free(wbuf); 00482 } 00483 00484 _sx_debug(ZONE, "prepared %d ssl bytes for write", buf->len); 00485 } 00486 00487 /* flag if we want to read */ 00488 if(sc->last_state == SX_SSL_STATE_WANT_READ || sc->last_state == SX_SSL_STATE_NONE) 00489 s->want_read = 1; 00490 00491 return 1; 00492 } 00493 00494 static int _sx_ssl_rio(sx_t s, sx_plugin_t p, sx_buf_t buf) { 00495 _sx_ssl_conn_t sc = (_sx_ssl_conn_t) s->plugin_data[p->index]; 00496 int est, ret, err, pending; 00497 char *errstring; 00498 sx_error_t sxe; 00499 00500 /* sanity */ 00501 if(sc->last_state == SX_SSL_STATE_ERROR) 00502 return -1; 00503 00504 _sx_debug(ZONE, "in _sx_ssl_rio"); 00505 00506 /* move the data into the ssl read buffer */ 00507 if(buf->len > 0) { 00508 _sx_debug(ZONE, "loading %d bytes into ssl read buffer", buf->len); 00509 00510 BIO_write(sc->rbio, buf->data, buf->len); 00511 00512 _sx_buffer_clear(buf); 00513 } 00514 00515 /* handshake */ 00516 est = _sx_ssl_handshake(s, sc); 00517 if(est < 0) 00518 return -1; /* fatal error */ 00519 00520 /* channel is up, slurp up the read buffer */ 00521 if(est > 0) { 00522 00523 pending = SSL_pending(sc->ssl); 00524 if(pending == 0) 00525 pending = BIO_pending(sc->rbio); 00526 00527 /* get it all */ 00528 while((pending = SSL_pending(sc->ssl)) > 0 || (pending = BIO_pending(sc->rbio)) > 0) { 00529 _sx_buffer_alloc_margin(buf, 0, pending); 00530 00531 ret = SSL_read(sc->ssl, &(buf->data[buf->len]), pending); 00532 00533 if (ret == 0) 00534 { 00535 /* ret will equal zero if the SSL stream was closed. 00536 (See the SSL_read manpage.) */ 00537 00538 /* If the SSL Shutdown happened properly, 00539 (i.e. we got an SSL "close notify") 00540 then proccess the last packet recieved. */ 00541 if (SSL_get_shutdown(sc->ssl) == SSL_RECEIVED_SHUTDOWN) 00542 { 00543 _sx_close(s); 00544 break; 00545 } 00546 00547 /* If the SSL stream was just closed and not shutdown, 00548 drop the last packet recieved. 00549 WARNING: This may cause clients that use SSLv2 and 00550 earlier to not log out properly. */ 00551 00552 err = SSL_get_error(sc->ssl, ret); 00553 00554 _sx_buffer_clear(buf); 00555 00556 00557 if(err == SSL_ERROR_ZERO_RETURN) { 00558 /* ssl channel closed, we're done */ 00559 _sx_close(s); 00560 } 00561 00562 return -1; 00563 } 00564 else if(ret < 0) { 00565 /* ret will be negative if the SSL stream needs 00566 more data, or if there was a SSL error. 00567 (See the SSL_read manpage.) */ 00568 err = SSL_get_error(sc->ssl, ret); 00569 00570 /* ssl block incomplete, need more */ 00571 if(err == SSL_ERROR_WANT_READ) { 00572 sc->last_state = SX_SSL_STATE_WANT_READ; 00573 00574 break; 00575 } 00576 00577 /* something's wrong */ 00578 _sx_buffer_clear(buf); 00579 00580 00581 /* !!! need checks for renegotiation */ 00582 00583 sc->last_state = SX_SSL_STATE_ERROR; 00584 00585 errstring = ERR_error_string(ERR_get_error(), NULL); 00586 _sx_debug(ZONE, "openssl error: %s", errstring); 00587 00588 /* do not throw an error if in wrapper mode and pre-stream */ 00589 if(!(s->state < state_STREAM && s->flags & SX_SSL_WRAPPER)) { 00590 _sx_gen_error(sxe, SX_ERR_SSL, "SSL handshake error", errstring); 00591 _sx_event(s, event_ERROR, (void *) &sxe); 00592 sx_error(s, stream_err_UNDEFINED_CONDITION, errstring); 00593 } 00594 00595 sx_close(s); 00596 00597 /* !!! drop queue */ 00598 00599 return -1; 00600 } 00601 00602 buf->len += ret; 00603 } 00604 } 00605 00606 /* flag if stuff to write */ 00607 if(BIO_pending(sc->wbio) > 0 || (est > 0 && jqueue_size(sc->wq) > 0)) 00608 s->want_write = 1; 00609 00610 /* flag if we want to read */ 00611 if(sc->last_state == SX_SSL_STATE_WANT_READ || sc->last_state == SX_SSL_STATE_NONE) 00612 s->want_read = 1; 00613 00614 if(buf->len == 0) 00615 return 0; 00616 00617 return 1; 00618 } 00619 00620 static void _sx_ssl_client(sx_t s, sx_plugin_t p) { 00621 _sx_ssl_conn_t sc; 00622 SSL_CTX *ctx; 00623 char *pemfile = NULL; 00624 int ret, i; 00625 00626 /* only bothering if they asked for wrappermode */ 00627 if(!(s->flags & SX_SSL_WRAPPER) || s->ssf > 0) 00628 return; 00629 00630 _sx_debug(ZONE, "preparing for ssl connect for %d from %s", s->tag, s->req_from); 00631 00632 /* find the ssl context for this source */ 00633 ctx = xhash_get((xht) p->private, s->req_from); 00634 if(ctx == NULL) { 00635 _sx_debug(ZONE, "using default ssl context for %d", s->tag); 00636 ctx = xhash_get((xht) p->private, "*"); 00637 } else { 00638 _sx_debug(ZONE, "using configured ssl context for %d", s->tag); 00639 } 00640 assert((int) (ctx != NULL)); 00641 00642 sc = (_sx_ssl_conn_t) calloc(1, sizeof(struct _sx_ssl_conn_st)); 00643 00644 /* create the buffers */ 00645 sc->rbio = BIO_new(BIO_s_mem()); 00646 sc->wbio = BIO_new(BIO_s_mem()); 00647 00648 /* new ssl conn */ 00649 sc->ssl = SSL_new(ctx); 00650 SSL_set_bio(sc->ssl, sc->rbio, sc->wbio); 00651 SSL_set_connect_state(sc->ssl); 00652 SSL_set_ssl_method(sc->ssl, TLSv1_client_method()); 00653 SSL_set_options(sc->ssl, SSL_OP_NO_TICKET); 00654 00655 /* empty external_id */ 00656 for (i = 0; i < SX_CONN_EXTERNAL_ID_MAX_COUNT; i++) 00657 sc->external_id[i] = NULL; 00658 00659 /* alternate pemfile */ 00660 /* !!! figure out how to error correctly here - just returning will cause 00661 * us to send a normal unencrypted stream start while the server is 00662 * waiting for ClientHelo. the server will flag an error, but it won't 00663 * help the admin at all to figure out what happened */ 00664 if(s->plugin_data[p->index] != NULL) { 00665 pemfile = ((_sx_ssl_conn_t)s->plugin_data[p->index])->pemfile; 00666 free(s->plugin_data[p->index]); 00667 s->plugin_data[p->index] = NULL; 00668 } 00669 if(pemfile != NULL) { 00670 /* load the certificate */ 00671 ret = SSL_use_certificate_file(sc->ssl, pemfile, SSL_FILETYPE_PEM); 00672 if(ret != 1) { 00673 _sx_debug(ZONE, "couldn't load alternate certificate from %s", pemfile); 00674 SSL_free(sc->ssl); 00675 free(sc); 00676 free(pemfile); 00677 return; 00678 } 00679 00680 /* load the private key */ 00681 ret = SSL_use_PrivateKey_file(sc->ssl, pemfile, SSL_FILETYPE_PEM); 00682 if(ret != 1) { 00683 _sx_debug(ZONE, "couldn't load alternate private key from %s", pemfile); 00684 SSL_free(sc->ssl); 00685 free(sc); 00686 free(pemfile); 00687 return; 00688 } 00689 00690 /* check the private key matches the certificate */ 00691 ret = SSL_check_private_key(sc->ssl); 00692 if(ret != 1) { 00693 _sx_debug(ZONE, "private key does not match certificate public key"); 00694 SSL_free(sc->ssl); 00695 free(sc); 00696 free(pemfile); 00697 return; 00698 } 00699 00700 _sx_debug(ZONE, "loaded alternate pemfile %s", pemfile); 00701 00702 free(pemfile); 00703 } 00704 00705 /* buffer queue */ 00706 sc->wq = jqueue_new(); 00707 00708 s->plugin_data[p->index] = (void *) sc; 00709 00710 /* bring the plugin online */ 00711 _sx_chain_io_plugin(s, p); 00712 } 00713 00714 static void _sx_ssl_server(sx_t s, sx_plugin_t p) { 00715 _sx_ssl_conn_t sc; 00716 SSL_CTX *ctx; 00717 int i; 00718 00719 /* only bothering if they asked for wrappermode */ 00720 if(!(s->flags & SX_SSL_WRAPPER) || s->ssf > 0) 00721 return; 00722 00723 _sx_debug(ZONE, "preparing for ssl accept for %d to %s", s->tag, s->req_to); 00724 00725 /* find the ssl context for this destination */ 00726 ctx = xhash_get((xht) p->private, s->req_to); 00727 if(ctx == NULL) { 00728 _sx_debug(ZONE, "using default ssl context for %d", s->tag); 00729 ctx = xhash_get((xht) p->private, "*"); 00730 } else { 00731 _sx_debug(ZONE, "using configured ssl context for %d", s->tag); 00732 } 00733 assert((int) (ctx != NULL)); 00734 00735 sc = (_sx_ssl_conn_t) calloc(1, sizeof(struct _sx_ssl_conn_st)); 00736 00737 /* create the buffers */ 00738 sc->rbio = BIO_new(BIO_s_mem()); 00739 sc->wbio = BIO_new(BIO_s_mem()); 00740 00741 /* new ssl conn */ 00742 sc->ssl = SSL_new(ctx); 00743 SSL_set_bio(sc->ssl, sc->rbio, sc->wbio); 00744 SSL_set_accept_state(sc->ssl); 00745 00746 /* empty external_id */ 00747 for (i = 0; i < SX_CONN_EXTERNAL_ID_MAX_COUNT; i++) 00748 sc->external_id[i] = NULL; 00749 00750 /* buffer queue */ 00751 sc->wq = jqueue_new(); 00752 00753 s->plugin_data[p->index] = (void *) sc; 00754 00755 /* bring the plugin online */ 00756 _sx_chain_io_plugin(s, p); 00757 } 00758 00760 static void _sx_ssl_free(sx_t s, sx_plugin_t p) { 00761 _sx_ssl_conn_t sc = (_sx_ssl_conn_t) s->plugin_data[p->index]; 00762 sx_buf_t buf; 00763 int i; 00764 00765 if(sc == NULL) 00766 return; 00767 00768 log_debug(ZONE, "cleaning up conn state"); 00769 00770 if(s->type == type_NONE) { 00771 free(sc); 00772 return; 00773 } 00774 00775 for (i = 0; i < SX_CONN_EXTERNAL_ID_MAX_COUNT; i++) 00776 if(sc->external_id[i] != NULL) 00777 free(sc->external_id[i]); 00778 else 00779 break; 00780 00781 if(sc->pemfile != NULL) free(sc->pemfile); 00782 00783 if(sc->ssl != NULL) SSL_free(sc->ssl); /* frees wbio and rbio too */ 00784 00785 if(sc->wq != NULL) { 00786 while((buf = jqueue_pull(sc->wq)) != NULL) 00787 _sx_buffer_free(buf); 00788 00789 jqueue_free(sc->wq); 00790 } 00791 00792 free(sc); 00793 00794 s->plugin_data[p->index] = NULL; 00795 } 00796 00797 static void _sx_ssl_unload(sx_plugin_t p) { 00798 xht contexts = (xht) p->private; 00799 void *ctx; 00800 00801 if(xhash_iter_first(contexts)) 00802 do { 00803 xhash_iter_get(contexts, NULL, NULL, &ctx); 00804 SSL_CTX_free((SSL_CTX *) ctx); 00805 } while(xhash_iter_next(contexts)); 00806 00807 xhash_free(contexts); 00808 } 00809 00810 int sx_openssl_initialized = 0; 00811 00813 int sx_ssl_init(sx_env_t env, sx_plugin_t p, va_list args) { 00814 char *name, *pemfile, *cachain; 00815 int ret; 00816 int mode; 00817 00818 _sx_debug(ZONE, "initialising ssl plugin"); 00819 00820 name = va_arg(args, char *); 00821 pemfile = va_arg(args, char *); 00822 if(pemfile == NULL) 00823 return 1; 00824 00825 if(p->private != NULL) 00826 return 1; 00827 00828 cachain = va_arg(args, char *); 00829 mode = va_arg(args, int); 00830 00831 /* !!! output openssl error messages to the debug log */ 00832 00833 /* openssl startup */ 00834 if(!sx_openssl_initialized) { 00835 SSL_library_init(); 00836 SSL_load_error_strings(); 00837 } 00838 sx_openssl_initialized = 1; 00839 00840 ret = sx_ssl_server_addcert(p, name, pemfile, cachain, mode); 00841 if(ret) 00842 return 1; 00843 00844 p->magic = SX_SSL_MAGIC; 00845 00846 p->unload = _sx_ssl_unload; 00847 00848 p->client = _sx_ssl_client; 00849 p->server = _sx_ssl_server; 00850 p->rio = _sx_ssl_rio; 00851 p->wio = _sx_ssl_wio; 00852 p->features = _sx_ssl_features; 00853 p->process = _sx_ssl_process; 00854 p->free = _sx_ssl_free; 00855 00856 return 0; 00857 } 00858 00860 int sx_ssl_server_addcert(sx_plugin_t p, char *name, char *pemfile, char *cachain, int mode) { 00861 xht contexts = (xht) p->private; 00862 SSL_CTX *ctx; 00863 SSL_CTX *tmp; 00864 STACK_OF(X509_NAME) *cert_names; 00865 X509_STORE * store; 00866 int ret; 00867 00868 if(!sx_openssl_initialized) { 00869 _sx_debug(ZONE, "ssl plugin not initialised"); 00870 return 1; 00871 } 00872 00873 if(name == NULL) 00874 name = "*"; 00875 00876 if(pemfile == NULL) 00877 return 1; 00878 00879 /* begin with fresh error stack */ 00880 ERR_clear_error(); 00881 00882 /* create the context */ 00883 ctx = SSL_CTX_new(SSLv23_method()); 00884 if(ctx == NULL) { 00885 _sx_debug(ZONE, "ssl context creation failed; %s", ERR_error_string(ERR_get_error(), NULL)); 00886 return 1; 00887 } 00888 00889 // Set allowed ciphers 00890 if (SSL_CTX_set_cipher_list(ctx, "ALL:!LOW:!SSLv2:!EXP:!aNULL") != 1) { 00891 _sx_debug(ZONE, "Can't set cipher list for SSL context: %s", ERR_error_string(ERR_get_error(), NULL)); 00892 SSL_CTX_free(ctx); 00893 return 1; 00894 } 00895 00896 /* Load the CA chain, if configured */ 00897 if (cachain != NULL) { 00898 ret = SSL_CTX_load_verify_locations (ctx, cachain, NULL); 00899 if(ret != 1) { 00900 _sx_debug(ZONE, "WARNING: couldn't load CA chain: %s; %s", cachain, ERR_error_string(ERR_get_error(), NULL)); 00901 } else { 00902 _sx_debug(ZONE, "Loaded CA verify location chain: %s", cachain); 00903 } 00904 cert_names = SSL_load_client_CA_file(cachain); 00905 if (cert_names != NULL) { 00906 SSL_CTX_set_client_CA_list(ctx, cert_names); 00907 _sx_debug(ZONE, "Loaded client CA chain: %s", cachain); 00908 } else { 00909 _sx_debug(ZONE, "WARNING: couldn't load client CA chain: %s", cachain); 00910 } 00911 } else { 00912 /* Load the default OpenlSSL certs from /etc/ssl/certs 00913 We must assume that the client certificate's CA is there 00914 00915 Note: We don't send client_CA_list here. Will possibly break some clients. 00916 */ 00917 SSL_CTX_set_default_verify_paths(ctx); 00918 _sx_debug(ZONE, "No CA chain specified. Loading SSL default CA certs: /etc/ssl/certs"); 00919 } 00920 /* Add server CRL verificaition */ 00921 store = SSL_CTX_get_cert_store(ctx); 00922 // Not sure if this should be X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL 00923 // or only X509_V_FLAG_CRL_CHECK 00924 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK); 00925 00926 /* load the certificate */ 00927 ret = SSL_CTX_use_certificate_chain_file(ctx, pemfile); 00928 if(ret != 1) { 00929 _sx_debug(ZONE, "couldn't load certificate from %s; %s", pemfile, ERR_error_string(ERR_get_error(), NULL)); 00930 SSL_CTX_free(ctx); 00931 return 1; 00932 } 00933 00934 /* load the private key */ 00935 ret = SSL_CTX_use_PrivateKey_file(ctx, pemfile, SSL_FILETYPE_PEM); 00936 if(ret != 1) { 00937 _sx_debug(ZONE, "couldn't load private key from %s; %s", pemfile, ERR_error_string(ERR_get_error(), NULL)); 00938 SSL_CTX_free(ctx); 00939 return 1; 00940 } 00941 00942 /* check the private key matches the certificate */ 00943 ret = SSL_CTX_check_private_key(ctx); 00944 if(ret != 1) { 00945 _sx_debug(ZONE, "private key does not match certificate public key; %s", ERR_error_string(ERR_get_error(), NULL)); 00946 SSL_CTX_free(ctx); 00947 return 1; 00948 } 00949 00950 _sx_debug(ZONE, "setting ssl context '%s' verify mode to %02x", name, mode); 00951 SSL_CTX_set_verify(ctx, mode, _sx_ssl_verify_callback); 00952 00953 /* create hash and create default context */ 00954 if(contexts == NULL) { 00955 contexts = xhash_new(1021); 00956 p->private = (void *) contexts; 00957 00958 /* this is the first context, if it's not the default then make a copy of it as the default */ 00959 if(!(name[0] == '*' && name[1] == 0)) { 00960 int ret = sx_ssl_server_addcert(p, "*", pemfile, cachain, mode); 00961 00962 if(ret) { 00963 /* uh-oh */ 00964 xhash_free(contexts); 00965 p->private = NULL; 00966 return 1; 00967 } 00968 } 00969 } 00970 00971 _sx_debug(ZONE, "ssl context '%s' initialised; certificate and key loaded from %s", name, pemfile); 00972 00973 /* remove an existing context with the same name before replacing it */ 00974 tmp = xhash_get(contexts, name); 00975 if(tmp != NULL) 00976 SSL_CTX_free((SSL_CTX *) tmp); 00977 00978 xhash_put(contexts, name, ctx); 00979 00980 return 0; 00981 } 00982 00983 int sx_ssl_client_starttls(sx_plugin_t p, sx_t s, char *pemfile) { 00984 assert((int) (p != NULL)); 00985 assert((int) (s != NULL)); 00986 00987 /* sanity */ 00988 if(s->type != type_CLIENT || s->state != state_STREAM) { 00989 _sx_debug(ZONE, "wrong conn type or state for client starttls"); 00990 return 1; 00991 } 00992 00993 /* check if we're already encrypted or compressed */ 00994 if(s->ssf > 0 || s->compressed) { 00995 _sx_debug(ZONE, "encrypted channel already established"); 00996 return 1; 00997 } 00998 00999 _sx_debug(ZONE, "initiating starttls sequence"); 01000 01001 /* save the given pemfile for later */ 01002 if(pemfile != NULL) { 01003 s->plugin_data[p->index] = (_sx_ssl_conn_t) calloc(1, sizeof(struct _sx_ssl_conn_st)); 01004 ((_sx_ssl_conn_t)s->plugin_data[p->index])->pemfile = strdup(pemfile); 01005 } 01006 01007 /* go */ 01008 jqueue_push(s->wbufq, _sx_buffer_new("<starttls xmlns='" uri_TLS "'/>", strlen(uri_TLS) + 20, NULL, NULL), 0); 01009 s->want_write = 1; 01010 _sx_event(s, event_WANT_WRITE, NULL); 01011 01012 return 0; 01013 }