Esempio n. 1
0
/**
 * Read a from a stream and handle restarts if nessecary
 */
ssize_t read_from_stream(BIO* bio, char* buffer, ssize_t length) {

    ssize_t r = -1;

    while (r < 0) {

        r = BIO_read(bio, buffer, length);
        if (r == 0) {

            print_ssl_error("Reached the end of the data stream.\n", stdout);
            continue;

        } else if (r < 0) {

            if (!BIO_should_retry(bio)) {

                print_ssl_error("BIO_read should retry test failed.\n", stdout);
                continue;
            }

            /* It would be prudent to check the reason for the retry and handle
             * it appropriately here */
        }

    };

    return r;
}
Esempio n. 2
0
/* Load private key and certificate from file
 */
int ssl_load_key_cert(char *file, rsa_context **private_key, x509_cert **certificate) {
	int result;

	if (file == NULL) {
		return -1;
	}

	if ((*private_key = (rsa_context*)malloc(sizeof(rsa_context))) == NULL) {
		return -1;
	}
	memset(*private_key, 0, sizeof(rsa_context));

	if ((result = x509parse_keyfile(*private_key, file, NULL)) != 0) {
		print_ssl_error("Error loading RSA private key", result);
		return -1;
	}

	if ((*certificate = (x509_cert*)malloc(sizeof(x509_cert))) == NULL) {
		return -1;
	}
	memset(*certificate, 0, sizeof(x509_cert));

	if ((result = x509parse_crtfile(*certificate, file)) != 0) {
		print_ssl_error("Error loading X.509 certificates", result);
		return -1;
	}

	return 0;
}
Esempio n. 3
0
void gtget_ssl_connect(connection_t * conn)
{
  int ret;
  sslparam_t *ssl = (sslparam_t *) conn->ssl;

  if (conn->proxy->host)
    proxy_connect(conn);

  ssl_set_bio(&ssl->ssl, net_recv, &conn->sockfd, net_send, &conn->sockfd);

  while ((ret = ssl_handshake(&ssl->ssl))) {
    if (ret != POLARSSL_ERR_NET_WANT_WRITE && ret != POLARSSL_ERR_NET_WANT_READ)
      break;
  }

  if (ret) {
    if (conn->verbosity >= 1) {
      write2f("ssl_handshake() @ %d returned %d, ", conn->sockfd, -ret);
      print_ssl_error(ret);
    }
    die(conn, "ssl_handshake() failed", NULL);
  }

  if (conn->verbosity >= 1)
    write2f(" => ssl_handshake OK. %s\n", ssl_get_ciphersuite(&ssl->ssl));

  conn->read = gtget_ssl_read;
  conn->write = gtget_ssl_write;
}
Esempio n. 4
0
/**
 * Connect to a host using an encrypted stream
 */
BIO* connect_encrypted(char* host_and_port, char* store_path, char store_type, SSL_CTX** ctx, SSL** ssl) {

    BIO* bio = NULL;
    int r = 0;

    /* Set up the SSL pointers */
    *ctx = SSL_CTX_new(SSLv23_client_method());
    *ssl = NULL;

    /* Load the trust store from the pem location in argv[2] */
    if (store_type == 'f')
        r = SSL_CTX_load_verify_locations(*ctx, store_path, NULL);
    else
        r = SSL_CTX_load_verify_locations(*ctx, NULL, store_path);
    if (r == 0) {

        print_ssl_error_2("Unable to load the trust store from %s.\n", store_path, stdout);
        return NULL;
    }

    /* Setting up the BIO SSL object */
    bio = BIO_new_ssl_connect(*ctx);
    BIO_get_ssl(bio, ssl);
    if (!(*ssl)) {

        print_ssl_error("Unable to allocate SSL pointer.\n", stdout);
        return NULL;
    }
    SSL_set_mode(*ssl, SSL_MODE_AUTO_RETRY);

    /* Attempt to connect */
    BIO_set_conn_hostname(bio, host_and_port);

    /* Verify the connection opened and perform the handshake */
    if (BIO_do_connect(bio) < 1) {

        print_ssl_error_2("Unable to connect BIO.%s\n", host_and_port, stdout);
        return NULL;
    }

    if (SSL_get_verify_result(*ssl) != X509_V_OK) {

        print_ssl_error("Unable to verify connection result.\n", stdout);
    }

    return bio;
}
Esempio n. 5
0
static int
shutdown_free_server_dtls (int pos)
{
  int i, err;

  if (dtls_socket_tab[pos].ssl_type == 1)
    {
      if (dtls_socket_tab[pos].ssl_conn != NULL)
	{
#ifdef SSLDEBUG
	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO3, NULL,
				  "DTLS server SSL_shutdown\n"));
#endif

	  i = SSL_shutdown (dtls_socket_tab[pos].ssl_conn);

	  if (i <= 0)
	    {
	      err = SSL_get_error (dtls_socket_tab[pos].ssl_conn, i);
	      print_ssl_error (err);
#ifdef SSLDEBUG

	      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,
				      "DTLS server shutdown <= 0\n"));
#endif
	    }
	  else
	    {
#ifdef SSLDEBUG
	      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO3, NULL,
				      "DTLS server shutdown > 0\n"));
#endif

	    }

	  SSL_free (dtls_socket_tab[pos].ssl_conn);

#if 0
	  if (dtls_socket_tab[pos].ssl_ctx != NULL)
	    SSL_CTX_free (dtls_socket_tab[pos].ssl_ctx);
#endif

	  memset (&(dtls_socket_tab[pos]), 0,
		  sizeof (struct socket_tab));

	  return 0;
	}
      else
	{
	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,
				  "DTLS server shutdown: invalid SSL object!\n"));
	  return -1;
	}
    }
  return -1;
}
Esempio n. 6
0
/**
 * Connect to a host using an unencrypted stream
 */
BIO* connect_unencrypted(char* host_and_port) {

    BIO* bio = NULL;

    /* Create a new connection */
    bio = BIO_new_connect(host_and_port);
    if (bio == NULL) {

        print_ssl_error("Unable to create a new unencrypted BIO object.\n", stdout);
        return NULL;
    }

    /* Verify successful connection */
    if (BIO_do_connect(bio) != 1) {

        print_ssl_error("Unable to connect unencrypted.\n", stdout);
        close_connection(bio);
        return NULL;
    }

    return bio;
}
Esempio n. 7
0
/* Load CA CRL from file
 */
int ssl_load_ca_crl(char *file, x509_crl **ca_crl) {
	int result;

	if (file == NULL) {
		return -1;
	}

	if ((*ca_crl = (x509_crl*)malloc(sizeof(x509_crl))) == NULL) {
		return -1;
	}
	memset(*ca_crl, 0, sizeof(x509_crl));

	if ((result = x509parse_crlfile(*ca_crl, file)) != 0) {
		print_ssl_error("Error loading X.509 CA CRL", result);
		return -1;
	}

	return 0;
}
Esempio n. 8
0
/* Load CA certificate from file.
 */
int ssl_load_ca_cert(char *file, x509_cert **ca_certificate) {
	int result;

	if (file == NULL) {
		return -1;
	}

	if ((*ca_certificate = (x509_cert*)malloc(sizeof(x509_cert))) == NULL) {
		return -1;
	}
	memset(*ca_certificate, 0, sizeof(x509_cert));

	if ((result = x509parse_crtfile(*ca_certificate, file)) != 0) {
		print_ssl_error("Error loading X.509 CA certificate", result);
		return -1;
	}

	return 0;
}
Esempio n. 9
0
/**
 * Write to a stream and handle restarts if nessecary
 */
int write_to_stream(BIO* bio, char* buffer, ssize_t length) {

    ssize_t r = -1;

    while (r < 0) {

        r = BIO_write(bio, buffer, length);
        if (r <= 0) {

            if (!BIO_should_retry(bio)) {

                print_ssl_error("BIO_read should retry test failed.\n", stdout);
                continue;
            }

            /* It would be prudent to check the reason for the retry and handle
             * it appropriately here */
        }

    }

    return r;
}
Esempio n. 10
0
static int
dtls_tl_send_message(osip_transaction_t * tr, osip_message_t * sip, char *host,
                    int port, int out_socket)
{
  int len = 0;
  size_t length = 0;
  struct addrinfo *addrinfo;
  struct __eXosip_sockaddr addr;
  char *message;

  char ipbuf[INET6_ADDRSTRLEN];
  int i;

  int pos;
  struct socket_tab *socket_tab_used=NULL;
  BIO *sbio=NULL;

  if (dtls_socket <= 0)
    return -1;

  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;

  if (MSG_IS_REQUEST(sip))
    {
      if (MSG_IS_REGISTER(sip)
	  ||MSG_IS_INVITE(sip)
	  ||MSG_IS_SUBSCRIBE(sip)
	  || MSG_IS_NOTIFY(sip))
	eXtl_update_local_target(sip);
    }

  i=-1;
#ifndef MINISIZE
  if (tr!=NULL && tr->record.name[0]!='\0' && tr->record.srventry[0].srv[0]!='\0')
    {
      /* always choose the first here.
	 if a network error occur, remove first entry and
	 replace with next entries.
      */
      osip_srv_entry_t *srv;
      int n=0;
      for (srv = &tr->record.srventry[0];
	   n<10 && tr->record.srventry[0].srv[0];
	   srv = &tr->record.srventry[0])
	{
	  i = eXosip_get_addrinfo (&addrinfo, srv->srv, srv->port, IPPROTO_UDP);
	  if (i == 0)
	    {
	      host = srv->srv;
	      port = srv->port;
	      break;
	    }
	  memmove(&tr->record.srventry[0], &tr->record.srventry[1], 9*sizeof(osip_srv_entry_t));
	  memset(&tr->record.srventry[9], 0, sizeof(osip_srv_entry_t));
	  i=-1;
	  /* copy next element */
	  n++;
	}
    }
#endif
  
  /* if SRV was used, distination may be already found */
  if (i != 0)
    {
      i = eXosip_get_addrinfo (&addrinfo, host, port, IPPROTO_UDP);
    }
  
  if (i != 0)
    {
      return -1;
    }
  
  memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen);
  len = addrinfo->ai_addrlen;
  
  eXosip_freeaddrinfo (addrinfo);
  
  /* 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;
    }
  
  switch ( ((struct sockaddr *)&addr)->sa_family )
    {
    case AF_INET:
      inet_ntop (((struct sockaddr *)&addr)->sa_family, &(((struct sockaddr_in *) &addr)->sin_addr),
		 ipbuf, sizeof (ipbuf));
      break;
    case AF_INET6:
      inet_ntop (((struct sockaddr *)&addr)->sa_family,
		 &(((struct sockaddr_in6 *) &addr)->sin6_addr), ipbuf,
		 sizeof (ipbuf));
      break;
    default:
      strncpy (ipbuf, "(unknown)", sizeof (ipbuf));
      break;
    }
  
  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL,
                          "Message sent: \n%s (to dest=%s:%i)\n",
                          message, ipbuf, port));

  for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++)
    {
      if (dtls_socket_tab[pos].ssl_conn != NULL
	  && dtls_socket_tab[pos].ssl_type == EXOSIP_AS_A_SERVER)
	{
	  if (dtls_socket_tab[pos].remote_port == port &&
	      (strcmp (dtls_socket_tab[pos].remote_ip, ipbuf) == 0))
	    {
	      BIO *rbio;
	      socket_tab_used = &dtls_socket_tab[pos];
	      rbio = BIO_new_dgram (dtls_socket, BIO_NOCLOSE);
	      BIO_dgram_set_peer (rbio, &addr);
	      dtls_socket_tab[pos].ssl_conn->rbio = rbio;
	      break;
	    }
	}
    }
  if (socket_tab_used==NULL)
    {
      for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++)
	{
	  if (dtls_socket_tab[pos].ssl_conn != NULL
	      && dtls_socket_tab[pos].ssl_type == EXOSIP_AS_A_CLIENT)
	    {
	      if (dtls_socket_tab[pos].remote_port == port &&
		  (strcmp (dtls_socket_tab[pos].remote_ip, ipbuf) == 0))
		{
		  BIO *rbio;
		  socket_tab_used = &dtls_socket_tab[pos];
		  rbio = BIO_new_dgram (dtls_socket, BIO_NOCLOSE);
		  BIO_dgram_set_peer (rbio, &addr);
		  dtls_socket_tab[pos].ssl_conn->rbio = rbio;
		  break;
		}
	    }
	}
    }

  if (socket_tab_used==NULL)
    {
      /* delete an old one! */
      pos=0;
      if (dtls_socket_tab[pos].ssl_conn != NULL)
	{
	  shutdown_free_client_dtls (pos);
	  shutdown_free_server_dtls (pos);
	}
      
      memset(&dtls_socket_tab[pos], 0, sizeof(struct socket_tab));
    }
  
  if (dtls_socket_tab[pos].ssl_conn == NULL)
    {
      /* create a new one */
      SSL_CTX_set_read_ahead (client_ctx, 1);
      dtls_socket_tab[pos].ssl_conn = SSL_new (client_ctx);

      if (dtls_socket_tab[pos].ssl_conn == NULL)
	{
	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,
				  "DTLS SSL_new error\n"));

	  if (dtls_socket_tab[pos].ssl_conn != NULL)
	    {
	      shutdown_free_client_dtls (pos);
	      shutdown_free_server_dtls (pos);
	    }
	  
	  memset(&dtls_socket_tab[pos], 0, sizeof(struct socket_tab));

	  osip_free (message);
	  return -1;
	}

      if (connect (dtls_socket, (struct sockaddr *) &addr, sizeof (addr)) == -1)
	{
	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,
				  "DTLS connect error\n"));
	  if (dtls_socket_tab[pos].ssl_conn != NULL)
	    {
	      shutdown_free_client_dtls (pos);
	      shutdown_free_server_dtls (pos);
	    }
	  
	  memset(&dtls_socket_tab[pos], 0, sizeof(struct socket_tab));

	  osip_free (message);
	  return -1;
	}
      
      SSL_set_options (dtls_socket_tab[pos].ssl_conn, SSL_OP_NO_QUERY_MTU);
      SSL_set_mtu (dtls_socket_tab[pos].ssl_conn, 2000);
      SSL_set_connect_state (dtls_socket_tab[pos].ssl_conn);
      sbio = BIO_new_dgram (dtls_socket, BIO_NOCLOSE);
      BIO_ctrl_set_connected (sbio, 1, (struct sockaddr *) &addr);
      SSL_set_bio (dtls_socket_tab[pos].ssl_conn, sbio, sbio);

      dtls_socket_tab[pos].ssl_type = 2;
      dtls_socket_tab[pos].ssl_state = 2;
      
      osip_strncpy (dtls_socket_tab[pos].remote_ip, ipbuf,
		    sizeof (dtls_socket_tab[pos].remote_ip));
      dtls_socket_tab[pos].remote_port = port;
    }

  i = SSL_write (dtls_socket_tab[pos].ssl_conn, message, length);

  if (i<0)
    {
      i = SSL_get_error (dtls_socket_tab[pos].ssl_conn, i);
      print_ssl_error (i);
      if (i==SSL_ERROR_SSL
	  || i==SSL_ERROR_SYSCALL)
	{
	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,
				  "DTLS SSL_write error\n"));
	  if (dtls_socket_tab[pos].ssl_conn != NULL)
	      {
		shutdown_free_client_dtls (pos);
		shutdown_free_server_dtls (pos);
	      }
	  
	  memset(&dtls_socket_tab[pos], 0, sizeof(struct socket_tab));
	  
	}

