Ejemplo n.º 1
0
void TLSSocket::Handshake(TCPSocket& socket, HandshakeRole role, TLSSocket* reuse)
{

  SSL_CTX* ctx = role == Client ? TLSClientContext::Get() : TLSServerContext::Get();
                 
  if (!ctx) throw TLSError("TLS context not initialised.");

  session = SSL_new(ctx);
  if (!session) throw TLSProtocolError();
  
  if (SSL_set_fd(session, socket.Socket()) != 1) throw TLSProtocolError();
  
  if (reuse)
  {
    assert(reuse->session);
    SSL_copy_session_id(session, reuse->session);
  }

  if (role == Client) SSL_set_connect_state(session);
  else SSL_set_accept_state(session);

  int result;
  while (true)
  {
    if (role == Client) result = SSL_connect(session);
    else result = SSL_accept(session);
    boost::this_thread::interruption_point();
    if (result == 1) break;
    else EvaluateResult(result);
  }
}
Ejemplo n.º 2
0
bool SSLSocket::setupCrypto(SSLSocket *session /* = NULL */) {
  if (m_handle) {
    raise_warning("SSL/TLS already set-up for this stream");
    return false;
  }

  /* need to do slightly different things, based on client/server method,
   * so lets remember which method was selected */
#if OPENSSL_VERSION_NUMBER < 0x00909000L
  SSL_METHOD *smethod;
#else
  const SSL_METHOD *smethod;
#endif
  switch (m_method) {
  case ClientSSLv23: m_client = true;  smethod = SSLv23_client_method(); break;
  case ClientSSLv3:  m_client = true;  smethod = SSLv3_client_method();  break;
  case ClientTLS:    m_client = true;  smethod = TLSv1_client_method();  break;
  case ServerSSLv23: m_client = false; smethod = SSLv23_server_method(); break;
  case ServerSSLv3:  m_client = false; smethod = SSLv3_server_method();  break;

  /* SSLv2 protocol might be disabled in the OpenSSL library */
#ifndef OPENSSL_NO_SSL2
  case ClientSSLv2:  m_client = true;  smethod = SSLv2_client_method();  break;
  case ServerSSLv2:  m_client = false; smethod = SSLv2_server_method();  break;
#else
  case ClientSSLv2:
  case ServerSSLv2:
    raise_warning("OpenSSL library does not support SSL2 protocol");
    return false;
  break;
#endif

  case ServerTLS:    m_client = false; smethod = TLSv1_server_method();  break;
  default:
    return false;
  }

  SSL_CTX *ctx = SSL_CTX_new(smethod);
  if (ctx == nullptr) {
    raise_warning("failed to create an SSL context");
    return false;
  }

  SSL_CTX_set_options(ctx, SSL_OP_ALL);
  m_handle = createSSL(ctx);
  if (m_handle == nullptr) {
    raise_warning("failed to create an SSL handle");
    SSL_CTX_free(ctx);
    return false;
  }

  if (!SSL_set_fd(m_handle, m_fd)) {
    handleError(0, true);
  }
  if (session) {
    SSL_copy_session_id(m_handle, session->m_handle);
  }
  return true;
}
Ejemplo n.º 3
0
int BIO_ssl_copy_session_id(BIO *t, BIO *f)
	{
	t=BIO_find_type(t,BIO_TYPE_SSL);
	f=BIO_find_type(f,BIO_TYPE_SSL);
	if ((t == NULL) || (f == NULL))
		return(0);
	if (	(((BIO_SSL *)t->ptr)->ssl == NULL) ||
		(((BIO_SSL *)f->ptr)->ssl == NULL))
		return(0);
	SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl,((BIO_SSL *)f->ptr)->ssl);
	return(1);
	}
Ejemplo n.º 4
0
int BIO_ssl_copy_session_id(BIO *t, BIO *f)
{
    BIO_SSL *tdata, *fdata;
    t = BIO_find_type(t, BIO_TYPE_SSL);
    f = BIO_find_type(f, BIO_TYPE_SSL);
    if ((t == NULL) || (f == NULL))
        return 0;
    tdata = BIO_get_data(t);
    fdata = BIO_get_data(f);
    if ((tdata->ssl == NULL) || (fdata->ssl == NULL))
        return 0;
    if (!SSL_copy_session_id(tdata->ssl, (fdata->ssl)))
        return 0;
    return 1;
}
Ejemplo n.º 5
0
static void
create_conn (Sess *sess, struct Conn_Info *ci)
{
  Conn_Private_Data *cpriv;

  /* No connection yet (or anymore).  Create a new connection.  Note
     that CI->CONN is NOT reference-counted.  This is again to avoid
     introducing recursive dependencies (see also comment regarding
     member CONN in call.h). */
  ci->conn = conn_new ();
  if (!ci->conn)
    {
      sess_failure (sess);
      return;
    }
  cpriv = CONN_PRIVATE_DATA (ci->conn);
  cpriv->sess = sess;
  cpriv->ci = ci;

  ci->is_connected = 0;
  ci->is_successful = 0;
  ci->num_sent = 0;		/* (re-)send all pending calls */

#ifdef HAVE_SSL
  if (param.ssl_reuse && ci->conn->ssl && sess->ssl)
    {
      if (DBG > 0)
	fprintf (stderr, "create_conn: reusing SSL session %p\n",
		 (void *) sess->ssl);
      SSL_copy_session_id (ci->conn->ssl, sess->ssl);
    }
#endif

  if (core_connect (ci->conn) < 0)
    sess_failure (sess);
}
Ejemplo n.º 6
0
/* {{{ data_accept
 */
databuf_t*
data_accept(databuf_t *data, ftpbuf_t *ftp)
{
	php_sockaddr_storage addr;
	socklen_t			size;

#if HAVE_OPENSSL_EXT
	SSL_CTX		*ctx;
	zend_long ssl_ctx_options = SSL_OP_ALL;
#endif

	if (data->fd != -1) {
		goto data_accepted;
	}
	size = sizeof(addr);
	data->fd = my_accept(ftp, data->listener, (struct sockaddr*) &addr, &size);
	closesocket(data->listener);
	data->listener = -1;

	if (data->fd == -1) {
		efree(data);
		return NULL;
	}

data_accepted:
#if HAVE_OPENSSL_EXT
	
	/* now enable ssl if we need to */
	if (ftp->use_ssl && ftp->use_ssl_for_data) {
		ctx = SSL_CTX_new(SSLv23_client_method());
		if (ctx == NULL) {
			php_error_docref(NULL, E_WARNING, "data_accept: failed to create the SSL context");
			return 0;
		}

#if OPENSSL_VERSION_NUMBER >= 0x0090605fL
		ssl_ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
#endif
		SSL_CTX_set_options(ctx, ssl_ctx_options);

		data->ssl_handle = SSL_new(ctx);
		if (data->ssl_handle == NULL) {
			php_error_docref(NULL, E_WARNING, "data_accept: failed to create the SSL handle");
			SSL_CTX_free(ctx);
			return 0;
		}
			
		
		SSL_set_fd(data->ssl_handle, data->fd);

		if (ftp->old_ssl) {
			SSL_copy_session_id(data->ssl_handle, ftp->ssl_handle);
		}
			
		if (SSL_connect(data->ssl_handle) <= 0) {
			php_error_docref(NULL, E_WARNING, "data_accept: SSL/TLS handshake failed");
			SSL_shutdown(data->ssl_handle);
			SSL_free(data->ssl_handle);
			return 0;
		}
			
		data->ssl_active = 1;
	}	

#endif

	return data;
}
Ejemplo n.º 7
0
/* {{{ data_accept
 */
databuf_t*
data_accept(databuf_t *data, ftpbuf_t *ftp)
{
	php_sockaddr_storage addr;
	socklen_t			size;

#ifdef HAVE_FTP_SSL
	SSL_CTX		*ctx;
	SSL_SESSION *session;
	int err, res;
	zend_bool retry;
#endif

	if (data->fd != -1) {
		goto data_accepted;
	}
	size = sizeof(addr);
	data->fd = my_accept(ftp, data->listener, (struct sockaddr*) &addr, &size);
	closesocket(data->listener);
	data->listener = -1;

	if (data->fd == -1) {
		efree(data);
		return NULL;
	}

data_accepted:
#ifdef HAVE_FTP_SSL

	/* now enable ssl if we need to */
	if (ftp->use_ssl && ftp->use_ssl_for_data) {
		ctx = SSL_get_SSL_CTX(ftp->ssl_handle);
		if (ctx == NULL) {
			php_error_docref(NULL, E_WARNING, "data_accept: failed to retreive the existing SSL context");
			return 0;
		}

		data->ssl_handle = SSL_new(ctx);
		if (data->ssl_handle == NULL) {
			php_error_docref(NULL, E_WARNING, "data_accept: failed to create the SSL handle");
			return 0;
		}

		SSL_set_fd(data->ssl_handle, data->fd);

		if (ftp->old_ssl) {
			SSL_copy_session_id(data->ssl_handle, ftp->ssl_handle);
		}

		/* get the session from the control connection so we can re-use it */
		session = SSL_get_session(ftp->ssl_handle);
		if (session == NULL) {
			php_error_docref(NULL, E_WARNING, "data_accept: failed to retreive the existing SSL session");
			SSL_free(data->ssl_handle);
			return 0;
		}

		/* and set it on the data connection */
		res = SSL_set_session(data->ssl_handle, session);
		if (res == 0) {
			php_error_docref(NULL, E_WARNING, "data_accept: failed to set the existing SSL session");
			SSL_free(data->ssl_handle);
			return 0;
		}

		do {
			res = SSL_connect(data->ssl_handle);
			err = SSL_get_error(data->ssl_handle, res);

			switch (err) {
				case SSL_ERROR_NONE:
					retry = 0;
					break;

				case SSL_ERROR_ZERO_RETURN:
					retry = 0;
					SSL_shutdown(data->ssl_handle);
					break;

				case SSL_ERROR_WANT_READ:
				case SSL_ERROR_WANT_WRITE: {
						php_pollfd p;
						int i;

						p.fd = ftp->fd;
						p.events = (err == SSL_ERROR_WANT_READ) ? (POLLIN|POLLPRI) : POLLOUT;
						p.revents = 0;

						i = php_poll2(&p, 1, 300);

						retry = i > 0;
					}
					break;

				default:
					php_error_docref(NULL, E_WARNING, "data_accept: SSL/TLS handshake failed");
					SSL_shutdown(data->ssl_handle);
					SSL_free(data->ssl_handle);
					return 0;
			}
		} while (retry);

		data->ssl_active = 1;
	}

#endif

	return data;
}
Ejemplo n.º 8
0
Archivo: ftp.c Proyecto: 20uf/php-src
/* {{{ data_accept
 */
databuf_t*
data_accept(databuf_t *data, ftpbuf_t *ftp)
{
	php_sockaddr_storage addr;
	socklen_t			size;

#ifdef HAVE_FTP_SSL
	SSL_CTX		*ctx;
	zend_long ssl_ctx_options = SSL_OP_ALL;
	int err, res;
	zend_bool retry;
#endif

	if (data->fd != -1) {
		goto data_accepted;
	}
	size = sizeof(addr);
	data->fd = my_accept(ftp, data->listener, (struct sockaddr*) &addr, &size);
	closesocket(data->listener);
	data->listener = -1;

	if (data->fd == -1) {
		efree(data);
		return NULL;
	}

data_accepted:
#ifdef HAVE_FTP_SSL

	/* now enable ssl if we need to */
	if (ftp->use_ssl && ftp->use_ssl_for_data) {
		ctx = SSL_CTX_new(SSLv23_client_method());
		if (ctx == NULL) {
			php_error_docref(NULL, E_WARNING, "data_accept: failed to create the SSL context");
			return 0;
		}

#if OPENSSL_VERSION_NUMBER >= 0x0090605fL
		ssl_ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
#endif
		SSL_CTX_set_options(ctx, ssl_ctx_options);

		data->ssl_handle = SSL_new(ctx);
		if (data->ssl_handle == NULL) {
			php_error_docref(NULL, E_WARNING, "data_accept: failed to create the SSL handle");
			SSL_CTX_free(ctx);
			return 0;
		}


		SSL_set_fd(data->ssl_handle, data->fd);

		if (ftp->old_ssl) {
			SSL_copy_session_id(data->ssl_handle, ftp->ssl_handle);
		}

		do {
			res = SSL_connect(data->ssl_handle);
			err = SSL_get_error(data->ssl_handle, res);

			switch (err) {
				case SSL_ERROR_NONE:
					retry = 0;
					break;

				case SSL_ERROR_ZERO_RETURN:
					retry = 0;
					SSL_shutdown(data->ssl_handle);
					break;

				case SSL_ERROR_WANT_READ:
				case SSL_ERROR_WANT_WRITE: {
						php_pollfd p;
						int i;

						p.fd = ftp->fd;
						p.events = (err == SSL_ERROR_WANT_READ) ? (POLLIN|POLLPRI) : POLLOUT;
						p.revents = 0;

						i = php_poll2(&p, 1, 300);

						retry = i > 0;
					}
					break;

				default:
					php_error_docref(NULL, E_WARNING, "data_accept: SSL/TLS handshake failed");
					SSL_shutdown(data->ssl_handle);
					SSL_free(data->ssl_handle);
					return 0;
			}
		} while (retry);

		data->ssl_active = 1;
	}

#endif

	return data;
}