📄 extl_tls.c
字号:
snprintf(tmp, sizeof(tmp), "CRL signature failure"); break; case X509_V_ERR_CERT_NOT_YET_VALID: snprintf(tmp, sizeof(tmp), "certificate is not yet valid"); break; case X509_V_ERR_CERT_HAS_EXPIRED: snprintf(tmp, sizeof(tmp), "certificate has expired"); break; case X509_V_ERR_CRL_NOT_YET_VALID: snprintf(tmp, sizeof(tmp), "CRL is not yet valid"); break; case X509_V_ERR_CRL_HAS_EXPIRED: snprintf(tmp, sizeof(tmp), "CRL has expired"); break; case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: snprintf(tmp, sizeof(tmp), "format error in certificate's notBefore field"); break; case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: snprintf(tmp, sizeof(tmp), "format error in certificate's notAfter field"); break; case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: snprintf(tmp, sizeof(tmp), "format error in CRL's lastUpdate field"); break; case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: snprintf(tmp, sizeof(tmp), "format error in CRL's nextUpdate field"); break; case X509_V_ERR_OUT_OF_MEM: snprintf(tmp, sizeof(tmp), "out of memory"); break; case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: snprintf(tmp, sizeof(tmp), "self signed certificate"); break; case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: snprintf(tmp, sizeof(tmp), "self signed certificate in certificate chain"); break; case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: snprintf(tmp, sizeof(tmp), "unable to get local issuer certificate"); break; case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: snprintf(tmp, sizeof(tmp), "unable to verify the first certificate"); break; case X509_V_ERR_CERT_CHAIN_TOO_LONG: snprintf(tmp, sizeof(tmp), "certificate chain too long"); break; case X509_V_ERR_CERT_REVOKED: snprintf(tmp, sizeof(tmp), "certificate revoked"); break; case X509_V_ERR_INVALID_CA: snprintf(tmp, sizeof(tmp), "invalid CA certificate"); break; case X509_V_ERR_PATH_LENGTH_EXCEEDED: snprintf(tmp, sizeof(tmp), "path length constraint exceeded"); break; case X509_V_ERR_INVALID_PURPOSE: snprintf(tmp, sizeof(tmp), "unsupported certificate purpose"); break; case X509_V_ERR_CERT_UNTRUSTED: snprintf(tmp, sizeof(tmp), "certificate not trusted"); break; case X509_V_ERR_CERT_REJECTED: snprintf(tmp, sizeof(tmp), "certificate rejected"); break; case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: snprintf(tmp, sizeof(tmp), "subject issuer mismatch"); break; case X509_V_ERR_AKID_SKID_MISMATCH: snprintf(tmp, sizeof(tmp), "authority and subject key identifier mismatch"); break; case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: snprintf(tmp, sizeof(tmp), "authority and issuer serial number mismatch"); break; case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: snprintf(tmp, sizeof(tmp), "key usage does not include certificate signing"); break; case X509_V_ERR_APPLICATION_VERIFICATION: snprintf(tmp, sizeof(tmp), "application verification failure"); break; } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "verification failure: %s\n", tmp));}static int_tls_tl_connect_socket (char *host, int port){ int pos; int res; struct addrinfo *addrinfo = NULL; struct addrinfo *curinfo; int sock = -1; BIO *sbio; SSL *ssl; SSL_CTX *ctx; X509* cert; char src6host[NI_MAXHOST]; memset (src6host, 0, sizeof (src6host)); for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++) { if (tls_socket_tab[pos].socket == 0) { break; } } if (pos == EXOSIP_MAX_SOCKETS) return -1; res = eXosip_get_addrinfo (&addrinfo, host, port, IPPROTO_TCP); if (res) return -1; for (curinfo = addrinfo; curinfo; curinfo = curinfo->ai_next) { if (curinfo->ai_protocol && curinfo->ai_protocol != IPPROTO_TCP) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Skipping protocol %d\n", curinfo->ai_protocol)); continue; } res = getnameinfo ((struct sockaddr *) curinfo->ai_addr, curinfo->ai_addrlen, src6host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (res == 0) { int i = _tls_tl_find_socket (src6host, port); if (i>=0) { eXosip_freeaddrinfo (addrinfo); return i; } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "New binding with %s\n", src6host)); } sock = (int) socket (curinfo->ai_family, curinfo->ai_socktype, curinfo->ai_protocol); if (sock < 0) {#if !defined(OSIP_MT) || defined(_WIN32_WCE) OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot create socket!\n"));#else OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot create socket %s!\n", strerror (errno)));#endif continue; } if (curinfo->ai_family == AF_INET6) {#ifdef IPV6_V6ONLY if (setsockopt_ipv6only (sock)) { close (sock); sock = -1;#if !defined(OSIP_MT) || defined(_WIN32_WCE) OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot set socket option!\n"));#else OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot set socket option %s!\n", strerror (errno)));#endif continue; }#endif /* IPV6_V6ONLY */ } res = connect (sock, curinfo->ai_addr, curinfo->ai_addrlen); if (res < 0) {#if !defined(OSIP_MT) || defined(_WIN32_WCE) OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot bind socket node:%s family:%d\n", host, curinfo->ai_family));#else OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: Cannot bind socket node:%s family:%d %s\n", host, curinfo->ai_family, strerror (errno)));#endif close (sock); sock = -1; continue; } break; } eXosip_freeaddrinfo (addrinfo); if (sock > 0) { ctx = initialize_client_ctx (CLIENT_KEYFILE, CLIENT_CERTFILE, PASSWORD, IPPROTO_TCP); ssl = SSL_new (ctx); if (ssl == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL_new error\n")); close (sock); if (ctx != NULL) SSL_CTX_free (ctx); return -1; } sbio = BIO_new_socket (sock, BIO_NOCLOSE); if (sbio == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "BIO_new_socket error\n")); SSL_shutdown (ssl); close (sock); SSL_free (ssl); if (ctx != NULL) SSL_CTX_free (ctx); return -1; } SSL_set_bio (ssl, sbio, sbio); res = SSL_connect (ssl); if (res < 1) { res = SSL_get_error (ssl, res); print_ssl_error (res); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL_connect error\n")); SSL_shutdown (ssl); close (sock); SSL_free (ssl); if (ctx != NULL) SSL_CTX_free (ctx); return -1; } cert = SSL_get_peer_certificate(ssl); if (cert != 0) { tls_dump_cert_info("tls_connect: remote certificate: ", cert); if (SSL_get_verify_result(ssl) != X509_V_OK) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Failed to verify remote certificate\n")); tls_dump_verification_failure(SSL_get_verify_result(ssl)); } X509_free(cert); } tls_socket_tab[pos].socket = sock; if (src6host[0]=='\0') osip_strncpy (tls_socket_tab[pos].remote_ip, host, sizeof (tls_socket_tab[pos].remote_ip) - 1); else osip_strncpy (tls_socket_tab[pos].remote_ip, src6host, sizeof (tls_socket_tab[pos].remote_ip) - 1); tls_socket_tab[pos].remote_port = port; tls_socket_tab[pos].ssl_conn = ssl; tls_socket_tab[pos].ssl_state = 3; return pos; } return -1;}static inttls_tl_send_message(osip_transaction_t * tr, osip_message_t * sip, char *host, int port, int out_socket){ size_t length = 0; char *message; int i; SSL *ssl = NULL; if (host == NULL) { host = sip->req_uri->host; if (sip->req_uri->port != NULL) port = osip_atoi (sip->req_uri->port); else port = 5061; } if (port == 5060) port = 5061; /* remove preloaded route if there is no tag in the To header */ { osip_route_t *route=NULL; osip_generic_param_t *tag=NULL; osip_message_get_route (sip, 0, &route); osip_to_get_tag (sip->to, &tag); if (tag==NULL && route != NULL && route->url != NULL) { osip_list_remove(&sip->routes, 0); } i = osip_message_to_str (sip, &message, &length); if (tag==NULL && route != NULL && route->url != NULL) { osip_list_add(&sip->routes, route, 0); } } if (i != 0 || length <= 0) { return -1; } if (out_socket > 0) { int pos; for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++) { if (tls_socket_tab[pos].socket != 0) { if (tls_socket_tab[pos].socket==out_socket) { out_socket = tls_socket_tab[pos].socket; ssl = tls_socket_tab[pos].ssl_conn; OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message sent: \n%s (reusing REQUEST connection)\n", message)); break; } } } if (pos == EXOSIP_MAX_SOCKETS) out_socket=0; } /* Step 1: find existing socket to send message */ if (out_socket <= 0) { int pos = _tls_tl_find_socket (host, port); /* Step 2: create new socket with host:port */ if (pos < 0) { pos = _tls_tl_connect_socket (host, port); } if (pos >= 0) { out_socket = tls_socket_tab[pos].socket; ssl = tls_socket_tab[pos].ssl_conn; } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message sent: \n%s (to dest=%s:%i)\n", message, host, port)); } if (out_socket <= 0 || ssl==NULL) { return -1; } SSL_set_mode (ssl, SSL_MODE_AUTO_RETRY); while (1) { i = SSL_write (ssl, (const void *) message, length); if (i<=0) { i = SSL_get_error (ssl, i); print_ssl_error (i); if (i==SSL_ERROR_WANT_READ) continue; osip_free (message); return -1; } break; } osip_free (message); return 0;}static inttls_tl_keepalive(void){ return 0;}static inttls_tl_set_socket(int socket){ tls_socket = socket; return 0;}static inttls_tl_masquerade_contact(const char *public_address, int port){ if (public_address == NULL || public_address[0] == '\0') { memset (tls_firewall_ip, '\0', sizeof (tls_firewall_ip)); return 0; } snprintf (tls_firewall_ip, sizeof (tls_firewall_ip), "%s", public_address); if (port > 0) { snprintf (tls_firewall_port, sizeof(tls_firewall_port), "%i", port); } return 0;}static inttls_tl_get_masquerade_contact(char *ip, int ip_size, char *port, int port_size){ memset(ip, 0, ip_size); memset(port, 0, port_size); if (tls_firewall_ip!='\0') snprintf(ip, ip_size, "%s", tls_firewall_ip); if (tls_firewall_port!='\0') snprintf(port, port_size, "%s", tls_firewall_port); return 0;}struct eXtl_protocol eXtl_tls = { 1, 5061, "TLS", "0.0.0.0", IPPROTO_TCP, AF_INET, 0, 0, &tls_tl_init, &tls_tl_free, &tls_tl_open, &tls_tl_set_fdset, &tls_tl_read_message, &tls_tl_send_message, &tls_tl_keepalive, &tls_tl_set_socket, &tls_tl_masquerade_contact, &tls_tl_get_masquerade_contact};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -