// 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()); }
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; }
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; }
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(); }
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(); } }
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; }
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]; } }
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; }
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); }
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 }
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; }