// Connect EINVAL
TEST_F(SSLClientServerConnectionTest, ConnectEinval) {
  MockHandler ch;
  SSLContext context(SSLContext::TLSv1_1);
  context.SetCertificate(std::string(CLIENT_CERT));
  context.SetPrivateKey(std::string(CLIENT_PKEY));
  context.SetCAFile(std::string(CA_CERT));
  context.SetCiphers(std::string(CIPHER_LIST));
  context.SetVerifyMode(SSLContext::VERIFY_PEER);
  SSLClient cl(ch, context);
  MockHandler sh;
  SSLContext server_context(SSLContext::TLSv1_1);
  server_context.SetCertificate(std::string(SERVER_CERT));
  server_context.SetPrivateKey(std::string(SERVER_PKEY));
  server_context.SetCAFile(std::string(CA_CERT));
  server_context.SetCiphers(std::string(CIPHER_LIST));
  server_context.SetVerifyMode(SSLContext::VERIFY_PEER);
  SSLServer sv(sh, server_context);

  Error e = sv.Start(TEST_ADDR, TEST_PORT);
  ASSERT_EQ(LNR_OK, e.Code());

  SSLSocket cs = cl.CreateSocket(TEST_ADDR, TEST_PORT);

  EXPECT_CALL(sh, OnConnectMock(_)).WillOnce(Assign(&srv_finished, true));
  EXPECT_CALL(ch, OnConnectMock(cs)).WillOnce(Assign(&cli_finished, true));

  e = cs.Connect();
  ASSERT_EQ(LNR_OK, e.Code());
  WAIT_TO_FINISH_CALLBACK();

  e = sh.s_.Connect();
  ASSERT_EQ(LNR_EINVAL, e.Code());
}
示例#2
0
static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) {
  int ret = preverify_ok;

  /* determine the status for the current cert */
  X509_STORE_CTX_get_current_cert(ctx);
  int err = X509_STORE_CTX_get_error(ctx);
  int depth = X509_STORE_CTX_get_error_depth(ctx);

  /* conjure the stream & context to use */
  SSL *ssl = (SSL*)X509_STORE_CTX_get_ex_data
    (ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
  SSLSocket *stream =
    (SSLSocket*)SSL_get_ex_data(ssl, SSLSocket::GetSSLExDataIndex());

  /* if allow_self_signed is set, make sure that verification succeeds */
  if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT &&
      stream->getContext()["allow_self_signed"].toBoolean()) {
    ret = 1;
  }

  /* check the depth */
  Variant vdepth = stream->getContext()["verify_depth"];
  if (vdepth.toBoolean() && depth > vdepth.toInt64()) {
    ret = 0;
    X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_CHAIN_TOO_LONG);
  }

  return ret;
}
示例#3
0
void
rec( SSLSocket *server ) 
{   
    server->open();
    server->bind( 5000 );
    server->listen();
    
    int count = 3;
    
    SSLSocket client;
    
    // Socket client;
    // we block here
    if ( server->accept(client) )
    {
        while (count--)
        {
            std::string msgIn;
            if ( client.receive(msgIn) )
            {
                std::cout << "Server recieved message: " << msgIn << std::endl;
                std::cout << "Server sending ACK" << std::endl;
                std::string rep("ACK");
                client.send(rep);
            }
            sleep(1);
        }
    }
    server->close();
    std::cout << "Server closed" << std::endl;      
}
示例#4
0
static int passwd_callback(char *buf, int num, int verify, void *data) {
  /* TODO: could expand this to make a callback into PHP user-space */
  SSLSocket *stream = (SSLSocket *)data;
  String passphrase = stream->getContext()["passphrase"];
  if (!passphrase.empty() && passphrase.size() < num - 1) {
    memcpy(buf, passphrase.data(), passphrase.size() + 1);
    return passphrase.size();
  }
  return 0;
}
// Connect - Disconnect delayed Socket Destruct: must not SEGV
TEST_F(SSLClientServerConnectionTest, DelayedSocketDestruct) {
  DelayedMockHandler ch;
  SSLContext context(SSLContext::TLSv1_1);
  context.SetCertificate(std::string(CLIENT_CERT));
  context.SetPrivateKey(std::string(CLIENT_PKEY));
  context.SetCAFile(std::string(CA_CERT));
  context.SetCiphers(std::string(CIPHER_LIST));
  context.SetVerifyMode(SSLContext::VERIFY_PEER);
  SSLClient cl(ch, context);
  MockHandler sh;
  SSLContext server_context(SSLContext::TLSv1_1);
  server_context.SetCertificate(std::string(SERVER_CERT));
  server_context.SetPrivateKey(std::string(SERVER_PKEY));
  server_context.SetCAFile(std::string(CA_CERT));
  server_context.SetCiphers(std::string(CIPHER_LIST));
  server_context.SetVerifyMode(SSLContext::VERIFY_PEER);
  SSLServer sv(sh, server_context);

  {
    InSequence dummy;
    EXPECT_CALL(sh, OnConnectMock(_)).WillOnce(WithArg<0>(Disconnect()));
    EXPECT_CALL(sh, OnDisconnectMock(Eq(ByRef(sh.s_)), Error(LNR_OK))).WillOnce(Assign(&srv_finished, true));
  }

  Error e = sv.Start(TEST_ADDR, TEST_PORT);
  ASSERT_EQ(LNR_OK, e.Code());
  SSLSocket cs = cl.CreateSocket(TEST_ADDR, TEST_PORT);

  {
    InSequence dummy;
    EXPECT_CALL(ch, OnConnectMock(cs));
    EXPECT_CALL(ch, OnDisconnectMock(cs, Error(LNR_EOF))).WillOnce(Assign(&cli_finished, true));
  }

  e = cs.Connect();
  ASSERT_EQ(LNR_OK, e.Code());
  WAIT_TO_FINISH_CALLBACK();
  ASSERT_EQ(global::gs_, cs);

  cs = cl.CreateSocket(TEST_ADDR, TEST_PORT);

  EXPECT_CALL(sh, OnConnectMock(_)).WillOnce(Assign(&srv_finished, true));
  EXPECT_CALL(ch, OnConnectMock(cs)).WillOnce(Assign(&cli_finished, true));

  e = cs.Connect();
  ASSERT_EQ(LNR_OK, e.Code());
  WAIT_TO_FINISH_CALLBACK();
  ASSERT_NE(global::gs_, cs);

  EXPECT_CALL(sh, OnDisconnectMock(_, _)).Times(::testing::AtLeast(0));
  EXPECT_CALL(ch, OnDisconnectMock(_, _)).Times(::testing::AtLeast(0));
}
// Disconnect EALREADY
TEST_F(SSLClientServerConnectionTest, DisconnectEalready) {
  MockHandler ch;
  SSLContext context(SSLContext::TLSv1_1);
  context.SetCertificate(std::string(CLIENT_CERT));
  context.SetPrivateKey(std::string(CLIENT_PKEY));
  context.SetCAFile(std::string(CA_CERT));
  context.SetCiphers(std::string(CIPHER_LIST));
  context.SetVerifyMode(SSLContext::VERIFY_PEER);
  SSLClient cl(ch, context);
  SSLSocket cs = cl.CreateSocket(TEST_ADDR, TEST_PORT);

  EXPECT_CALL(ch, OnConnectMock(_)).Times(0);
  EXPECT_CALL(ch, OnDisconnectMock(_, _)).Times(0);

  Error e = cs.Disconnect();
  ASSERT_EQ(LNR_EALREADY, e.Code());
  msleep(WAIT_MSEC);
}
// Timeout
TEST_F(SSLClientServerConnectionTest, ConnectTimeout) {
  MockHandler ch;
  SSLContext context(SSLContext::TLSv1_1);
  context.SetCertificate(std::string(CLIENT_CERT));
  context.SetPrivateKey(std::string(CLIENT_PKEY));
  context.SetCAFile(std::string(CA_CERT));
  context.SetCiphers(std::string(CIPHER_LIST));
  context.SetVerifyMode(SSLContext::VERIFY_PEER);
  SSLClient cl(ch, context);
  SSLSocket cs = cl.CreateSocket(TEST_ADDR_4_TIMEOUT, TEST_PORT);

  EXPECT_CALL(ch, OnConnectMock(_)).Times(0);
  EXPECT_CALL(ch, OnDisconnectMock(cs, Error(LNR_ETIMEDOUT))).WillOnce(DoAll(Assign(&srv_finished, true), Assign(&cli_finished, true)));

  Error e = cs.Connect(1);
  ASSERT_EQ(LNR_OK, e.Code());
  WAIT_TO_FINISH_CALLBACK();
}
示例#8
0
ContextId ServiceManager::registerContext(SSLContextShrPtr _context, uint32 _sktClrNum, uint32 _perClrNum)
{
	if (!m_usingSSL)
		return 0;

	if (!_context)
	{
		sLogger->out(OL_DEBUG, "[Error]", __FILE__, " - [", d2s(__LINE__).c_str(), "]: ", "!_context", 0);
		return 0;
	}

	_sktClrNum = _sktClrNum == 0 ? 1 : _sktClrNum;
	_perClrNum = _perClrNum == 0 ? 1 : _perClrNum;

	DynShrLock lock(m_contexts.mutex((ContextId)_context.get(), (ContextId)_context.get()));
	if (m_contexts.add((ContextId)_context.get(), _context, (ContextId)_context.get(), false) != 0)
	{
		sLogger->out(OL_DEBUG, "[Error]", __FILE__, " - [", d2s(__LINE__).c_str(), "]: ", "m_contexts.add != 0", 0);
		return 0;
	}
	else
	{
		// create sslSocket freelist
		IFreeListShrPtr sslSktFl(new FreeList<SSLSocket>(_sktClrNum, _perClrNum));
		sSSLSktFList.init(_sktClrNum);
		uint32 maxSSLNum = _sktClrNum*_perClrNum;
		for (uint32 ix=0, i=0; i<maxSSLNum; ++i)
		{
			ix = (m_currMaxSnIndex+i) % m_sslSvcs.size();
			SSLSocket* sslSkt = (SSLSocket*)sslSktFl->get(i);
			if (sslSkt)
				sslSkt->init(ISessionShrPtr(new Session(m_currMaxSnIndex+i, &m_netInfoMgr, m_currMaxSnIndex+i+(uint32)_context.get(), 
														m_pktParser->create())), m_sslSvcs[ix], _context->getContext(), (ContextId)_context.get(), this);
		}
		m_currMaxSnIndex += maxSSLNum;
		if (sSSLSktFList.add((ContextId)_context.get(), sslSktFl) != 0)
		{
			sLogger->out(OL_DEBUG, "[Error]", __FILE__, " - [", d2s(__LINE__).c_str(), "]: ", "sSSLSktFList.add != 0", 0);
			return 0;
		}
		else
			return (ContextId)_context.get();
	}
}
示例#9
0
int
main(int argc, char *argv[])
{  
    std::cout << "SSLDemo  Copyright (C) 2015,  W. B. Yates" << std::endl;
    std::cout << "This program comes with ABSOLUTELY NO WARRANTY; for details see http://www.gnu.org/licenses/." << std::endl;
    std::cout << "This is free software, and you are welcome to redistribute it" << std::endl;
    std::cout << "under certain conditions; see http://www.gnu.org/licenses/" << std::endl;
    
    SSLContext ctx1("client", "client.pem", "password");
    SSLContext ctx2("server", "server.pem", "password", true);
    
    SSLSocket::registerContext( &ctx1 );
    SSLSocket::registerContext( &ctx2 );
    
    SSLSocket client;
    client.setContext("client");
    
    SSLSocket server("server");
    
    //Socket client;
    //Socket server;
    

    for (int i = 0; i < 5; ++i)
    {
        std::cout << "\nBegin socket test " << i + 1 <<  std::endl;
        std::thread thread1 = std::thread(rec,&server);
        std::thread thread2;
        
        if (i == 0)
            thread2 = std::thread(sender1,&client);
        else thread2 = std::thread(sender2,&client);
        thread1.join();
        thread2.join();
    }

    SSLSocket::clearRegister();
    std::cout << "End socket test" <<  std::endl;
    return 0;
}
示例#10
0
ServiceManager::~ServiceManager()
{
	uint32 maxTcpNum = m_tcpSktClrNum*m_perClrTcpSktNum;
	for (uint32 i=0; (i<maxTcpNum && m_usingTcp); ++i)
	{
		TcpSocket* tcpSkt = (TcpSocket*)sTcpSktFList.get()->get(i);
		if (tcpSkt)
		{
			tcpSkt->close();
			tcpSkt->clean();
		}
	}

	HashMapShrPtr hm = sSSLSktFList.getFls();
	if (hm)
	{
		uint32 size = hm->arraySize();
		for (uint32 i=0; i<size; ++i)
		{
			hm->lockWrite((ContextId)i, (ContextId)i);
			std::map<ContextId, IFreeListShrPtr>& hmMap = hm->map(i);
			for (std::map<ContextId, IFreeListShrPtr>::iterator itr=hmMap.begin(); itr!=hmMap.end(); ++itr)
			{
				uint32 maxSSLSktNum = itr->second->getClr() * itr->second->getPer();
				for (uint32 j=0; (j<maxSSLSktNum && m_usingSSL); ++j)
				{
					SSLSocket* sslSkt = (SSLSocket*)itr->second->get(j);
					if (sslSkt)
					{
						sslSkt->socket()->lowest_layer().close();
						sslSkt->clean();
					}
				}
			}
			hm->unlockWrite((ContextId)i, (ContextId)i);
		}
	}
	hm = HashMapShrPtr();

	uint32 maxUdpSubNum = m_udpSubSktClrNum*m_perClrUdpSubSktNum;
	for (uint32 i=0; (i<maxUdpSubNum && m_usingUdp); ++i)
	{
		UdpSubSocket* udpSubSkt = (UdpSubSocket*)sUdpSubSktFList.get()->get(i);
		if (udpSubSkt)
		{
			udpSubSkt->close();
			udpSubSkt->clean();
		}
	}
	uint32 maxUdpNum = m_udpSktClrNum*m_perClrUdpSktNum;
	for (uint32 i=0; (i<maxUdpNum && m_usingUdp); ++i)
	{
		UdpSocket* udpSkt = (UdpSocket*)sUdpSktFList.get()->get(i);
		if (udpSkt)
		{
			udpSkt->socket()->close();
			udpSkt->clean();
		}
	}

	m_contexts.clear();

	for (uint32 i=0; i<m_tcpAcptrSvcs.size(); ++i)
	{
		if (m_tcpAcptrSvcs[i])
			delete m_tcpAcptrSvcs[i];
	}
	for (uint32 i=0; i<m_sslAcptrSvcs.size(); ++i)
	{
		if (m_sslAcptrSvcs[i])
			delete m_sslAcptrSvcs[i];
	}
	for (uint32 i=0; i<m_udpAcptrSvcs.size(); ++i)
	{
		if (m_udpAcptrSvcs[i])
			delete m_udpAcptrSvcs[i];
	}
	for (uint32 i=0; i<m_tcpSvcs.size(); ++i)
	{
		if (m_tcpSvcs[i])
			delete m_tcpSvcs[i];
	}
	for (uint32 i=0; i<m_sslSvcs.size(); ++i)
	{
		if (m_sslSvcs[i])
			delete m_sslSvcs[i];
	}
	for (uint32 i=0; i<m_udpSvcs.size(); ++i)
	{
		if (m_udpSvcs[i])
			delete m_udpSvcs[i];
	}
	
}
示例#11
0
static Variant sockopen_impl(CStrRef hostname, int port, Variant &errnum,
                             Variant &errstr, double timeout,
                             bool persistent) {
  string key;
  if (persistent) {
    key = hostname.data();
    key += ":";
    key += boost::lexical_cast<string>(port);
    Socket *sock =
      dynamic_cast<Socket*>(g_persistentObjects->get("socket", key.c_str()));
    if (sock) {
      if (sock->getError() == 0 && sock->checkLiveness()) {
        return Object(sock);
      }

      // socket had an error earlier, we need to remove it from persistent
      // storage, and create a new one
      g_persistentObjects->remove("socket", key.c_str());
    }
  }

  Object ret;
  const char *name = hostname.data();
  Socket *sock = NULL;

  if (timeout <= 0) timeout = RuntimeOption::SocketDefaultTimeout;
  // test if protocol is SSL
  SSLSocket *sslsock = SSLSocket::Create(name, port, timeout);
  if (sslsock) {
    sock = sslsock;
    ret = sock;
  } else if (!create_new_socket(name, port, errnum, errstr,
                                ret, sock, timeout)) {
    return false;
  }
  assert(ret.get() && sock);

  sockaddr_storage sa_storage;
  struct sockaddr *sa_ptr;
  size_t sa_size;
  if (!set_sockaddr(sa_storage, sock, name, port, sa_ptr, sa_size)) {
    return false;
  }

  int retval;
  int fd = sock->fd();
  IOStatusHelper io("socket::connect", name, port);
  if (timeout <= 0) {
    retval = connect(fd, sa_ptr, sa_size);
  } else {
    // set non-blocking so we can do timeouts
    long arg = fcntl(fd, F_GETFL, NULL);
    fcntl(fd, F_SETFL, arg | O_NONBLOCK);

    retval = connect(fd, sa_ptr, sa_size);
    if (retval < 0) {
      if (errno == EINPROGRESS) {
        struct pollfd fds[1];
        fds[0].fd = fd;
        fds[0].events = POLLOUT;
        if (poll(fds, 1, (int)(timeout * 1000))) {
          socklen_t lon = sizeof(int);
          int valopt;
          getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon);
          if (valopt) {
            std::string msg = "failed to connect to ";
            msg += name;
            msg += ":";
            msg += boost::lexical_cast<std::string>(port);
            SOCKET_ERROR(sock, msg.c_str(), valopt);
            errnum = sock->getError();
            errstr = String(Util::safe_strerror(sock->getError()));
            return false;
          } else {
            retval = 0; // success
          }
        } else {
          std::string msg = "timed out after ";
          msg += boost::lexical_cast<std::string>(timeout);
          msg += " seconds when connecting to ";
          msg += name;
          msg += ":";
          msg += boost::lexical_cast<std::string>(port);
          SOCKET_ERROR(sock, msg.c_str(), ETIMEDOUT);
          errnum = sock->getError();
          errstr = String(Util::safe_strerror(sock->getError()));
          return false;
        }
      }
    }

    // set to blocking mode
    arg = fcntl(fd, F_GETFL, NULL);
    fcntl(fd, F_SETFL, arg & ~O_NONBLOCK);
  }

  if (retval != 0) {
    errnum = sock->getError();
    errstr = String(Util::safe_strerror(sock->getError()));
    return false;
  }

  if (sslsock && !sslsock->onConnect()) {
    raise_warning("Failed to enable crypto");
    return false;
  }

  if (persistent) {
    assert(!key.empty());
    g_persistentObjects->set("socket", key.c_str(), sock);
  }

  return ret;
}
示例#12
0
static Variant new_socket_connect(const HostURL &hosturl, int timeout,
                                  Variant &errnum, Variant &errstr) {
  int domain = AF_UNSPEC;
  int type = SOCK_STREAM;
  auto const& scheme = hosturl.getScheme();
  Socket* sock = nullptr;
  SSLSocket *sslsock = nullptr;
  std::string sockerr;
  int error;

  if (scheme == "udp" || scheme == "udg") {
    type = SOCK_DGRAM;
  } else if (scheme == "unix") {
    domain = AF_UNIX;
  }

  int fd = -1;
  if (domain == AF_UNIX) {
    sockaddr_storage sa_storage;
    struct sockaddr *sa_ptr;
    size_t sa_size;

    fd = socket(domain, type, 0);

    sock = new Socket(fd, domain, hosturl.getHost().c_str(), hosturl.getPort());

    if (!set_sockaddr(sa_storage, sock, hosturl.getHost().c_str(),
                      hosturl.getPort(), sa_ptr, sa_size)) {
      return false;
    }
    if (connect_with_timeout(fd, sa_ptr, sa_size, timeout,
                             hosturl, sockerr, error) != 0) {
      SOCKET_ERROR(sock, sockerr.c_str(), error);
      errnum = sock->getLastError();
      errstr = HHVM_FN(socket_strerror)(sock->getLastError());
      delete sock;
      return false;
    }
  } else {
    struct addrinfo  hints;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family   = domain;
    hints.ai_socktype = type;

    auto port = folly::to<std::string>(hosturl.getPort());
    auto host = hosturl.getHost();

    struct addrinfo *aiHead;
    int errcode = getaddrinfo(host.c_str(), port.c_str(), &hints, &aiHead);
    if (errcode != 0) {
      errstr = String(gai_strerror(errcode), CopyString);
      return false;
    }
    SCOPE_EXIT { freeaddrinfo(aiHead); };

    for (struct addrinfo *ai = aiHead; ai != nullptr; ai = ai->ai_next) {
      domain = ai->ai_family;
      fd = socket(domain, ai->ai_socktype, ai->ai_protocol);
      if (fd == -1) {
        continue;
      }

      if (connect_with_timeout(fd, ai->ai_addr, ai->ai_addrlen, timeout,
                               hosturl, sockerr, error) == 0) {
        break;
      }
      fd = -1;
    }

    sslsock = SSLSocket::Create(fd, domain, hosturl, timeout);
    if (sslsock) {
      sock = sslsock;
    } else {
      sock = new Socket(fd, domain,
                        hosturl.getHost().c_str(), hosturl.getPort());
    }
  }

  if (!sock->valid()) {
    SOCKET_ERROR(sock,
        sockerr.empty() ? "unable to create socket" : sockerr.c_str(), error);
    errnum = sock->getLastError();
    errstr = HHVM_FN(socket_strerror)(sock->getLastError());
    delete sock;
    return false;
  }

  if (sslsock && !sslsock->onConnect()) {
    raise_warning("Failed to enable crypto");
    delete sslsock;
    return false;
  }

  return Resource(sock);
}
示例#13
0
int main()
{

#if 1

    //string ip = "service.evchong.com";
    string ip = "123.59.53.85";
    string buf;
    string url;
    string param;
    HttpsPost httpspost;
    
    do
    {
        //int ret = httpspost.Connect(ip, 443, HOSTNAME_TYPE);
        int ret = httpspost.Connect(ip, 443, IP_TYPE);
        if( HTTPS_CONNECTED ==  ret)
        {
            break;
        }
        else if( HTTPS_CONNECT_FALSE ==  ret)
        {
            break;
        }
        
        // 防止死循环,设置超时或者尝试次数,close break
        
    }while(1);
    
#if 1
    int ok_couter = 0;
    int false_couter = 0;
    int connectCouter = 1;
/*
    while(1)
    {
        httpspost.State();
        ok_couter++;
        cout<< ok_couter<< endl;
        sleep(1);

    }
*/
    while(1)
    {
        // heartbeat
        url     = "https://service.evchong.com:443/evchong_API/evchong/v1/heartbeat";
        param   = "{\"chargeBoxSerialNumber\":{\"chargeBoxSerialNumber\":\"1012090561\"},\"chargePointSerialNumber\":{\"chargePointSerialNumber\":\"CSN00001\"}}";
        
        httpspost.State();
        //if(httpspost.State() == HTTPS_FREE)
        {
            do
            {
                //int ret = httpspost.Connect(ip, 443, HOSTNAME_TYPE);
                int ret = httpspost.Connect(ip, 443, IP_TYPE);
                if( HTTPS_CONNECTED ==  ret)
                {
                    connectCouter++;
                    break;
                }
                else if( HTTPS_CONNECT_FALSE ==  ret)
                {
                    break;
                }
                
                // 防止死循环,设置超时或者尝试次数,close break
                
            }while(1);
        }

        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            cout<< ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> send heartbeat" << endl;
            while(1)
            {
                int ret = httpspost.Recv(buf);
                if(HTTPS_RECVED == ret)
                {
                    ok_couter++;
                    //cout<< ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> revc heartbeat  " << endl;
                    //cout<< "response: " << endl << buf << endl;
                    break;
                }
                else if(HTTPS_RECV_FALSE == ret)
                {
                    false_couter++;
                    httpspost.Close();

                    //cout<< ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> recv heartbeat false and close" << endl;
                    break;
                }
            }
        }
        cout<<"connectCouter = "<< connectCouter << ", false_couter = " << false_couter << ", ok_couter = " << ok_couter << endl;
        sleep(65);
    }
#endif

    


#endif



#if 0
    string ip = "183.131.144.74";
    string buf;
    string url;
    string param;
    HttpsPost httpspost;
    
    do
    {
        int ret = httpspost.Connect(ip, 8443, IP_TYPE);
        if( HTTPS_CONNECTED ==  ret)
        {
            break;
        }
        else if( HTTPS_CONNECT_FALSE ==  ret)
        {
            break;
        }
        
        // 防止死循环,设置超时或者尝试次数,close break
        
    }while(1);
    

    
#if 1
{
    /*
     * 例子4
     * HttpsPost类测试,HTTP,SSL_ENABLE需要置为0
     */


        
        // deviceBoot
        url     = "https://183.131.144.74:8443/evchong_API/evchong/v1/deviceBoot";
        param   = "{\"iccid\":{\"iccid\":\"112233\"},\"chargePointModel\":{\"chargePointModel\":\"11\"},\"chargePointVendor\":{\"chargePointVendor\":\"3456\"},\"chargeBoxSerialNumber\":{\"chargeBoxSerialNumber\":\"123456\"},\"chargePointSerialNumber\":{\"chargePointSerialNumber\":\"45678\"},\"imsi\":{\"imsi\":\"xxxxx\"},\"meterType\":{\"meterType\":\"xxxxx\"},\"firmwareVersion\":{\"firmwareVersion\":\"xxxxx\"},\"meterSerialNumber\":{\"meterSerialNumber\":\"xxxxx\"}}";
        
        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            cout<< "send deviceBoot ----------------------- " << endl;
            while(1)
            {
                int ret = httpspost.Recv(buf);
                if(HTTPS_RECVED == ret)
                {
                    cout<< "recv deviceBoot" << endl;
                    cout<< "response: " << endl << buf << endl;
                    break;
                }
                else if(HTTPS_RECV_FALSE == ret)
                {
                    httpspost.Close();
                    cout<< "recv deviceBoot false and close" << endl;
                    break;
                }
            }
        }
        
        sleep(2);

}
#endif

#if 1
{
        // heartbeat
        url     = "https://183.131.144.74:8443/evchong_API/evchong/v1/heartbeat";
        param   = "{\"chargePointSerialNumber\":{\"chargePointSerialNumber\":\"112233\"},\"chargeBoxSerialNumber\":{\"chargeBoxSerialNumber\":\"33qw34\"}}";
        
        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            cout<< "send heartbeat ----------------------- " << endl;
            while(1)
            {
                int ret = httpspost.Recv(buf);
                if(HTTPS_RECVED == ret)
                {
                    cout<< "recv heartbeat" << endl;
                    cout<< "response: " << endl << buf << endl;
                    break;
                }
                else if(HTTPS_RECV_FALSE == ret)
                {
                    httpspost.Close();
                    cout<< "recv heartbeat false and close" << endl;
                    break;
                }
            }
        }
        
        sleep(2);
}
#endif

#if 1
{
        // authorize
        url     = "https://183.131.144.74:8443/evchong_API/evchong/v1/authorize";
        param   = "{\"idToken\":{\"idToken\":\"12345\"},\"chargeBoxSerialNumber\":{\"chargeBoxSerialNumber\":\"0004455\"}}";
        
        buf.erase();
        
        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            cout<< "send authorize ----------------------- " << endl;
            while(1)
            {
                if(HTTPS_RECVED == httpspost.Recv(buf))
                {
                    cout<< "recv authorize" << endl;
                    cout<< "response: " << endl << buf << endl;
                    break;
                }
            }
        }
        
        sleep(2);
}
#endif

#if 0
{
        // startTrans
        url     = "https://183.131.144.74:8443/evchong_API/evchong/v1/startTrans";
        param   = "{\"idTag\":{\"idToken\":\"223344\"},\"connectorId\":1,\"meterStart\":1,\"reservationId\":1,\"chargeBoxSerialNumber\":{\"chargeBoxSerialNumber\":\"123456\"},\"timestamp\":1425289031076}";
        
        buf.erase();
        
        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            cout<< "send startTrans ----------------------- " << endl;
            while(1)
            {
                if(HTTPS_RECVED == httpspost.Recv(buf))
                {
                    cout<< "recv startTrans" << endl;
                    cout<< "response: " << endl << buf << endl;
                    break;
                }
            }
        }
        
        sleep(2);
}
#endif

#if 0
{
        // meterValues
        url     = "https://183.131.144.74:8443/evchong_API/evchong/v1/meterValues";
        param   = "{\"connectorId\":1,\"transactionId\":1,\"chargeBoxSerialNumber\":{\"chargeBoxSerialNumber\":\"123456\"},\"values\":[{\"measurand\":\"Energy_Active_Import_Register\",\"unit\":\"Wh\",\"value\":\"xxxxx\",\"location\":\"Outlet\",\"context\":\"Sample_Periodic\",\"format\":\"Raw\",\"timestamp\":1425289652130}]}";
        
        buf.erase();
        
        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            cout<< "send meterValues ----------------------- " << endl;
            while(1)
            {
                if(HTTPS_RECVED == httpspost.Recv(buf))
                {
                    cout<< "recv meterValues" << endl;
                    cout<< "response: " << endl << buf << endl;
                    break;
                }
            }
        }
        
        sleep(2);
}
#endif

#if 0
{
        // stopTrans
        url     = "https://183.131.144.74:8443/evchong_API/evchong/v1/stopTrans";
        param   = "{\"idTag\":{\"idToken\":\"123456\"},\"transactionId\":1,\"transactionData\":{\"values\":{\"measurand\":\"Energy_Active_Import_Register\",\"unit\":\"Wh\",\"value\":\"xxxxxx\",\"location\":\"Outlet\",\"context\":\"Sample_Periodic\",\"format\":\"Raw\",\"timestamp\":1425886218825}},\"chargeBoxSerialNumber\":{\"chargeBoxSerialNumber\":\"445566\"},\"meterStop\":1,\"timestamp\":1425886218829}";
        
        buf.erase();
        
        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            cout<< "send stopTrans ----------------------- " << endl;
            while(1)
            {
                if(HTTPS_RECVED == httpspost.Recv(buf))
                {
                    cout<< "recv stopTrans" << endl;
                    cout<< "response: " << endl << buf << endl;
                    break;
                }
            }
        }
        
        sleep(2);
}
#endif

#if 0
{
        // statusNotify
        url     = "https://183.131.144.74:8443/evchong_API/evchong/v1/statusNotify";
        param   = "{\"connectorId\":1,\"vendorErrorCode\":\"1122\",\"chargeBoxSerialNumber\":{\"chargeBoxSerialNumber\":\"123456\"},\"errorCode\":\"GroundFailure\",\"vendorId\":\"4455\",\"info\":\"xxxxx\",\"timestamp\":1425290540330,\"status\":\"Available\"}";
        
        buf.erase();
        
        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            cout<< "send statusNotify ----------------------- " << endl;
            while(1)
            {
                if(HTTPS_RECVED == httpspost.Recv(buf))
                {
                    cout<< "recv statusNotify" << endl;
                    cout<< "response: " << endl << buf << endl;
                    break;
                }
            }
        }
        
        sleep(2);
        


}
#endif

    httpspost.Close();
