}
//============================================================
-//bool TcpClient::connect (HostSpec& host) {
bool TcpClient::connect (const HostSpec* host) {
char pbuf[10];
const char* bindaddr = NULL;
}
//============================================================
-//bool SslClient::connect (HostSpec& host) {
bool SslClient::connect (const HostSpec* _host) {
bool rc;
SSL_load_error_strings();
ssl_meth = SSLv23_client_method();
- ssl_ctx = SSL_CTX_new(ssl_meth);
- SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
+ ssl_ctx.reset (SSL_CTX_new(ssl_meth));
+ SSL_CTX_set_mode(ssl_ctx.get (), SSL_MODE_AUTO_RETRY);
loadCAFile (kCERTFILE);
- ssl = SSL_new(ssl_ctx);
- if (ssl == NULL){
+ ssl.reset (SSL_new(ssl_ctx.get ()));
+ if (ssl.get () == NULL){
throw (ustring (CharConst ("SSL context creation failed\n")));
close ();
return false;
}
- SSL_set_fd (ssl, sd);
- if (SSL_connect (ssl) == -1){
+ SSL_set_fd (ssl.get (), sd);
+ if (SSL_connect (ssl.get ()) == -1){
ERR_print_errors_fp (stderr);
close ();
return false;
}
void SslClient::loadCAFile (const char* certfile, int depth) {
- if (!SSL_CTX_load_verify_locations (ssl_ctx, certfile, NULL))
+ if (!SSL_CTX_load_verify_locations (ssl_ctx.get (), certfile, NULL))
return;
- SSL_CTX_set_verify_depth (ssl_ctx, depth);
+ SSL_CTX_set_verify_depth (ssl_ctx.get (), depth);
}
bool SslClient::verifyCA () {
- X509 *cert;
- char buf[SSL_NAME_LEN];
+ X509_autoptr cert;
+ char buf[SSL_NAME_LEN];
long rc;
- if ((rc = SSL_get_verify_result (ssl)) != X509_V_OK) {
+ if ((rc = SSL_get_verify_result (ssl.get ())) != X509_V_OK) {
switch (rc) {
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
throw (ustring (CharConst ("unable to get issuer cert locally.")));
}
return false;
}
- cert = SSL_get_peer_certificate (ssl);
- if (!cert)
+ cert.reset (SSL_get_peer_certificate (ssl.get ()));
+ if (!cert.get ())
return false;
- X509_NAME_get_text_by_NID (X509_get_subject_name (cert), NID_commonName, buf, sizeof (buf));
+ X509_NAME_get_text_by_NID (X509_get_subject_name (cert.get ()), NID_commonName, buf, sizeof (buf));
if (host && host->host.length () > 0) {
// std::cerr << "hostname: " << buf << "\n";
}
ssize_t SslClient::write2 (struct iovec* iov, int iovcnt) {
- return SSL_write(ssl, iov->iov_base, iov->iov_len);
+ return SSL_write(ssl.get (), iov->iov_base, iov->iov_len);
}
ssize_t SslClient::read2 (void* buf, size_t nbytes) {
- return SSL_read (ssl, buf, nbytes);
+ return SSL_read (ssl.get (), buf, nbytes);
}
TcpBuf () {
buf.assign (65536, '\0');
-// buf.assign (256, 0);
+// buf.assign (256, 0); // debug
start = tail = buf.begin ();
};
virtual ~TcpBuf () {};
virtual ssize_t read2 (void* buf, size_t nbytes);
};
+class SSL_autoptr {
+ public:
+ SSL* ptr;
+ SSL_autoptr (SSL* p = NULL) {
+ ptr = p;
+ };
+ ~SSL_autoptr () {
+ if (ptr) {
+ SSL_free (ptr);
+ ptr = NULL;
+ }
+ };
+ void reset (SSL* p = NULL) {
+ assert (p == 0 || p != ptr);
+ if (ptr)
+ SSL_free (ptr);
+ ptr = p;
+ };
+ SSL& operator * () const {
+ assert (ptr != NULL);
+ return *ptr;
+ };
+ SSL* operator -> () const {
+ assert (ptr != NULL);
+ return ptr;
+ };
+ SSL* get () const {
+ return ptr;
+ };
+};
+
+class SSL_CTX_autoptr {
+ public:
+ SSL_CTX* ptr;
+ SSL_CTX_autoptr (SSL_CTX* p = NULL) {
+ ptr = p;
+ };
+ ~SSL_CTX_autoptr () {
+ if (ptr) {
+ SSL_CTX_free (ptr);
+ ptr = NULL;
+ }
+ };
+ void reset (SSL_CTX* p = NULL) {
+ assert (p == 0 || p != ptr);
+ if (ptr)
+ SSL_CTX_free (ptr);
+ ptr = p;
+ };
+ SSL_CTX& operator * () const {
+ assert (ptr != NULL);
+ return *ptr;
+ };
+ SSL_CTX* operator -> () const {
+ assert (ptr != NULL);
+ return ptr;
+ };
+ SSL_CTX* get () const {
+ return ptr;
+ };
+};
+
+class X509_autoptr {
+ public:
+ X509* ptr;
+ X509_autoptr (X509* p = NULL) {
+ ptr = p;
+ };
+ ~X509_autoptr () {
+ if (ptr) {
+ X509_free (ptr);
+ ptr = NULL;
+ }
+ };
+ void reset (X509* p = NULL) {
+ assert (p == 0 || p != ptr);
+ if (ptr)
+ X509_free (ptr);
+ ptr = p;
+ };
+ X509& operator * () const {
+ assert (ptr != NULL);
+ return *ptr;
+ };
+ X509* operator -> () const {
+ assert (ptr != NULL);
+ return ptr;
+ };
+ X509* get () const {
+ return ptr;
+ };
+};
+
class SslClient: public TcpClient {
public:
const HostSpec* host;
- SSL* ssl;
- SSL_CTX* ssl_ctx;
- X509* ssl_cert;
+ SSL_autoptr ssl;
+ SSL_CTX_autoptr ssl_ctx;
SSL_METHOD* ssl_meth;
bool fnoverify;
- SslClient () {
- host = NULL;
- ssl = NULL;
- ssl_ctx = NULL;
- ssl_cert = NULL;
- ssl_meth = NULL;
- fnoverify = false;
- };
- SslClient (bool _fnoverify) {
+ SslClient (bool _fnoverify = false) {
host = NULL;
- ssl = NULL;
- ssl_ctx = NULL;
- ssl_cert = NULL;
ssl_meth = NULL;
fnoverify = _fnoverify;
};