#ifndef MINISIZE
      /* delete first SRV entry that is not reachable */
      if (tr->record.name[0]!='\0' && tr->record.srventry[0].srv[0]!='\0')
	{
	  memmove(&tr->record.srventry[0], &tr->record.srventry[1], 9*sizeof(osip_srv_entry_t));
	  memset(&tr->record.srventry[9], 0, sizeof(osip_srv_entry_t));
	  osip_free (message);
	  return 0; /* retry for next retransmission! */
	}
#endif
      /* SIP_NETWORK_ERROR; */
      osip_free (message);
      return -1;
    }

  if (eXosip.keep_alive > 0)
    {
      if (MSG_IS_REGISTER (sip))
        {
          eXosip_reg_t *reg = NULL;
	  
          if (_eXosip_reg_find (&reg, tr) == 0)
            {
              memcpy (&(reg->addr), &addr, len);
              reg->len = len;
            }
        }
    }
  
  osip_free (message);
  return 0;
}
Esempio n. 11
0
static int
dtls_tl_read_message(fd_set *osip_fdset)
{
  char *enc_buf;
  char *dec_buf;
  int i;
  int enc_buf_len;

  if (dtls_socket<=0)
    return -1;
  
  if (FD_ISSET (dtls_socket, osip_fdset))
    {
      struct sockaddr_storage sa;
      
#ifdef __linux
      socklen_t slen;
#else
      int slen;
#endif
      if (eXtl_dtls.proto_family == AF_INET)
	slen = sizeof (struct sockaddr_in);
      else
	slen = sizeof (struct sockaddr_in6);
      
      enc_buf = (char *) osip_malloc (SIP_MESSAGE_MAX_LENGTH * sizeof (char) + 1);
      if (enc_buf==NULL)
	return -1;

      enc_buf_len = recvfrom (dtls_socket, enc_buf,
		    SIP_MESSAGE_MAX_LENGTH, 0,
		    (struct sockaddr *) &sa, &slen);
      
      if (enc_buf_len > 5)
	{
	  char src6host[NI_MAXHOST];
	  int recvport = 0;
	  int err;
	  
	  BIO *rbio;
	  struct socket_tab *socket_tab_used=NULL;
	  int pos;

	  osip_strncpy (enc_buf + enc_buf_len, "\0", 1);
	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL,
				  "Received message: \n%s\n", enc_buf));

	  memset (src6host, 0, sizeof (src6host));
	  
	  if (eXtl_dtls.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));
	      }
	  }