#endif
















////////////////////////////////////////////////////////////////////////////////////////

    
#if 0
{
    /*
     * 例子1
     * sslSocket类测试
     */
    SSLSocket  ssocket;
    string ip1 = "127.0.0.1";
    string buf1 = "hello, I am sslSocket";
  
    ssocket.Connect(ip1, 7838, IP_TYPE);
    ssocket.Send(buf1);
    ssocket.Recv(buf1);
    ssocket.Close();
}
#endif


#if 0
{
    /*
     * 例子2
     * HttpsPost类测试,HTTPS, 需要开server
     */
    string ip = "127.0.0.1";
    string buf;
    HttpsPost httpspost;
    if( HTTPS_CONNECTED == httpspost.Connect(ip, 7838, IP_TYPE) )
    {
        string url = "127.0.0.1";
        string param = "hehe";
        
        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            if( HTTPS_RECVED == httpspost.Recv(buf))
            {
                cout<< "response: " << buf << endl;
            }
        }

        httpspost.Close();
    }
}
#endif



#if 0
{
    /*
     * 例子3
     * HttpsPost类测试,HTTPS,发送给微信,SSL_ENABLE需要置为1
     */
    string ip = "api.weixin.qq.com";
    string buf;
    HttpsPost httpspost;
    if( HTTPS_CONNECTED == httpspost.Connect(ip, 443, HOSTNAME_TYPE) )
    {
        string url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
        string param = "'button':[{'type':'click','name':'helloworld','key':'HELLO_WORLD'}]";
        
        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            if( HTTPS_RECVED == httpspost.Recv(buf))
            {
                cout<< "response: " << buf << endl;
            }
        }

        httpspost.Close();
    }
}
#endif


