📄 extl_tls.c
字号:
len = sizeof (ai_addr); res = getsockname (sock, (struct sockaddr *) &ai_addr, &len); if (res != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: Cannot get socket name (%s)\n", strerror (errno))); memcpy (&ai_addr, curinfo->ai_addr, curinfo->ai_addrlen); } if (eXtl_tls.proto_num == IPPROTO_TCP) { res = listen (sock, SOMAXCONN); if (res < 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: Cannot bind socket node:%s family:%d %s\n", eXtl_tls.proto_ifs, curinfo->ai_family, strerror (errno))); close (sock); sock = -1; continue; } } break; } eXosip_freeaddrinfo (addrinfo); if (sock < 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: Cannot bind on port: %i\n", eXtl_tls.proto_port)); return -1; } tls_socket = sock; if (eXtl_tls.proto_port == 0) { /* get port number from socket */ if (eXtl_tls.proto_family == AF_INET) eXtl_tls.proto_port = ntohs (((struct sockaddr_in *) &ai_addr)->sin_port); else eXtl_tls.proto_port = ntohs (((struct sockaddr_in6 *) &ai_addr)->sin6_port); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "eXosip: Binding on port %i!\n", eXtl_tls.proto_port)); } snprintf(tls_firewall_port, sizeof(tls_firewall_port), "%i", eXtl_tls.proto_port); return 0;}static inttls_tl_set_fdset(fd_set *osip_fdset, int *fd_max){ int pos; if (tls_socket<=0) return -1; eXFD_SET (tls_socket, osip_fdset); if (tls_socket > *fd_max) *fd_max = tls_socket; for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++) { if (tls_socket_tab[pos].socket > 0) { eXFD_SET (tls_socket_tab[pos].socket, osip_fdset); if (tls_socket_tab[pos].socket > *fd_max) *fd_max = tls_socket_tab[pos].socket; } } return 0;}intstatic print_ssl_error (int err){ switch (err) { case SSL_ERROR_NONE: OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL ERROR NONE - OK\n")); break; case SSL_ERROR_ZERO_RETURN: OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL ERROR ZERO RETURN - SHUTDOWN\n")); break; case SSL_ERROR_WANT_READ: OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL want read\n")); break; case SSL_ERROR_WANT_WRITE: OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL want write\n")); break; case SSL_ERROR_SSL: OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL ERROR\n")); break; case SSL_ERROR_SYSCALL: OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL ERROR SYSCALL\n")); break; default: OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL problem\n")); } return 0;}static inttls_tl_read_message(fd_set *osip_fdset){ int pos = 0; char *buf; if (FD_ISSET (tls_socket, osip_fdset)) { /* accept incoming connection */ char src6host[NI_MAXHOST]; int recvport = 0; struct sockaddr_storage sa; int sock; int i;#ifdef __linux socklen_t slen;#else int slen;#endif SSL *ssl = NULL; BIO *sbio; if (eXtl_tls.proto_family == AF_INET) slen = sizeof (struct sockaddr_in); else slen = sizeof (struct sockaddr_in6); for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++) { if (tls_socket_tab[pos].socket <= 0) break; } if (pos<0) { /* delete an old one! */ pos=0; if (tls_socket_tab[pos].socket > 0) { if (tls_socket_tab[pos].ssl_conn != NULL) { SSL_shutdown (tls_socket_tab[pos].ssl_conn); SSL_shutdown (tls_socket_tab[pos].ssl_conn); SSL_free (tls_socket_tab[pos].ssl_conn); SSL_CTX_free (tls_socket_tab[pos].ssl_ctx); } close(tls_socket_tab[pos].socket); } memset(&tls_socket_tab[pos], 0, sizeof(struct socket_tab)); } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO3, NULL, "creating TLS socket at index: %i\n", pos)); sock = accept (tls_socket, (struct sockaddr *) &sa, &slen); if (sock < 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Error accepting TLS socket\n")); } else { if (ssl_ctx!=NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "TLS connection rejected\n")); close(sock); return -1; } if (!SSL_CTX_check_private_key (ssl_ctx)) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL CTX private key check error\n")); } ssl = SSL_new (ssl_ctx); if (ssl==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Cannot create ssl connection context\n")); return -1; } if (!SSL_check_private_key (ssl)) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "SSL private key check error\n")); } 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_set_bio (ssl, sbio, sbio); /* cannot fail */ i = SSL_accept (ssl); if (i<=0) { i = SSL_get_error (ssl, i); print_ssl_error (i); SSL_shutdown (ssl); close (sock); SSL_free (ssl); if (tls_socket_tab[pos].ssl_ctx != NULL) SSL_CTX_free (tls_socket_tab[pos].ssl_ctx); tls_socket_tab[pos].ssl_conn = NULL; tls_socket_tab[pos].ssl_ctx = NULL; tls_socket_tab[pos].socket = 0; return -1; } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "New TLS connection accepted\n")); tls_socket_tab[pos].socket = sock; tls_socket_tab[pos].ssl_conn = ssl; tls_socket_tab[pos].ssl_state = 2; memset (src6host, 0, sizeof (src6host)); if (eXtl_tls.proto_family == AF_INET) recvport = ntohs (((struct sockaddr_in *) &sa)->sin_port); else recvport = ntohs (((struct sockaddr_in6 *) &sa)->sin6_port); #if defined(__arc__) { struct sockaddr_in *fromsa = (struct sockaddr_in *) &sa; char *tmp; tmp = inet_ntoa(fromsa->sin_addr); if (tmp==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Message received from: NULL:%i inet_ntoa failure\n", recvport)); } else { snprintf(src6host, sizeof(src6host), "%s", tmp); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message received from: %s:%i\n", src6host, recvport)); osip_strncpy (tls_socket_tab[pos].remote_ip, src6host, sizeof (tls_socket_tab[pos].remote_ip)); tls_socket_tab[pos].remote_port = recvport; } }#else i = getnameinfo ((struct sockaddr *) &sa, slen, src6host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Message received from: NULL:%i getnameinfo failure\n", recvport)); snprintf(src6host, sizeof(src6host), "127.0.0.1"); } else { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message received from: %s:%i\n", src6host, recvport)); osip_strncpy (tls_socket_tab[pos].remote_ip, src6host, sizeof (tls_socket_tab[pos].remote_ip)); tls_socket_tab[pos].remote_port = recvport; }#endif } } buf=NULL; for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++) { if (tls_socket_tab[pos].socket > 0 && FD_ISSET (tls_socket_tab[pos].socket, osip_fdset)) { int i; int rlen, err; if (buf==NULL) buf = (char *) osip_malloc (SIP_MESSAGE_MAX_LENGTH * sizeof (char) + 1); if (buf==NULL) return -1; /* do TLS handshake? */ if (tls_socket_tab[pos].ssl_state == 2) { i = SSL_do_handshake (tls_socket_tab[pos].ssl_conn); if (i<=0) { i = SSL_get_error (tls_socket_tab[pos].ssl_conn, i); print_ssl_error (i); SSL_shutdown (tls_socket_tab[pos].ssl_conn); close (tls_socket_tab[pos].socket); SSL_free (tls_socket_tab[pos].ssl_conn); if (tls_socket_tab[pos].ssl_ctx != NULL) SSL_CTX_free (tls_socket_tab[pos].ssl_ctx); memset (&(tls_socket_tab[pos]), 0, sizeof (tls_socket_tab[pos])); continue; } tls_socket_tab[pos].ssl_state = 3; } if (tls_socket_tab[pos].ssl_state != 3) continue; i = 0; rlen = 0; do { i = SSL_read (tls_socket_tab[pos].ssl_conn, buf + rlen, SIP_MESSAGE_MAX_LENGTH - rlen); err = SSL_get_error (tls_socket_tab[pos].ssl_conn, i); print_ssl_error (err); switch (err) { case SSL_ERROR_NONE: rlen += i; break; } if (err==SSL_ERROR_SSL || err==SSL_ERROR_SYSCALL || err==SSL_ERROR_ZERO_RETURN) { /* The TLS/SSL connection has been closed. If the protocol version is SSL 3.0 or TLS 1.0, this result code is returned only if a closure alert has occurred in the protocol, i.e. if the connection has been closed cleanly. Note that in this case SSL_ERROR_ZERO_RETURN does not necessarily indicate that the underlying transport has been closed. */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "TLS closed\n")); SSL_shutdown (tls_socket_tab[pos].ssl_conn); close (tls_socket_tab[pos].socket); SSL_free (tls_socket_tab[pos].ssl_conn); if (tls_socket_tab[pos].ssl_ctx != NULL) SSL_CTX_free (tls_socket_tab[pos].ssl_ctx); memset (&(tls_socket_tab[pos]), 0, sizeof (tls_socket_tab[pos])); rlen=0; /* discard any remaining data ? */ break; } } while (SSL_pending (tls_socket_tab[pos].ssl_conn)); if (rlen > 5) { osip_strncpy (buf + rlen, "\0", 1); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Received TLS message: \n%s\n", buf)); _eXosip_handle_incoming_message (buf, i, tls_socket_tab[pos].socket, tls_socket_tab[pos].remote_ip, tls_socket_tab[pos].remote_port); } } } if (buf!=NULL) osip_free (buf); return 0;}static int_tls_tl_find_socket (char *host, int port){ int pos; for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++) { if (tls_socket_tab[pos].socket != 0) { if (0 == osip_strcasecmp (tls_socket_tab[pos].remote_ip, host) && port == tls_socket_tab[pos].remote_port) return pos; } } return -1;}static void tls_dump_cert_info(char* s, X509* cert){ char* subj; char* issuer; subj = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); issuer = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "%s subject:%s\n", s ? s : "", subj)); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "%s issuer: %s\n", s ? s : "", issuer)); OPENSSL_free(subj); OPENSSL_free(issuer);}static void tls_dump_verification_failure(long verification_result){ char tmp[64]; snprintf(tmp, sizeof(tmp), "unknown errror"); switch(verification_result) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: snprintf(tmp, sizeof(tmp), "unable to get issuer certificate"); break; case X509_V_ERR_UNABLE_TO_GET_CRL: snprintf(tmp, sizeof(tmp), "unable to get certificate CRL"); break; case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: snprintf(tmp, sizeof(tmp), "unable to decrypt certificate's signature"); break; case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: snprintf(tmp, sizeof(tmp), "unable to decrypt CRL's signature"); break; case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: snprintf(tmp, sizeof(tmp), "unable to decode issuer public key"); break; case X509_V_ERR_CERT_SIGNATURE_FAILURE: snprintf(tmp, sizeof(tmp), "certificate signature failure"); break; case X509_V_ERR_CRL_SIGNATURE_FAILURE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -