⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 openssladapter.cc

📁 本人收集整理的一份c/c++跨平台网络库
💻 CC
📖 第 1 页 / 共 2 页
字号:
#ifdef _HAVE_OPENSSL#include <openssl/bio.h>#include <openssl/ssl.h>#include <openssl/err.h>#include <openssl/x509v3.h>#include "common.h"#include "logging.h"#include "openssladapter.h"#include "stringutils.h"#include "Equifax_Secure_Global_eBusiness_CA-1.h"//////////////////////////////////////////////////////////////////////// StreamBIO//////////////////////////////////////////////////////////////////////#if 0static int stream_write(BIO* h, const char* buf, int num);static int stream_read(BIO* h, char* buf, int size);static int stream_puts(BIO* h, const char* str);static long stream_ctrl(BIO* h, int cmd, long arg1, void* arg2);static int stream_new(BIO* h);static int stream_free(BIO* data);static BIO_METHOD methods_stream = {	BIO_TYPE_BIO,	"stream",	stream_write,	stream_read,	stream_puts,	0,	stream_ctrl,	stream_new,	stream_free,	NULL,};BIO_METHOD* BIO_s_stream() { return(&methods_stream); }BIO* BIO_new_stream(StreamInterface* stream) {	BIO* ret = BIO_new(BIO_s_stream());	if (ret == NULL)    return NULL;	ret->ptr = stream;	return ret;}static int stream_new(BIO* b) {	b->shutdown = 0;	b->init = 1;	b->num = 0; // 1 means end-of-stream	b->ptr = 0;	return 1;}static int stream_free(BIO* b) {	if (b == NULL)		return 0;	return 1;}static int stream_read(BIO* b, char* out, int outl) {	if (!out)		return -1;	StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);	BIO_clear_retry_flags(b);	size_t read;  int error;  StreamResult result = stream->Read(out, outl, &read, &error);  if (result == SR_SUCCESS) {    return read;  } else if (result == SR_EOS) {		b->num = 1;	} else if (result == SR_BLOCK) {		BIO_set_retry_read(b);	}	return -1;}static int stream_write(BIO* b, const char* in, int inl) {	if (!in)		return -1;	StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);	BIO_clear_retry_flags(b);	size_t written;  int error;  StreamResult result = stream->Write(in, inl, &written, &error);  if (result == SR_SUCCESS) {    return written;  } else if (result == SR_BLOCK) {		BIO_set_retry_write(b);	}	return -1;}static int stream_puts(BIO* b, const char* str) {	return stream_write(b, str, strlen(str));}static long stream_ctrl(BIO* b, int cmd, long num, void* ptr) {  UNUSED(num);  UNUSED(ptr);	switch (cmd) {	case BIO_CTRL_RESET:		return 0;	case BIO_CTRL_EOF:		return b->num;	case BIO_CTRL_WPENDING:	case BIO_CTRL_PENDING:		return 0;	case BIO_CTRL_FLUSH:		return 1;	default:		return 0;	}}#endif//////////////////////////////////////////////////////////////////////// SocketBIO//////////////////////////////////////////////////////////////////////static int socket_write(BIO* h, const char* buf, int num);static int socket_read(BIO* h, char* buf, int size);static int socket_puts(BIO* h, const char* str);static long socket_ctrl(BIO* h, int cmd, long arg1, void* arg2);static int socket_new(BIO* h);static int socket_free(BIO* data);static BIO_METHOD methods_socket = {	BIO_TYPE_BIO,	"socket",	socket_write,	socket_read,	socket_puts,	0,	socket_ctrl,	socket_new,	socket_free,	NULL,};BIO_METHOD* BIO_s_socket2() { return(&methods_socket); }BIO* BIO_new_socket(talk_base::AsyncSocket* socket) {	BIO* ret = BIO_new(BIO_s_socket2());	if (ret == NULL) {          return NULL;	}	ret->ptr = socket;	return ret;}static int socket_new(BIO* b) {	b->shutdown = 0;	b->init = 1;	b->num = 0; // 1 means socket closed	b->ptr = 0;	return 1;}static int socket_free(BIO* b) {	if (b == NULL)		return 0;	return 1;}static int socket_read(BIO* b, char* out, int outl) {	if (!out)		return -1;	talk_base::AsyncSocket* socket = static_cast<talk_base::AsyncSocket*>(b->ptr);	BIO_clear_retry_flags(b);  int result = socket->Recv(out, outl);  if (result > 0) {    return result;  } else if (result == 0) {		b->num = 1;  } else if (socket->IsBlocking()) {		BIO_set_retry_read(b);	}	return -1;}static int socket_write(BIO* b, const char* in, int inl) {	if (!in)		return -1;	talk_base::AsyncSocket* socket = static_cast<talk_base::AsyncSocket*>(b->ptr);	BIO_clear_retry_flags(b);  int result = socket->Send(in, inl);  if (result > 0) {    return result;  } else if (socket->IsBlocking()) {		BIO_set_retry_write(b);	}	return -1;}static int socket_puts(BIO* b, const char* str) {	return socket_write(b, str, strlen(str));}static long socket_ctrl(BIO* b, int cmd, long num, void* ptr) {  UNUSED(num);  UNUSED(ptr);	switch (cmd) {	case BIO_CTRL_RESET:		return 0;	case BIO_CTRL_EOF:		return b->num;	case BIO_CTRL_WPENDING:	case BIO_CTRL_PENDING:		return 0;	case BIO_CTRL_FLUSH:		return 1;	default:		return 0;	}}/////////////////////////////////////////////////////////////////////////////// OpenSSLAdapter/////////////////////////////////////////////////////////////////////////////namespace talk_base {OpenSSLAdapter::OpenSSLAdapter(AsyncSocket* socket)  : SSLAdapter(socket),    state_(SSL_NONE),    ssl_read_needs_write_(false),    ssl_write_needs_read_(false),    restartable_(false),    ssl_(NULL), ssl_ctx_(NULL) {}OpenSSLAdapter::~OpenSSLAdapter() {  Cleanup();}intOpenSSLAdapter::StartSSL(const char* hostname, bool restartable) {  if (state_ != SSL_NONE)    return -1;   ssl_host_name_ = hostname;  restartable_ = restartable;  if (socket_->GetState() != Socket::CS_CONNECTED) {    state_ = SSL_WAIT;    return 0;  }  state_ = SSL_CONNECTING;  if (int err = BeginSSL()) {    Error("BeginSSL", err, false);    return err;  }  return 0;}intOpenSSLAdapter::BeginSSL() {  LOG(LS_INFO) << "BeginSSL: " << ssl_host_name_;  ASSERT(state_ == SSL_CONNECTING);  int err = 0;  BIO* bio = NULL;  // First set up the context  if (!ssl_ctx_)    ssl_ctx_ = SetupSSLContext();  if (!ssl_ctx_) {    err = -1;    goto ssl_error;  }  bio = BIO_new_socket(static_cast<talk_base::AsyncSocketAdapter*>(socket_));  if (!bio) {    err = -1;    goto ssl_error;  }  ssl_ = SSL_new(ssl_ctx_);  if (!ssl_) {    err = -1;    goto ssl_error;  }  SSL_set_app_data(ssl_, this);  SSL_set_bio(ssl_, bio, bio);  SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |                     SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);  // the SSL object owns the bio now  bio = NULL;  // Do the connect  err = ContinueSSL();  if (err != 0)    goto ssl_error;  return err;ssl_error:  Cleanup();  if (bio)    BIO_free(bio);  return err;}intOpenSSLAdapter::ContinueSSL() {  LOG(LS_INFO) << "ContinueSSL";  ASSERT(state_ == SSL_CONNECTING);  int code = SSL_connect(ssl_);  switch (SSL_get_error(ssl_, code)) {  case SSL_ERROR_NONE:    LOG(LS_INFO) << " -- success";    if (!SSLPostConnectionCheck(ssl_, ssl_host_name_.c_str())) {      LOG(LS_ERROR) << "TLS post connection check failed";      // make sure we close the socket      Cleanup();      // The connect failed so return -1 to shut down the socket      return -1;    }    state_ = SSL_CONNECTED;    AsyncSocketAdapter::OnConnectEvent(this);#if 0  // TODO: worry about this    // Don't let ourselves go away during the callbacks    PRefPtr<OpenSSLAdapter> lock(this);    LOG(LS_INFO) << " -- onStreamReadable";    AsyncSocketAdapter::OnReadEvent(this);    LOG(LS_INFO) << " -- onStreamWriteable";    AsyncSocketAdapter::OnWriteEvent(this);#endif    break;  case SSL_ERROR_WANT_READ:    LOG(LS_INFO) << " -- error want read";    break;  case SSL_ERROR_WANT_WRITE:    LOG(LS_INFO) << " -- error want write";    break;  case SSL_ERROR_ZERO_RETURN:  default:    LOG(LS_INFO) << " -- error " << code;    return (code != 0) ? code : -1;  }  return 0;}voidOpenSSLAdapter::Error(const char* context, int err, bool signal) {  LOG(LS_WARNING) << "SChannelAdapter::Error("                  << context << ", " << err << ")";  state_ = SSL_ERROR;  SetError(err);  if (signal)    AsyncSocketAdapter::OnCloseEvent(this, err);}voidOpenSSLAdapter::Cleanup() {  LOG(LS_INFO) << "Cleanup";  state_ = SSL_NONE;  ssl_read_needs_write_ = false;  ssl_write_needs_read_ = false;  if (ssl_) {    SSL_free(ssl_);    ssl_ = NULL;  }  if (ssl_ctx_) {    SSL_CTX_free(ssl_ctx_);    ssl_ctx_ = NULL;  }}//// AsyncSocket Implementation//intOpenSSLAdapter::Send(const void* pv, size_t cb) {  //LOG(LS_INFO) << "OpenSSLAdapter::Send(" << cb << ")";  switch (state_) {  case SSL_NONE:    return AsyncSocketAdapter::Send(pv, cb);  case SSL_WAIT:  case SSL_CONNECTING:    SetError(EWOULDBLOCK);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -