⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 extl_tls.c

📁 libeXosip2-3.0.3.tar.gz
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  eXosip - This is the eXtended osip library.  Copyright (C) 2002,2003,2004,2005,2006,2007  Aymeric MOIZARD  - jack@atosc.org    eXosip is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2 of the License, or  (at your option) any later version.    eXosip is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.    You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#ifdef ENABLE_MPATROL#include <mpatrol.h>#endif#include "eXosip2.h"#include "eXtransport.h"#ifdef HAVE_OPENSSL_SSL_H#include <openssl/ssl.h>#define SPROTO_TLS 500#define SPROTO_DTLS 501#include <openssl/ssl.h>#include <openssl/err.h>#include <openssl/pem.h>#include <openssl/x509.h>#include <openssl/rand.h>#define SSLDEBUG 1#define PASSWORD "password"#define CLIENT_KEYFILE "ckey.pem"#define CLIENT_CERTFILE "c.pem"#define SERVER_KEYFILE "skey.pem"#define SERVER_CERTFILE "s.pem"#define CA_LIST "cacert.pem"#define RANDOM  "random.pem"#define DHFILE "dh1024.pem"#if defined(_WIN32_WCE)#define strerror(X) "-1"#endifSSL_CTX *initialize_client_ctx (const char *keyfile, const char *certfile,		       const char *password, int transport);SSL_CTX *initialize_server_ctx (const char *keyfile, const char *certfile,		       const char *password, int transport);static int tls_socket;static struct sockaddr_storage ai_addr;static char tls_firewall_ip[64];static char tls_firewall_port[10];static SSL_CTX *ssl_ctx;static SSL_CTX *client_ctx;/* persistent connection */struct socket_tab{  int socket;  char remote_ip[65];  int remote_port;  SSL *ssl_conn;  SSL_CTX *ssl_ctx;  int ssl_state;};#ifndef EXOSIP_MAX_SOCKETS#define EXOSIP_MAX_SOCKETS#endifstatic struct socket_tab tls_socket_tab[EXOSIP_MAX_SOCKETS];static inttls_tl_init(void){  tls_socket=0;  ssl_ctx=NULL;  client_ctx=NULL;  memset(&ai_addr, 0, sizeof(struct sockaddr_storage));  memset(&tls_socket_tab, 0, sizeof(struct socket_tab)*EXOSIP_MAX_SOCKETS);  memset(tls_firewall_ip, 0, sizeof(tls_firewall_ip));  memset(tls_firewall_port, 0, sizeof(tls_firewall_port));  return 0;}static inttls_tl_free(void){  int pos;  if (ssl_ctx != NULL)    SSL_CTX_free (ssl_ctx);  if (client_ctx != NULL)    SSL_CTX_free (client_ctx);  for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++)    {      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, 0, sizeof(struct socket_tab)*EXOSIP_MAX_SOCKETS);  memset(tls_firewall_ip, 0, sizeof(tls_firewall_ip));  memset(tls_firewall_port, 0, sizeof(tls_firewall_port));  memset(&ai_addr, 0, sizeof(struct sockaddr_storage));  if (tls_socket>0)    close(tls_socket);  return 0;}static intpassword_cb (char *buf, int num, int rwflag, void *userdata){  if (userdata == NULL)    {      return 0;    }  strncpy (buf, (char *) userdata, num);  buf[num - 1] = '\0';  return strlen (buf);}static voidload_dh_params (SSL_CTX * ctx, char *file){  DH *ret = 0;  BIO *bio;  if ((bio = BIO_new_file (file, "r")) == NULL)    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_ERROR, NULL,		   "eXosip: Couldn't open DH file!\n"));    }  else    {      ret = PEM_read_bio_DHparams (bio, NULL, NULL, NULL);      BIO_free (bio);      if (SSL_CTX_set_tmp_dh (ctx, ret) < 0)	OSIP_TRACE (osip_trace		    (__FILE__, __LINE__, OSIP_ERROR, NULL,		     "eXosip: Couldn't set DH param!\n"));    }}static voidgenerate_eph_rsa_key (SSL_CTX * ctx){  RSA *rsa;  rsa = RSA_generate_key (512, RSA_F4, NULL, NULL);  if (rsa != NULL)    {      if (!SSL_CTX_set_tmp_rsa (ctx, rsa))	OSIP_TRACE (osip_trace		    (__FILE__, __LINE__, OSIP_ERROR, NULL,		     "eXosip: Couldn't set RSA key!\n"));      RSA_free (rsa);    }}SSL_CTX *initialize_client_ctx (const char *keyfile, const char *certfile,		       const char *password, int transport){  SSL_METHOD *meth;  SSL_CTX *ctx;  char *passwd;  if (transport == IPPROTO_UDP)    {      meth = DTLSv1_client_method ();    }  else if (transport == IPPROTO_TCP)    {      meth = TLSv1_client_method ();    }  else    {      return NULL;    }  ctx = SSL_CTX_new (meth);  if (ctx == NULL)    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_ERROR, NULL,		   "eXosip: Couldn't create SSL_CTX!\n"));      return NULL;    }  /* SSL_CTX_set_read_ahead(ctx, 1); */  if (password != NULL)    {      passwd = osip_strdup (password);      if (passwd == NULL)	return NULL;    }  else    passwd = NULL;  SSL_CTX_set_default_passwd_cb_userdata (ctx, passwd);  SSL_CTX_set_default_passwd_cb (ctx, password_cb);  /* Load our keys and certificates */  if (!(SSL_CTX_use_certificate_file (ctx, certfile, SSL_FILETYPE_PEM)))    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_ERROR, NULL,		   "eXosip: Couldn't read client certificate file %s!\n",		   certfile));    }  if (!(SSL_CTX_use_PrivateKey_file (ctx, keyfile, SSL_FILETYPE_PEM)))    OSIP_TRACE (osip_trace		(__FILE__, __LINE__, OSIP_ERROR, NULL,		 "eXosip: Couldn't read client pkey file %s!\n", keyfile));  if (!(SSL_CTX_use_RSAPrivateKey_file (ctx, keyfile, SSL_FILETYPE_PEM)))    OSIP_TRACE (osip_trace		(__FILE__, __LINE__, OSIP_ERROR, NULL,		 "eXosip: Couldn't read client RSA key file %s!\n", keyfile));  /* Load the CAs we trust */  if (!(SSL_CTX_load_verify_locations (ctx, CA_LIST, 0)))    OSIP_TRACE (osip_trace		(__FILE__, __LINE__, OSIP_ERROR, NULL,		 "eXosip: Couldn't read CA list\n"));  {    int verify_mode = SSL_VERIFY_NONE;#if 0    verify_mode = SSL_VERIFY_PEER;#endif        SSL_CTX_set_verify(ctx, verify_mode, NULL);    SSL_CTX_set_verify_depth (ctx, 3);  }  SSL_CTX_set_options (ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 |		       SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |		       SSL_OP_CIPHER_SERVER_PREFERENCE);  osip_free (passwd);  passwd = 0;  return ctx;}SSL_CTX *initialize_server_ctx (const char *keyfile, const char *certfile,		       const char *password, int transport){  SSL_METHOD *meth;  SSL_CTX *ctx;  char *passwd;  int s_server_session_id_context = 1;  /* initialization */  SSL_library_init ();  SSL_load_error_strings ();  if (transport == IPPROTO_UDP)    {      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO3, NULL,			      "DTLSv1 server method\n"));      meth = DTLSv1_server_method ();    }  else if (transport == IPPROTO_TCP)    {      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO3, NULL,			      "TLS server method\n"));      meth = TLSv1_server_method ();    }  else    {      return NULL;    }  ctx = SSL_CTX_new (meth);  if (ctx == NULL)    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_ERROR, NULL,		   "eXosip: Couldn't create SSL_CTX!\n"));      return NULL;    }  if (password != NULL)    {      passwd = osip_strdup (password);      if (passwd == NULL)	return NULL;    }  else    passwd = NULL;  SSL_CTX_set_default_passwd_cb_userdata (ctx, passwd);  SSL_CTX_set_default_passwd_cb (ctx, password_cb);  if (transport == IPPROTO_UDP)    {      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO3, NULL,			      "DTLS read ahead\n"));      SSL_CTX_set_read_ahead (ctx, 1);    }  /* Load our keys and certificates */  if (!(SSL_CTX_use_certificate_file (ctx, certfile, SSL_FILETYPE_PEM)))    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_ERROR, NULL,		   "eXosip: Couldn't read certificate file!\n"));    }  /* Load the CAs we trust */  if (!(SSL_CTX_load_verify_locations (ctx, CA_LIST, 0)))    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_ERROR, NULL,		   "eXosip: Couldn't read CA list\n"));    }  SSL_CTX_set_verify_depth (ctx, 5);  SSL_CTX_set_options (ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 |		       SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |		       SSL_OP_CIPHER_SERVER_PREFERENCE);  if (!(SSL_CTX_use_PrivateKey_file (ctx, keyfile, SSL_FILETYPE_PEM)))    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_ERROR, NULL,		   "eXosip: Couldn't read key file: %s\n", keyfile));      return 0;    }  if (!SSL_CTX_check_private_key(ctx)) {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_ERROR, NULL,		   "check_private_key: Key '%s' does not match the public key of the certificate\n", SSL_FILETYPE_PEM));    return NULL;  }  /* Load randomness */  if (!(RAND_load_file (RANDOM, 1024 * 1024)))    OSIP_TRACE (osip_trace		(__FILE__, __LINE__, OSIP_ERROR, NULL,		 "eXosip: Couldn't load randomness\n"));  load_dh_params (ctx, DHFILE);  generate_eph_rsa_key (ctx);  SSL_CTX_set_session_id_context (ctx, (void *) &s_server_session_id_context,				  sizeof s_server_session_id_context);  osip_free (passwd);  passwd = 0;  return ctx;}static inttls_tl_open(void){  int res;  struct addrinfo *addrinfo = NULL;  struct addrinfo *curinfo;  int sock = -1;  if (eXtl_tls.proto_port < 0)    eXtl_tls.proto_port = 5061;  ssl_ctx = initialize_server_ctx (SERVER_KEYFILE, SERVER_CERTFILE, PASSWORD,				   IPPROTO_TCP);  client_ctx = initialize_client_ctx (CLIENT_KEYFILE, CLIENT_CERTFILE, PASSWORD,				      IPPROTO_TCP);  res = eXosip_get_addrinfo (&addrinfo,			     eXtl_tls.proto_ifs,			     eXtl_tls.proto_port,			     eXtl_tls.proto_num);  if (res)    return -1;  for (curinfo = addrinfo; curinfo; curinfo = curinfo->ai_next)    {      socklen_t len;      if (curinfo->ai_protocol && curinfo->ai_protocol != eXtl_tls.proto_num)        {          OSIP_TRACE (osip_trace                      (__FILE__, __LINE__, OSIP_INFO3, NULL,                       "eXosip: Skipping protocol %d\n", curinfo->ai_protocol));          continue;        }      sock = (int) socket (curinfo->ai_family, curinfo->ai_socktype,                           curinfo->ai_protocol);      if (sock < 0)        {          OSIP_TRACE (osip_trace                      (__FILE__, __LINE__, OSIP_ERROR, NULL,                       "eXosip: Cannot create socket %s!\n", strerror (errno)));          continue;        }      if (curinfo->ai_family == AF_INET6)        {#ifdef IPV6_V6ONLY          if (setsockopt_ipv6only (sock))            {              close (sock);              sock = -1;              OSIP_TRACE (osip_trace                          (__FILE__, __LINE__, OSIP_ERROR, NULL,                           "eXosip: Cannot set socket option %s!\n",                           strerror (errno)));              continue;            }#endif /* IPV6_V6ONLY */        }      res = bind (sock, curinfo->ai_addr, curinfo->ai_addrlen);      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;        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -