示例#1
0
static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
                  ssl_handshake_func_t func,
                  unsigned long *ssl_errno_holder)
{
  int r;
  SSL *ssl;
  my_socket sd= mysql_socket_getfd(vio->mysql_socket);
  DBUG_ENTER("ssl_do");
  DBUG_PRINT("enter", ("ptr: 0x%lx, sd: %d  ctx: 0x%lx",
                       (long) ptr, sd, (long) ptr->ssl_context));

  if (!(ssl= SSL_new(ptr->ssl_context)))
  {
    DBUG_PRINT("error", ("SSL_new failure"));
    *ssl_errno_holder= ERR_get_error();
    DBUG_RETURN(1);
  }
  DBUG_PRINT("info", ("ssl: 0x%lx timeout: %ld", (long) ssl, timeout));
  SSL_clear(ssl);
  SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
  SSL_set_fd(ssl, sd);
#ifndef HAVE_YASSL
  SSL_set_options(ssl, SSL_OP_NO_COMPRESSION);
#endif

  /*
    Since yaSSL does not support non-blocking send operations, use
    special transport functions that properly handles non-blocking
    sockets. These functions emulate the behavior of blocking I/O
    operations by waiting for I/O to become available.
  */
#ifdef HAVE_YASSL
  /* Set first argument of the transport functions. */
  yaSSL_transport_set_ptr(ssl, vio);
  /* Set functions to use in order to send and receive data. */
  yaSSL_transport_set_recv_function(ssl, yassl_recv);
  yaSSL_transport_set_send_function(ssl, yassl_send);
#endif

  if ((r= ssl_handshake_loop(vio, ssl, func, ssl_errno_holder)) < 1)
  {
    DBUG_PRINT("error", ("SSL_connect/accept failure"));
    SSL_free(ssl);
    DBUG_RETURN(1);
  }

  /*
    Connection succeeded. Install new function handlers,
    change type, set sd to the fd used when connecting
    and set pointer to the SSL structure
  */
  if (vio_reset(vio, VIO_TYPE_SSL, SSL_get_fd(ssl), ssl, 0))
    DBUG_RETURN(1);

#ifndef DBUG_OFF
  {
    /* Print some info about the peer */
    X509 *cert;
    char buf[512];

    DBUG_PRINT("info",("SSL connection succeeded"));
    DBUG_PRINT("info",("Using cipher: '%s'" , SSL_get_cipher_name(ssl)));

    if ((cert= SSL_get_peer_certificate (ssl)))
    {
      DBUG_PRINT("info",("Peer certificate:"));
      X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
      DBUG_PRINT("info",("\t subject: '%s'", buf));
      X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf));
      DBUG_PRINT("info",("\t issuer: '%s'", buf));
      X509_free(cert);
    }
    else
      DBUG_PRINT("info",("Peer does not have certificate."));

    if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf)))
    {
      DBUG_PRINT("info",("shared_ciphers: '%s'", buf));
    }
    else
      DBUG_PRINT("info",("no shared ciphers!"));
  }
#endif

  DBUG_RETURN(0);
}
示例#2
0
static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
                  ssl_handshake_func_t func,
                  unsigned long *ssl_errno_holder)
{
  int r;
  SSL *ssl;
  my_socket sd= mysql_socket_getfd(vio->mysql_socket);

  /* Declared here to make compiler happy */
#if !defined(HAVE_YASSL) && !defined(DBUG_OFF)
  int j, n;
#endif

  DBUG_ENTER("ssl_do");
  DBUG_PRINT("enter", ("ptr: 0x%lx, sd: %d  ctx: 0x%lx",
                       (long) ptr, sd, (long) ptr->ssl_context));

  if (!(ssl= SSL_new(ptr->ssl_context)))
  {
    DBUG_PRINT("error", ("SSL_new failure"));
    *ssl_errno_holder= ERR_get_error();
    DBUG_RETURN(1);
  }
  DBUG_PRINT("info", ("ssl: 0x%lx timeout: %ld", (long) ssl, timeout));
  SSL_clear(ssl);
  SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
  SSL_set_fd(ssl, sd);
#if !defined(HAVE_YASSL) && defined(SSL_OP_NO_COMPRESSION)
  SSL_set_options(ssl, SSL_OP_NO_COMPRESSION); /* OpenSSL >= 1.0 only */
#elif OPENSSL_VERSION_NUMBER >= 0x00908000L /* workaround for OpenSSL 0.9.8 */
  sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
#endif

#if !defined(HAVE_YASSL) && !defined(DBUG_OFF)
  {
    STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
    ssl_comp_methods = SSL_COMP_get_compression_methods();
    n= sk_SSL_COMP_num(ssl_comp_methods);
    DBUG_PRINT("info", ("Available compression methods:\n"));
    if (n == 0)
      DBUG_PRINT("info", ("NONE\n"));
    else
      for (j = 0; j < n; j++)
      {
        SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
        DBUG_PRINT("info", ("  %d: %s\n", c->id, c->name));
      }
  }
#endif

  /*
    Since yaSSL does not support non-blocking send operations, use
    special transport functions that properly handles non-blocking
    sockets. These functions emulate the behavior of blocking I/O
    operations by waiting for I/O to become available.
  */
#ifdef HAVE_YASSL
  /* Set first argument of the transport functions. */
  yaSSL_transport_set_ptr(ssl, vio);
  /* Set functions to use in order to send and receive data. */
  yaSSL_transport_set_recv_function(ssl, yassl_recv);
  yaSSL_transport_set_send_function(ssl, yassl_send);
#endif

  if ((r= ssl_handshake_loop(vio, ssl, func, ssl_errno_holder)) < 1)
  {
    DBUG_PRINT("error", ("SSL_connect/accept failure"));
    SSL_free(ssl);
    DBUG_RETURN(1);
  }

  /*
    Connection succeeded. Install new function handlers,
    change type, set sd to the fd used when connecting
    and set pointer to the SSL structure
  */
  if (vio_reset(vio, VIO_TYPE_SSL, SSL_get_fd(ssl), ssl, 0))
    DBUG_RETURN(1);

#ifndef DBUG_OFF
  {
    /* Print some info about the peer */
    X509 *cert;
    char buf[512];

    DBUG_PRINT("info",("SSL connection succeeded"));
    DBUG_PRINT("info",("Using cipher: '%s'" , SSL_get_cipher_name(ssl)));

    if ((cert= SSL_get_peer_certificate (ssl)))
    {
      DBUG_PRINT("info",("Peer certificate:"));
      X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
      DBUG_PRINT("info",("\t subject: '%s'", buf));
      X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf));
      DBUG_PRINT("info",("\t issuer: '%s'", buf));
      X509_free(cert);
    }
    else
      DBUG_PRINT("info",("Peer does not have certificate."));

    if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf)))
    {
      DBUG_PRINT("info",("shared_ciphers: '%s'", buf));
    }
    else
      DBUG_PRINT("info",("no shared ciphers!"));
  }
#endif

  DBUG_RETURN(0);
}