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

📄 sslendpoint.cc

📁 编译工具
💻 CC
字号:
// -*- Mode: C++; -*-//                            Package   : omniORB// sslEndpoint.cc             Created on: 29 May 2001//                            Author    : Sai Lai Lo (sll)////    Copyright (C) 2001 AT&T Laboratories Cambridge////    This file is part of the omniORB library////    The omniORB library is free software; you can redistribute it and/or//    modify it under the terms of the GNU Library General Public//    License as published by the Free Software Foundation; either//    version 2 of the License, or (at your option) any later version.////    This library is distributed in the hope that it will be useful,//    but WITHOUT ANY WARRANTY; without even the implied warranty of//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU//    Library General Public License for more details.////    You should have received a copy of the GNU Library General Public//    License along with this library; if not, write to the Free//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  //    02111-1307, USA////// Description://	*** PROPRIETORY INTERFACE ***// /*  $Log: sslEndpoint.cc,v $  Revision 1.1.2.24  2005/04/10 22:17:18  dgrisby  Fixes to connection management. Thanks Jon Biggar.  Revision 1.1.2.23  2004/10/18 11:47:02  dgrisby  accept() error handling didn't work on MacOS X.  Revision 1.1.2.22  2004/10/17 22:27:23  dgrisby  Handle errors in accept() properly. Thanks Kamaldeep Singh Khanuja and  Jeremy Van Grinsven.  Revision 1.1.2.21  2004/10/17 20:14:33  dgrisby  Updated support for OpenVMS. Many thanks to Bruce Visscher.  Revision 1.1.2.20  2003/11/12 16:04:17  dgrisby  Set sockets to close on exec.  Revision 1.1.2.19  2003/02/17 02:03:10  dgrisby  vxWorks port. (Thanks Michael Sturm / Acterna Eningen GmbH).  Revision 1.1.2.18  2003/01/06 11:11:55  dgrisby  New AddrInfo instead of gethostbyname.  Revision 1.1.2.17  2002/10/04 11:11:45  dgrisby  Transport fixes: ENOTSOCK for Windows, SOMAXCONN in listen().  Revision 1.1.2.16  2002/09/09 22:11:51  dgrisby  SSL transport cleanup even if certificates are wrong.  Revision 1.1.2.15  2002/08/16 16:00:53  dgrisby  Bugs accessing uninitialised String_vars with [].  Revision 1.1.2.14  2002/05/07 12:54:43  dgrisby  Fix inevitable Windows header brokenness.  Revision 1.1.2.13  2002/05/07 00:46:26  dgrisby  Different define for TCP protocol number.  Revision 1.1.2.12  2002/05/07 00:28:32  dgrisby  Turn off Nagle's algorithm. Fixes odd Linux loopback behaviour.  Revision 1.1.2.11  2002/04/29 11:52:51  dgrisby  More fixes for FreeBSD, Darwin, Windows.  Revision 1.1.2.10  2002/04/16 12:44:27  dpg1  Fix SSL accept bug, clean up logging.  Revision 1.1.2.9  2002/03/19 15:42:04  dpg1  Use list of IP addresses to pick a non-loopback interface if there is one.  Revision 1.1.2.8  2002/03/13 16:05:40  dpg1  Transport shutdown fixes. Reference count SocketCollections to avoid  connections using them after they are deleted. Properly close  connections when in thread pool mode.  Revision 1.1.2.7  2002/03/11 12:24:39  dpg1  Restrict bind to specified host, if any.  Revision 1.1.2.6  2001/07/31 16:16:22  sll  New transport interface to support the monitoring of active connections.  Revision 1.1.2.5  2001/07/26 16:37:21  dpg1  Make sure static initialisers always run.  Revision 1.1.2.4  2001/07/13 15:36:53  sll  Added the ability to monitor connections and callback to the giopServer  when data has arrived at a connection.  Revision 1.1.2.3  2001/06/20 18:35:16  sll  Upper case send,recv,connect,shutdown to avoid silly substutition by  macros defined in socket.h to rename these socket functions  to something else.  Revision 1.1.2.2  2001/06/18 20:27:56  sll  Use strchr instead of index() for maximal portability.  Revision 1.1.2.1  2001/06/11 18:11:06  sll  *** empty log message ****/#include <stdlib.h>#include <stdio.h>#include <omniORB4/CORBA.h>#include <omniORB4/giopEndpoint.h>#include <omniORB4/sslContext.h>#include <SocketCollection.h>#include <ssl/sslConnection.h>#include <ssl/sslAddress.h>#include <ssl/sslEndpoint.h>#include <tcp/tcpConnection.h>#include <openssl/err.h>#include <omniORB4/linkHacks.h>OMNI_EXPORT_LINK_FORCE_SYMBOL(sslEndpoint);OMNI_NAMESPACE_BEGIN(omni)/////////////////////////////////////////////////////////////////////////sslEndpoint::sslEndpoint(const IIOP::Address& address, sslContext* ctx) :   pd_socket(RC_INVALID_SOCKET), pd_address(address), pd_ctx(ctx),  pd_new_conn_socket(RC_INVALID_SOCKET), pd_callback_func(0),  pd_callback_cookie(0), pd_go(1) {  pd_address_string = (const char*) "giop:ssl:255.255.255.255:65535";  // address string is not valid until bind is called.}/////////////////////////////////////////////////////////////////////////sslEndpoint::sslEndpoint(const char* address, sslContext* ctx) :   pd_socket(RC_INVALID_SOCKET), pd_ctx(ctx),  pd_new_conn_socket(RC_INVALID_SOCKET), pd_callback_func(0),  pd_callback_cookie(0), pd_go(1) {  pd_address_string = address;  // OMNIORB_ASSERT(strncmp(address,"giop:ssl:",9) == 0);  const char* host = strchr(address,':');  host = strchr(host+1,':') + 1;  const char* port = strchr(host,':') + 1;  CORBA::ULong hostlen = port - host - 1;  // OMNIORB_ASSERT(hostlen);  pd_address.host = CORBA::string_alloc(hostlen);  strncpy(pd_address.host,host,hostlen);  ((char*)pd_address.host)[hostlen] = '\0';  int rc;  unsigned int v;  rc = sscanf(port,"%u",&v);  // OMNIORB_ASSERT(rc == 1);  // OMNIORB_ASSERT(v > 0 && v < 65536);  pd_address.port = v;}/////////////////////////////////////////////////////////////////////////sslEndpoint::~sslEndpoint() {  if (pd_socket != RC_INVALID_SOCKET) {    CLOSESOCKET(pd_socket);    pd_socket = RC_INVALID_SOCKET;  }}/////////////////////////////////////////////////////////////////////////const char*sslEndpoint::type() const {  return "giop:ssl";}/////////////////////////////////////////////////////////////////////////const char*sslEndpoint::address() const {  return pd_address_string;}/////////////////////////////////////////////////////////////////////////CORBA::BooleansslEndpoint::Bind() {  OMNIORB_ASSERT(pd_socket == RC_INVALID_SOCKET);  if ((pd_socket = socket(INETSOCKET,SOCK_STREAM,0)) == RC_INVALID_SOCKET) {    return 0;  }  {    // Prevent Nagle's algorithm    int valtrue = 1;    if (setsockopt(pd_socket,IPPROTO_TCP,TCP_NODELAY,		   (char*)&valtrue,sizeof(int)) == RC_SOCKET_ERROR) {      CLOSESOCKET(pd_socket);      pd_socket = RC_INVALID_SOCKET;      return 0;    }  }  SocketSetCloseOnExec(pd_socket);  const char* host;  if ((char*)pd_address.host && strlen(pd_address.host) != 0) {    if (omniORB::trace(25)) {      omniORB::logger log;      log << "Explicit bind to host " << pd_address.host << ".\n";    }    host = pd_address.host;  }  else {    host = 0;  }  LibcWrapper::AddrInfo_var ai;  ai = LibcWrapper::getAddrInfo(host, pd_address.port);  if ((LibcWrapper::AddrInfo*)ai == 0) {    if (omniORB::trace(1)) {      omniORB::logger log;      log << "Cannot get the address of host " << host << ".\n";    }    CLOSESOCKET(pd_socket);    return 0;  }  if (pd_address.port) {    int valtrue = 1;    if (setsockopt(pd_socket,SOL_SOCKET,SO_REUSEADDR,		   (char*)&valtrue,sizeof(int)) == RC_SOCKET_ERROR) {      CLOSESOCKET(pd_socket);      pd_socket = RC_INVALID_SOCKET;      return 0;    }  }  if (omniORB::trace(25)) {    omniORB::logger l;    CORBA::String_var addr(ai->asString());    l << "Bind to address " << addr << ".\n";  }  if (::bind(pd_socket, ai->addr(), ai->addrSize()) == RC_SOCKET_ERROR) {    CLOSESOCKET(pd_socket);    return 0;  }  if (listen(pd_socket,SOMAXCONN) == RC_SOCKET_ERROR) {    CLOSESOCKET(pd_socket);    return 0;  }  // Now figure out the details to put in IORs  struct sockaddr_in addr;  SOCKNAME_SIZE_T l;  l = sizeof(struct sockaddr_in);  if (getsockname(pd_socket,		  (struct sockaddr *)&addr,&l) == RC_SOCKET_ERROR) {    CLOSESOCKET(pd_socket);    return 0;  }  pd_address.port = ntohs(addr.sin_port);  if (!(char*)pd_address.host || strlen(pd_address.host) == 0) {    // Try to find the first interface that isn't the loopback    const omnivector<const char*>* ifaddrs      = giopTransportImpl::getInterfaceAddress("giop:ssl");    if (ifaddrs && !ifaddrs->empty()) {      // SSL transport successfully gave us a list of interface addresses      omnivector<const char*>::const_iterator i;      for (i = ifaddrs->begin(); i != ifaddrs->end(); i++) {	if (strcmp(*i, "127.0.0.1"))	  break;      }      if (i == ifaddrs->end()) {	// Only interface was the loopback -- we'll have to use that	i = ifaddrs->begin();      }      pd_address.host = CORBA::string_dup(*i);    }    else {      omniORB::logs(5, "No list of interface addresses; fall back to "		    "system hostname.");      char self[64];      if (gethostname(&self[0],64) == RC_SOCKET_ERROR) {	omniORB::logs(1, "Cannot get the name of this host.");	CLOSESOCKET(pd_socket);	return 0;      }      if (omniORB::trace(10)) {	omniORB::logger l;	l << "My hostname is " << self << ".\n";      }      LibcWrapper::AddrInfo_var ai;      ai = LibcWrapper::getAddrInfo(self, pd_address.port);      if ((LibcWrapper::AddrInfo*)ai == 0) {	if (omniORB::trace(1)) {	  omniORB::logger log;	  log << "Cannot get the address of my hostname " << self << ".\n";	}	CLOSESOCKET(pd_socket);	return 0;      }      pd_address.host = ai->asString();    }  }  if (omniORB::trace(1) && strcmp(pd_address.host,"127.0.0.1") == 0) {    omniORB::logger log;    log << "Warning: the local loop back interface (127.0.0.1) is used as\n"	<< "this server's address. Only clients on this machine can talk to\n"	<< "this server.\n";  }  const char* format = "giop:ssl:%s:%d";  pd_address_string = CORBA::string_alloc(strlen(pd_address.host) +					  strlen(format)+6);  sprintf((char*)pd_address_string,format,	  (const char*)pd_address.host,(int)pd_address.port);  return 1;}/////////////////////////////////////////////////////////////////////////voidsslEndpoint::Poke() {  sslAddress* target = new sslAddress(pd_address,pd_ctx);  giopActiveConnection* conn;  unsigned long timeout_sec, timeout_nsec;  omni_thread::get_time(&timeout_sec, &timeout_nsec, 1);  if ((conn = target->Connect(timeout_sec, timeout_nsec)) == 0) {    if (omniORB::trace(5)) {      omniORB::logger log;      log << "Warning: Fail to connect to myself (" 	  << (const char*) pd_address_string << ") via ssl!\n";    }    pd_go = 0;    // No concurrency control on pd_go, but it should be safe to set    // it to zero here. The worst that can happen is AcceptAndMonitor    // goes one extra time around its loop before spotting the change.  }  else {    delete conn;  }  delete target;}/////////////////////////////////////////////////////////////////////////voidsslEndpoint::Shutdown() {  SHUTDOWNSOCKET(pd_socket);  decrRefCount();  omniORB::logs(20, "SSL endpoint shut down.");}/////////////////////////////////////////////////////////////////////////giopConnection*sslEndpoint::AcceptAndMonitor(giopConnection::notifyReadable_t func,			      void* cookie) {  OMNIORB_ASSERT(pd_socket != RC_INVALID_SOCKET);  pd_callback_func = func;  pd_callback_cookie = cookie;  setSelectable(pd_socket,1,0,0);  while (pd_go) {    pd_new_conn_socket = RC_INVALID_SOCKET;    if (!Select()) break;    if (pd_new_conn_socket != RC_INVALID_SOCKET) {      ::SSL* ssl = SSL_new(pd_ctx->get_SSL_CTX());      SSL_set_fd(ssl, pd_new_conn_socket);      SSL_set_accept_state(ssl);      int go = 1;      while(go) {	int result = SSL_accept(ssl);	int code = SSL_get_error(ssl, result);	switch(code) {	case SSL_ERROR_NONE:	  return new sslConnection(pd_new_conn_socket,ssl,this);	case SSL_ERROR_WANT_READ:	case SSL_ERROR_WANT_WRITE:	  continue;	case SSL_ERROR_SYSCALL:	  {	    if (ERRNO == RC_EINTR)	      continue;	  }	  // otherwise falls through	case SSL_ERROR_SSL:	  {	    if (omniORB::trace(10)) {	      omniORB::logger log;	      char buf[128];	      ERR_error_string_n(ERR_get_error(),buf,128);	      log << "openSSL error detected in sslEndpoint::accept.\n"		  << "Reason: " << (const char*) buf << "\n";	    }	    SSL_free(ssl);	    CLOSESOCKET(pd_new_conn_socket);	    go = 0;	  }	}      }    }  }  return 0;}/////////////////////////////////////////////////////////////////////////CORBA::BooleansslEndpoint::notifyReadable(SocketHandle_t fd) {  if (fd == pd_socket) {    // New connection    SocketHandle_t sock;again:    sock = ::accept(pd_socket,0,0);    if (sock == RC_SOCKET_ERROR) {      if (ERRNO == RC_EBADF) {        omniORB::logs(20, "accept() returned EBADF, unable to continue");        return 0;      }      else if (ERRNO == RC_EINTR) {        omniORB::logs(20, "accept() returned EINTR, trying again");        goto again;      }#ifdef UnixArchitecture      else if (ERRNO == RC_EAGAIN) {        omniORB::logs(20, "accept() returned EAGAIN, trying again");        goto again;      }#endif      if (omniORB::trace(20)) {        omniORB::logger log;        log << "accept() failed with unknown error " << ERRNO << "\n";      }    }    else {#if defined(__vxWorks__)      // vxWorks "forgets" socket options      static const int valtrue = 1;      if(setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,		    (char*)&valtrue, sizeof(valtrue)) == ERROR) {	return 0;      }#endif      pd_new_conn_socket = sock;    }    setSelectable(pd_socket,1,0,1);    return 1;  }  else {    // Existing connection    SocketLink* conn = findSocket(fd,1);    if (conn) {      pd_callback_func(pd_callback_cookie,(sslConnection*)conn);    }    return 1;  }}OMNI_NAMESPACE_END(omni)

⌨️ 快捷键说明

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