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

📄 extl_tls.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 4 页
字号:
      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;    }  SSL_CTX_set_default_passwd_cb_userdata (ctx, (void *) password);  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, eXosip_tls_ctx_params.root_ca_cert, 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 OSIP_SUCCESS;    }  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_dh_params (ctx, eXosip_tls_ctx_params.dh_param);  generate_eph_rsa_key (ctx);  SSL_CTX_set_session_id_context (ctx, (void *) &s_server_session_id_context,                                  sizeof s_server_session_id_context);  return ctx;}/*** @brief Initializes the OpenSSL lib and the client/server contexts.* Depending on the previously initialized eXosip TLS context (see eXosip_set_tls_ctx() ), only the necessary contexts will be initialized.* The client context will be ALWAYS initialized, the server context only if certificates are available. The following chart should illustrate* the behaviour.** possible certificates  | Client initialized			  | Server initialized* -------------------------------------------------------------------------------------* no certificate		 | yes, no cert used			  | not initialized* only client cert		 | yes, own cert (client) used    | yes, client cert used* only server cert		 | yes, server cert used		  | yes, own cert (server) used* server and client cert | yes, own cert (client) used    | yes, own cert (server) used** The file for seeding the PRNG is only needed on Windows machines. If you compile under a Windows environment, please set W32 oder _WINDOWS as* Preprocessor directives.*@return < 0 if an error occured**/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;  // initialization (outside initialize_server_ctx)  SSL_library_init ();  SSL_load_error_strings ();  if (eXosip_tls_ctx_params.server.cert[0] != '\0')    {      ssl_ctx = initialize_server_ctx (eXosip_tls_ctx_params.server.priv_key,                                       eXosip_tls_ctx_params.server.cert,                                       eXosip_tls_ctx_params.server.priv_key_pw,                                       IPPROTO_TCP);    }  //always initialize the client  client_ctx = initialize_client_ctx (eXosip_tls_ctx_params.client.priv_key,                                      eXosip_tls_ctx_params.client.cert,                                      eXosip_tls_ctx_params.server.priv_key_pw,                                      IPPROTO_TCP);//only necessary under Windows-based OS, unix-like systems use /dev/random or /dev/urandom#if defined(WIN32) || defined(_WINDOWS)#if 0  //check if a file with random data is present --> will be verified when random file is needed  if (eXosip_tls_ctx_params.random_file[0] == '\0')    {      return TLS_ERR_NO_RAND;    }#endif  /* Load randomness */  if (!(RAND_load_file (eXosip_tls_ctx_params.random_file, 1024 * 1024)))    OSIP_TRACE (osip_trace                (__FILE__, __LINE__, OSIP_ERROR, NULL,                 "eXosip: Couldn't load randomness\n"));#endif  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;        }      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 OSIP_SUCCESS;}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 OSIP_SUCCESS;}int staticprint_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 OSIP_SUCCESS;}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"));            }

⌨️ 快捷键说明

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