bool network_client::connect(const char* ip, int port) {
    if (connected_) {
        last_error_ = boost::system::errc::make_error_code(boost::system::errc::already_connected);
        return false;
    }
    
    if (io_service_ == nullptr) {
        io_service_ = io_service_pt(new asio_io_service_t());
    }
    
    if (strand_ == nullptr) {
        strand_ = strand_pt(new asio_strand_t(*io_service_));
    }
    
    
    boost::container::vector<unsigned char> cert_buff, key_buff;
    if (!make_certificate(cert_buff, key_buff)) {
        // @todo: make custom errors
        last_error_ = boost::system::errc::make_error_code(boost::system::errc::not_supported);
        return false;
    }
    
    asio_ssl_context_t ssl_context(*io_service_, asio_ssl_context_t::tlsv1);
    ssl_context.set_verify_mode(asio_ssl_context_t::verify_none);
    
    ssl_context.use_certificate(boost::asio::const_buffer(cert_buff.data(), cert_buff.size()), asio_ssl_context_t::asn1);
    ssl_context.use_private_key(boost::asio::const_buffer(key_buff.data(), key_buff.size()), asio_ssl_context_t::asn1);
    
    ssl_socket_ = ssl_socket_pt(new asio_ssl_socket_t(*io_service_, ssl_context));
    
    
    auto endpoint = boost::asio::ip::tcp::endpoint(
                                                   boost::asio::ip::address::from_string(ip), port);
    
    ssl_socket_->next_layer().async_connect(endpoint, strand_->wrap(boost::bind(&network_client::handle_connect, this, boost::asio::placeholders::error)));
    
    t_ = boost::thread(boost::bind(static_cast<size_t (boost::asio::io_service::*)()>(&boost::asio::io_service::run), io_service_));
   
    return true;
}
Example #2
0
int					/* O - 1 on success, 0 on error */
cupsdStartTLS(cupsd_client_t *con)	/* I - Client connection */
{
  OSStatus	error = 0;		/* Error code */
  SecTrustRef	peerTrust;		/* Peer certificates */


  cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Encrypting connection.",
                  con->number);

  con->http->encryption = HTTP_ENCRYPTION_ALWAYS;

  con->http->tls_credentials = copy_cdsa_certificate(con);

  if (!con->http->tls_credentials)
  {
   /*
    * No keychain (yet), make a self-signed certificate...
    */

    if (make_certificate(con))
      con->http->tls_credentials = copy_cdsa_certificate(con);
  }

  if (!con->http->tls_credentials)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
        	    "Could not find signing key in keychain \"%s\"",
		    ServerCertificate);
    error = errSSLBadConfiguration;
  }

  if (!error)
    con->http->tls = SSLCreateContext(kCFAllocatorDefault, kSSLServerSide,
                                     kSSLStreamType);

  if (!error)
    error = SSLSetIOFuncs(con->http->tls, _httpReadCDSA, _httpWriteCDSA);

  if (!error)
    error = SSLSetConnection(con->http->tls, HTTP(con));

  if (!error)
    error = SSLSetCertificate(con->http->tls, con->http->tls_credentials);

  if (!error)
  {
   /*
    * Perform SSL/TLS handshake
    */

    while ((error = SSLHandshake(con->http->tls)) == errSSLWouldBlock)
      usleep(1000);
  }

  if (error)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "Unable to encrypt connection from %s - %s (%d)",
                    con->http->hostname, cssmErrorString(error), (int)error);

    con->http->error  = error;
    con->http->status = HTTP_ERROR;

    if (con->http->tls)
    {
      CFRelease(con->http->tls);
      con->http->tls = NULL;
    }

    if (con->http->tls_credentials)
    {
      CFRelease(con->http->tls_credentials);
      con->http->tls_credentials = NULL;
    }

    return (0);
  }

  cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.",
                  con->http->hostname);

  if (!SSLCopyPeerTrust(con->http->tls, &peerTrust) && peerTrust)
  {
    cupsdLogMessage(CUPSD_LOG_DEBUG, "Received %d peer certificates.",
		    (int)SecTrustGetCertificateCount(peerTrust));
    CFRelease(peerTrust);
  }
  else
    cupsdLogMessage(CUPSD_LOG_DEBUG, "Received NO peer certificates.");

  return (1);
}
int					/* O - 1 on success, 0 on error */
cupsdStartTLS(cupsd_client_t *con)	/* I - Client connection */
{
  int		status;			/* Error code */
  gnutls_certificate_server_credentials *credentials;
					/* TLS credentials */


  cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Encrypting connection.",
                  con->http.fd);

 /*
  * Verify that we have a certificate...
  */

  if (access(ServerKey, 0) || access(ServerCertificate, 0))
  {
   /*
    * Nope, make a self-signed certificate...
    */

    if (!make_certificate(con))
      return (0);
  }

 /*
  * Create the SSL object and perform the SSL handshake...
  */

  credentials = (gnutls_certificate_server_credentials *)
                    malloc(sizeof(gnutls_certificate_server_credentials));
  if (credentials == NULL)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "Unable to encrypt connection from %s - %s",
                    con->http.hostname, strerror(errno));

    return (0);
  }

  gnutls_certificate_allocate_credentials(credentials);
  gnutls_certificate_set_x509_key_file(*credentials, ServerCertificate,
				       ServerKey, GNUTLS_X509_FMT_PEM);

  gnutls_init(&con->http.tls, GNUTLS_SERVER);
  gnutls_set_default_priority(con->http.tls);

  gnutls_credentials_set(con->http.tls, GNUTLS_CRD_CERTIFICATE, *credentials);
  gnutls_transport_set_ptr(con->http.tls, (gnutls_transport_ptr)HTTP(con));
  gnutls_transport_set_pull_function(con->http.tls, _httpReadGNUTLS);
  gnutls_transport_set_push_function(con->http.tls, _httpWriteGNUTLS);

  while ((status = gnutls_handshake(con->http.tls)) != GNUTLS_E_SUCCESS)
  {
    if (gnutls_error_is_fatal(status))
    {
      cupsdLogMessage(CUPSD_LOG_ERROR,
                      "Unable to encrypt connection from %s - %s",
                      con->http.hostname, gnutls_strerror(status));

      gnutls_deinit(con->http.tls);
      gnutls_certificate_free_credentials(*credentials);
      con->http.tls = NULL;
      free(credentials);
      return (0);
    }
  }

  cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.",
                  con->http.hostname);

  con->http.tls_credentials = credentials;
  return (1);
}