/* * Called when new tcp connection is accepted or connected, create ssl * data structures here, there is no need to acquire any lock, because the * connection is being created by a new process and on other process has * access to it yet, this is called before adding the tcp_connection * structure into the hash */ int tls_tcpconn_init(struct tcp_connection *c, int sock) { struct tls_domain *dom; struct usr_avp *avp; int_str val; /* * new connection within a single process, no lock necessary */ LM_DBG("entered: Creating a whole new ssl connection\n"); /* * do everything tcpconn_new wouldn't do when TLS */ c->type = PROTO_TLS; c->rcv.proto = PROTO_TLS; c->flags = 0; c->timeout = get_ticks() + DEFAULT_TCP_CONNECTION_LIFETIME; if (c->state == S_CONN_ACCEPT) { LM_DBG("looking up socket based TLS server " "domain [%s:%d]\n", ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port); dom = tls_find_server_domain(&c->rcv.dst_ip, c->rcv.dst_port); if (dom) { LM_DBG("found socket based TLS server domain " "[%s:%d]\n", ip_addr2a(&dom->addr), dom->port); c->extra_data = SSL_new(dom->ctx); } else { LM_ERR("no TLS server domain found\n"); return -1; } } else if (c->state == S_CONN_CONNECT) { avp = NULL; if (tls_client_domain_avp > 0) { avp = search_first_avp(0, tls_client_domain_avp, &val, 0); } else { LM_DBG("name based TLS client domains are disabled\n"); } if (!avp) { LM_DBG("no TLS client doman AVP set, looking " "for socket based TLS client domain\n"); dom = tls_find_client_domain(&c->rcv.src_ip, c->rcv.src_port); if (dom) { LM_DBG("found socket based TLS client domain " "[%s:%d]\n", ip_addr2a(&dom->addr), dom->port); c->extra_data = SSL_new(dom->ctx); } else { LM_ERR("no TLS client domain found\n"); return -1; } } else { LM_DBG("TLS client domain AVP found = '%.*s'\n", val.s.len, ZSW(val.s.s)); dom = tls_find_client_domain_name(val.s); if (dom) { LM_DBG("found name based TLS client domain " "'%.*s'\n", val.s.len, ZSW(val.s.s)); c->extra_data = SSL_new(dom->ctx); } else { LM_DBG("no name based TLS client domain found, " "trying socket based TLS client domains\n"); dom = tls_find_client_domain(&c->rcv.src_ip, c->rcv.src_port); if (dom) { LM_DBG("found socket based TLS client domain [%s:%d]\n", ip_addr2a(&dom->addr), dom->port); c->extra_data = SSL_new(dom->ctx); } else { LM_ERR("no TLS client domain found\n"); return -1; } } } } else { LM_ERR("invalid connection state (bug in TCP code)\n"); return -1; } if (!c->extra_data) { LM_ERR("failed to create SSL structure\n"); return -1; } #ifndef OPENSSL_NO_KRB5 if ( ((SSL *)c->extra_data)->kssl_ctx ) { kssl_ctx_free( ((SSL *)c->extra_data)->kssl_ctx ); ((SSL *)c->extra_data)->kssl_ctx = 0; } #endif if (c->state == S_CONN_ACCEPT) { LM_DBG("Setting in ACCEPT mode (server)\n"); SSL_set_accept_state((SSL *) c->extra_data); } else if (c->state == S_CONN_CONNECT) { LM_DBG("Setting in CONNECT mode (client)\n"); SSL_set_connect_state((SSL *) c->extra_data); } return 0; }
static int tls_conn_init(struct tcp_connection* c) { struct tls_domain *dom; struct usr_avp *avp; int_str val; /* * new connection within a single process, no lock necessary */ LM_DBG("entered: Creating a whole new ssl connection\n"); if ( c->flags&F_CONN_ACCEPTED ) { /* connection created as a result of an accept -> server */ c->proto_flags = F_TLS_DO_ACCEPT; LM_DBG("looking up socket based TLS server " "domain [%s:%d]\n", ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port); dom = tls_find_server_domain(&c->rcv.dst_ip, c->rcv.dst_port); if (dom) { LM_DBG("found socket based TLS server domain " "[%s:%d]\n", ip_addr2a(&dom->addr), dom->port); c->extra_data = SSL_new(dom->ctx); } else { LM_ERR("no TLS server domain found\n"); return -1; } } else { /* connection created as a result of a connect -> client */ avp = NULL; c->proto_flags = F_TLS_DO_CONNECT; if (tls_client_domain_avp > 0) { avp = search_first_avp(0, tls_client_domain_avp, &val, 0); } else { LM_DBG("name based TLS client domains are disabled\n"); } if (!avp) { LM_DBG("no TLS client doman AVP set, looking " "for socket based TLS client domain\n"); dom = tls_find_client_domain(&c->rcv.src_ip, c->rcv.src_port); if (dom) { LM_DBG("found socket based TLS client domain " "[%s:%d]\n", ip_addr2a(&dom->addr), dom->port); c->extra_data = SSL_new(dom->ctx); } else { LM_ERR("no TLS client domain found\n"); return -1; } } else { LM_DBG("TLS client domain AVP found = '%.*s'\n", val.s.len, ZSW(val.s.s)); dom = tls_find_client_domain_name(val.s); if (dom) { LM_DBG("found name based TLS client domain " "'%.*s'\n", val.s.len, ZSW(val.s.s)); c->extra_data = SSL_new(dom->ctx); } else { LM_DBG("no name based TLS client domain found, " "trying socket based TLS client domains\n"); dom = tls_find_client_domain(&c->rcv.src_ip, c->rcv.src_port); if (dom) { LM_DBG("found socket based TLS client domain [%s:%d]\n", ip_addr2a(&dom->addr), dom->port); c->extra_data = SSL_new(dom->ctx); } else { LM_ERR("no TLS client domain found\n"); return -1; } } } } if (!c->extra_data) { LM_ERR("failed to create SSL structure\n"); return -1; } #ifndef OPENSSL_NO_KRB5 if ( ((SSL *)c->extra_data)->kssl_ctx ) { kssl_ctx_free( ((SSL *)c->extra_data)->kssl_ctx ); ((SSL *)c->extra_data)->kssl_ctx = 0; } #endif if ( c->proto_flags & F_TLS_DO_ACCEPT ) { LM_DBG("Setting in ACCEPT mode (server)\n"); SSL_set_accept_state((SSL *) c->extra_data); } else { LM_DBG("Setting in CONNECT mode (client)\n"); SSL_set_connect_state((SSL *) c->extra_data); } return 0; }