#else
	  err = getnameinfo ((struct sockaddr *) &sa, slen,
			     src6host, NI_MAXHOST,
			     NULL, 0, NI_NUMERICHOST);
	  
	  if (err != 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));
	    }
#endif
	  
	  OSIP_TRACE (osip_trace
		      (__FILE__, __LINE__, OSIP_INFO1, NULL,
		       "Message received from: %s:%i\n",
		       src6host, recvport));

	  for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++)
	    {
	      if (dtls_socket_tab[pos].ssl_conn != NULL)
		{
		  if (dtls_socket_tab[pos].remote_port == recvport &&
		      (strcmp (dtls_socket_tab[pos].remote_ip, src6host) == 0))
		    {
		      socket_tab_used = &dtls_socket_tab[pos];
		      break;
		    }
		}
	    }

	  if (socket_tab_used==NULL)
	    {
	      for (pos = 0; pos < EXOSIP_MAX_SOCKETS; pos++)
		{
		  if (dtls_socket_tab[pos].ssl_conn == NULL)
		    {
		      /* should accept this connection? */
		      break;
		    }
		}

	      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO3, NULL,
				      "creating DTLS socket at index: %i\n", pos));
	      if (pos<0)
		{
		  /* delete an old one! */
		  pos=0;
		  if (dtls_socket_tab[pos].ssl_conn != NULL)
		    {
		      shutdown_free_client_dtls (pos);
		      shutdown_free_server_dtls (pos);
		    }

		  memset(&dtls_socket_tab[pos], 0, sizeof(struct socket_tab));
		}
	    }

	  if (dtls_socket_tab[pos].ssl_conn==NULL)
	    {
	      BIO *wbio;
	      if (!SSL_CTX_check_private_key (server_ctx))
		{
		  OSIP_TRACE (osip_trace
			      (__FILE__, __LINE__, OSIP_ERROR, NULL,
			       "SSL CTX private key check error\n"));
		  osip_free(enc_buf);
		  return -1;
		}

	      /* behave as a server: */
	      dtls_socket_tab[pos].ssl_conn = SSL_new (server_ctx);
	      if (dtls_socket_tab[pos].ssl_conn == NULL)
		{
		  OSIP_TRACE (osip_trace
			      (__FILE__, __LINE__, OSIP_ERROR, NULL,
			       "SSL_new error\n"));
		  osip_free(enc_buf);
		  return -1;
		}

	      /* No MTU query */
	      SSL_set_options (dtls_socket_tab[pos].ssl_conn, SSL_OP_NO_QUERY_MTU);
	      SSL_set_mtu (dtls_socket_tab[pos].ssl_conn, 2000);
	      /* MTU query */
	      /* BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); */
	      SSL_set_options (dtls_socket_tab[pos].ssl_conn, SSL_OP_COOKIE_EXCHANGE);
	      wbio = BIO_new_dgram (dtls_socket,
				    BIO_NOCLOSE);
	      BIO_dgram_set_peer (wbio, &sa);
	      SSL_set_bio (dtls_socket_tab[pos].ssl_conn, NULL, wbio);

	      SSL_set_accept_state (dtls_socket_tab[pos].ssl_conn);

	      dtls_socket_tab[pos].ssl_state = 0;
	      dtls_socket_tab[pos].ssl_type = EXOSIP_AS_A_SERVER;

	      osip_strncpy (dtls_socket_tab[pos].remote_ip, src6host,
			    sizeof (dtls_socket_tab[pos].remote_ip));
	      dtls_socket_tab[pos].remote_port = recvport;
	      
	      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL,
				      "New DTLS connection accepted\n"));

	    }

	  dec_buf = (char *) osip_malloc (SIP_MESSAGE_MAX_LENGTH * sizeof (char) + 1);
	  if (dec_buf==NULL)
	    {
		  OSIP_TRACE (osip_trace
			      (__FILE__, __LINE__, OSIP_ERROR, NULL,
			       "Allocation error\n"));
		  osip_free(enc_buf);
		  return -1;
	    }
	  rbio = BIO_new_mem_buf (enc_buf, enc_buf_len);
	  BIO_set_mem_eof_return (rbio, -1);
	  
	  dtls_socket_tab[pos].ssl_conn->rbio = rbio;
	  
	  i = SSL_read (dtls_socket_tab[pos].ssl_conn, dec_buf, SIP_MESSAGE_MAX_LENGTH);
	  /* done with the rbio */
	  BIO_free (dtls_socket_tab[pos].ssl_conn->rbio);
	  dtls_socket_tab[pos].ssl_conn->rbio = BIO_new (BIO_s_mem ());

	  if (i > 5)
	    {
	      osip_strncpy (dec_buf + i, "\0", 1);

	      _eXosip_handle_incoming_message(dec_buf, i, dtls_socket, src6host, recvport);
	      
	    }