#if 0
{
    /*
     * 例子4
     * HttpsPost类测试,HTTP,SSL_ENABLE需要置为0
     */
    string ip = "183.131.144.74";
    string buf;
    HttpsPost httpspost;
    if( HTTPS_CONNECTED == httpspost.Connect(ip, 8080, IP_TYPE) )
    {
        string url;
        string param;
        
        // deviceBoot
        url     = "http://183.131.144.74:8080/evchong_API/evchong/v1/deviceBoot";
        param   = "{\"iccid\":{\"iccid\":\"112233\"},\"chargePointModel\":{\"chargePointModel\":\"11\"},\"chargePointVendor\":{\"chargePointVendor\":\"3456\"},\"chargeBoxSerialNumber\":{\"chargeBoxSerialNumber\":\"123456\"},\"chargePointSerialNumber\":{\"chargePointSerialNumber\":\"45678\"},\"imsi\":{\"imsi\":\"xxxxx\"},\"meterType\":{\"meterType\":\"xxxxx\"},\"firmwareVersion\":{\"firmwareVersion\":\"xxxxx\"},\"meterSerialNumber\":{\"meterSerialNumber\":\"xxxxx\"}}";
        
        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            if( HTTPS_RECVED == httpspost.Recv(buf))
            {
                //cout<< "response: " << buf << endl;
            }
        }
        
        // heartbeat
        url     = "http://183.131.144.74:8080/evchong_API/evchong/v1/heartbeat";
        param   = "{\"chargePointSerialNumber\":{\"chargePointSerialNumber\":\"112233\"},\"chargeBoxSerialNumber\":{\"chargeBoxSerialNumber\":\"33qw34\"}}";
        
        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            if( HTTPS_RECVED == httpspost.Recv(buf))
            {
                //cout<< "response: " << buf << endl;
            }
        }
        
        // authorize
        url     = "http://183.131.144.74:8080/evchong_API/evchong/v1/authorize";
        param   = "{\"idToken\":{\"idToken\":\"12345\"},\"chargeBoxSerialNumber\":{\"chargeBoxSerialNumber\":\"0004455\"}}";
        
        buf.erase();
        
        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            if( HTTPS_RECVED == httpspost.Recv(buf))
            {
                // cout<< "response: " << buf << endl;
            }
        }
        
        // startTrans
        url     = "http://183.131.144.74:8080/evchong_API/evchong/v1/startTrans";
        param   = "{\"idTag\":{\"idToken\":\"223344\"},\"connectorId\":1,\"meterStart\":1,\"reservationId\":1,\"chargeBoxSerialNumber\":{\"chargeBoxSerialNumber\":\"123456\"},\"timestamp\":1425289031076}";
        
        buf.erase();
        
        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            if( HTTPS_RECVED == httpspost.Recv(buf))
            {
                // cout<< "response: " << buf << endl;
            }
        }
        
        // meterValues
        url     = "http://183.131.144.74:8080/evchong_API/evchong/v1/meterValues";
        param   = "{\"connectorId\":1,\"transactionId\":1,\"chargeBoxSerialNumber\":{\"chargeBoxSerialNumber\":\"123456\"},\"values\":[{\"measurand\":\"Energy_Active_Import_Register\",\"unit\":\"Wh\",\"value\":\"xxxxx\",\"location\":\"Outlet\",\"context\":\"Sample_Periodic\",\"format\":\"Raw\",\"timestamp\":1425289652130}]}";
        
        buf.erase();
        
        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            if( HTTPS_RECVED == httpspost.Recv(buf))
            {
                // cout<< "response: " << buf << endl;
            }
        }
        
        // stopTrans
        url     = "http://183.131.144.74:8080/evchong_API/evchong/v1/stopTrans";
        param   = "{\"idTag\":{\"idToken\":\"123456\"},\"transactionId\":1,\"transactionData\":{\"values\":{\"measurand\":\"Energy_Active_Import_Register\",\"unit\":\"Wh\",\"value\":\"xxxxxx\",\"location\":\"Outlet\",\"context\":\"Sample_Periodic\",\"format\":\"Raw\",\"timestamp\":1425886218825}},\"chargeBoxSerialNumber\":{\"chargeBoxSerialNumber\":\"445566\"},\"meterStop\":1,\"timestamp\":1425886218829}";
        
        buf.erase();
        
        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            if( HTTPS_RECVED == httpspost.Recv(buf))
            {
                // cout<< "response: " << buf << endl;
            }
        }
        
        // statusNotify
        url     = "http://183.131.144.74:8080/evchong_API/evchong/v1/statusNotify";
        param   = "{\"connectorId\":1,\"vendorErrorCode\":\"1122\",\"chargeBoxSerialNumber\":{\"chargeBoxSerialNumber\":\"123456\"},\"errorCode\":\"GroundFailure\",\"vendorId\":\"4455\",\"info\":\"xxxxx\",\"timestamp\":1425290540330,\"status\":\"Available\"}";
        
        buf.erase();
        
        if( HTTPS_SENTED == httpspost.Send(url, param) )
        {
            if( HTTPS_RECVED == httpspost.Recv(buf))
            {
                // cout<< "response: " << buf << endl;
            }
        }
        

        httpspost.Close();
    }
    
}
#endif


    
}
示例#14
0
void* SSLServerThread::run()
{
	int						port = pcfg->getIntParam(SSL_PORT_PARAM,9001);
	std::string				cert = pcfg->getParam(SSL_CERT_PARAM);
	std::string				key = pcfg->getParam(SSL_KEY_PARAM);
	std::string				caFile = pcfg->getParam(SSL_CA_PARAM);
	std::string				caDir = pcfg->getParam(SSL_CA_DIR_PARAM);
	bool					require_cert = stricmp(pcfg->getParam(SSL_REQUIRE_CLIENT_CERT, "no").c_str(), "yes") == 0;
	std::string				address_list = pcfg->getParam(SSL_BIND_ADDRESS, "");
	AddressParser			ap(address_list);

	SSLSocket				client;
	X509Certificate*		pcert;

	X509Certificate			serverCert;
	PrivateKey				serverPkey;
	CertificateAuthority	ca(caFile, caDir);
	SSLContext				ctx;
	bool					trusted = false;
	std::string				user;

	if (serverCert.loadPEMFile(cert) != X509Certificate::noError) {
		Log::getLog()->Info("Unable to load the SSL server certificate, disabling SSL");
		return NULL;
	}

	if (serverPkey.loadPEMFile(key) != PrivateKey::noError) {
		Log::getLog()->Info("Unable to load the SSL server private key, disabling SSL");
		return NULL;
	}

	Log::getLog()->Info("Reporting SSL Identity as: %s", serverCert.getSubjectName().c_str());

	ctx.setPrivateKey(&serverPkey);
	ctx.setX509Certificate(&serverCert);
	ctx.setCertificateAuthority(&ca);
	ctx.enableVerification(require_cert); // TODO: Get a parameter to determine if client certificates are required
	ctx.setSessionID(SAFMQ_SESSION_ID, sizeof(SAFMQ_SESSION_ID)-1);

	if (port < 1)
		port = 9001;

	if (ap.addresses.size() == 0) {
		try {
			SSLServerSocket* svr = new SSLServerSocket(port,&ctx);
			servers.push_back(svr);
			Log::getLog()->Info("Starting SAFMQ Server at address safmqs://*:%ld", port);
		} catch (tcpsocket::SocketException e) {
			Log::getLog()->Info("Error:Binding Address: safmqs://*:%ld -- %s", port, e.what());
		}
	} else {
		for(AddressParser::AddressList::size_type x=0;x<ap.addresses.size();x++) {
			unsigned short tmpport;
			try {
				tmpport = (ap.addresses[x].port == 0xFFFF ) ? port : ap.addresses[x].port;

				SSLServerSocket* svr = new SSLServerSocket(tmpport, &ctx, ap.addresses[x].address);
				servers.push_back(svr);
				Log::getLog()->Info("Starting SAFMQ Server at address safmqs://%s:%ld", ap.addresses[x].name.c_str(),tmpport);
			} catch (tcpsocket::SocketException e) {
				Log::getLog()->Info("Error:Binding Address: safmqs://%s:%ld -- %s", ap.addresses[x].name.c_str(),tmpport, e.what());
			}
		}
	}

	try {
		std::list<SSLServerSocket*>	avail;
		tcpsocket::Selector<tcpsocket::SSLServerSocket>	selector;
		std::list<tcpsocket::SSLServerSocket*>::iterator	i;

		while (!m_bStop) {
			trusted = false;
			user = "";

			avail.clear();
			avail.assign(servers.begin(), servers.end());

			selector.selectReaders(avail);
			for(i = avail.begin(); !m_bStop && i != avail.end(); ++i) {
				client = (*i)->acceptConnection();
				Log::getLog()->Info("New conneciton accepted");
				
				// Force the connection negotiation, this will call verify()
				pcert = client.getPeerCertificate();
				Log::getLog()->Info("Peer certificate obtained 0x%lx", pcert);

				int res = client.getVerifyResult();
				Log::getLog()->Info("Peer Verify Result: %ld", res);

				if (pcert) {
					Log::getLog()->Info("Client Cert Issuer: %s", pcert->getIssuerName().c_str());
					Log::getLog()->Info("Client Cert Subject: %s", pcert->getSubjectName().c_str());
				} else {
					Log::getLog()->Info("SSLServerThread::run()-pcert: %p", pcert);
				}

				// determine if a trusted user certificate has been presented
				if (res == X509_V_OK && pcert) {
					trusted = (SecurityControl::getSecurityControl()->identifyUser(pcert->getSubjectName(), pcert->getIssuerName(), user) == SecurityControl::GRANTED);
				} 
				Log::getLog()->Info("Certificate Trusted: %ld require_cert: %ld", trusted, require_cert);			

	
				if (require_cert && (res != X509_V_OK || !pcert) ) {
					// reject the client certificate not allowed
					// since valid certificates are required, enforce the requirement

					struct sockaddr_in	peername;

					client.getPeerName(&peername);
					Log::getLog()->SignOn(Log::error, "Digital Certificate", &peername, EC_Decode(EC_NOTAUTHORIZED));
					if (pcert) {
						Log::getLog()->Info("X509 Cert rejected, subject: %s -- reason: %s",
							pcert->getSubjectName().c_str(), X509_verify_cert_error_string(res));
					}
					client.close();
				} else {
					Log::getLog()->Info("Establishing a connection with client user:%s", user.c_str());

					// Establis a connection for the user
					socstream *stm = new tcpsocket::socstream(client);
					ServiceThread *thd = new ServiceThread(stm,trusted,user);
					thd->start();
				}

				if (pcert) delete pcert;
			}
		}
	} catch (tcpsocket::SocketException e) {
		Log::getLog()->Info("SSLServer exception: %s", e.what());
	}

	return NULL;
}