#ifndef MINISIZE
	  else if (i <= 0)
	    {
	      err = SSL_get_error (dtls_socket_tab[pos].ssl_conn, i);
	      print_ssl_error (err);
	      if (err==SSL_ERROR_SYSCALL)
		{
		  OSIP_TRACE (osip_trace
			      (__FILE__, __LINE__, OSIP_WARNING,
			       NULL, "DTLS SYSCALL on SSL_read\n"));
		}
	      else if (err==SSL_ERROR_SSL
		       || err==SSL_ERROR_ZERO_RETURN)
		{
		  OSIP_TRACE (osip_trace
			      (__FILE__, __LINE__, OSIP_WARNING,
			       NULL, "DTLS closed\n"));
		  
		  shutdown_free_client_dtls (pos);
		  shutdown_free_server_dtls (pos);
		  
		  memset (&(dtls_socket_tab[pos]), 0, sizeof (dtls_socket_tab[pos]));
		}
	    }
	  else
	    {
	      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL,
				      "Dummy SIP message received\n"));
	    }
#endif
  
	  osip_free (dec_buf);
	  osip_free (enc_buf);

	}
    }

  return 0;
}
Esempio n. 12
0
static int
shutdown_free_client_dtls (int pos)
{
  int i, err;
  BIO *rbio;

  struct addrinfo *addrinfo;
  struct __eXosip_sockaddr addr;

  if (dtls_socket_tab[pos].ssl_type == 2)
    {
      if (dtls_socket_tab[pos].ssl_conn != NULL)
	{

	  i = eXosip_get_addrinfo (&addrinfo,
				   dtls_socket_tab[pos].remote_ip,
				   dtls_socket_tab[pos].remote_port,
				   IPPROTO_UDP);
	  if (i != 0)
	    {
	      return -1;
	    }

	  memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen);
	  eXosip_freeaddrinfo (addrinfo);

	  rbio = BIO_new_dgram (dtls_socket,
				BIO_NOCLOSE);

	  BIO_dgram_set_peer (rbio, &addr);

	  (dtls_socket_tab[pos].ssl_conn)->rbio = rbio;

	  i = SSL_shutdown (dtls_socket_tab[pos].ssl_conn);

	  if (i <= 0)
	    {
	      err = SSL_get_error (dtls_socket_tab[pos].ssl_conn, i);
#ifdef SSLDEBUG

	      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,
				      "DTLS client shutdown error %d <= 0\n",
				      i));
#endif

	      print_ssl_error (err);
	    }
	  else
	    {
#ifdef SSLDEBUG
	      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO3, NULL,
				      "DTLS client shutdown > 0\n"));
#endif

	    }

	  SSL_free (dtls_socket_tab[pos].ssl_conn);

#if 0
	  if (dtls_socket_tab[pos].ssl_ctx != NULL)
	    SSL_CTX_free (dtls_socket_tab[pos].ssl_ctx);
#endif

	  memset (&(dtls_socket_tab[pos]), 0,
		  sizeof (struct socket_tab));

	  return 0;
	}
      else
	{
	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,
				  "DTLS client shutdown: invalid SSL object!\n"));
	  return -1;
	}
    }
  return -1;
}