mirror of
https://github.com/eclipse/paho.mqtt-sn.embedded-c.git
synced 2025-12-13 23:46:51 +01:00
Update: indivisual client assigns TLS connection by clients.conf file.
BugFix: TLS certificate required connection error Signed-off-by: tomoaki <tomoaki@tomy-tech.com>
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "MQTTGWPacket.h"
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
|
||||
using namespace MQTTSNGW;
|
||||
|
||||
|
||||
@@ -89,7 +89,6 @@ void BrokerRecvTask::run(void)
|
||||
{
|
||||
/* Check sockets is ready to read */
|
||||
int activity = select(maxSock + 1, &rset, 0, 0, &timeout);
|
||||
|
||||
if (activity > 0)
|
||||
{
|
||||
client = _gateway->getClientList()->getClient();
|
||||
@@ -110,6 +109,7 @@ void BrokerRecvTask::run(void)
|
||||
if ( rc > 0 )
|
||||
{
|
||||
if ( log(client, packet) == -1 )
|
||||
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -169,7 +169,7 @@ void BrokerRecvTask::run(void)
|
||||
*/
|
||||
int BrokerRecvTask::log(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
char pbuf[(SIZEOF_LOG_PACKET + 5 )* 3];
|
||||
char pbuf[(SIZE_OF_LOG_PACKET + 5 )* 3];
|
||||
char msgId[6];
|
||||
int rc = 0;
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "MQTTSNGateway.h"
|
||||
#include "MQTTSNGWClient.h"
|
||||
#include "MQTTGWPacket.h"
|
||||
#include <string.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace MQTTSNGW;
|
||||
@@ -34,8 +35,11 @@ BrokerSendTask::BrokerSendTask(Gateway* gateway)
|
||||
_gateway = gateway;
|
||||
_gateway->attach((Thread*)this);
|
||||
_host = 0;
|
||||
_service = 0;
|
||||
_serviceSecure = 0;
|
||||
_port = 0;
|
||||
_portSecure = 0;
|
||||
_certDirectory = 0;
|
||||
_rootCAfile = 0;
|
||||
|
||||
_light = 0;
|
||||
}
|
||||
|
||||
@@ -45,13 +49,25 @@ BrokerSendTask::~BrokerSendTask()
|
||||
{
|
||||
free(_host);
|
||||
}
|
||||
if (_service)
|
||||
if (_port)
|
||||
{
|
||||
free(_service);
|
||||
free(_port);
|
||||
}
|
||||
if (_serviceSecure)
|
||||
if (_portSecure)
|
||||
{
|
||||
free(_serviceSecure);
|
||||
free(_portSecure);
|
||||
}
|
||||
if (_certDirectory)
|
||||
{
|
||||
free(_certDirectory);
|
||||
}
|
||||
if (_rootCApath)
|
||||
{
|
||||
free(_rootCApath);
|
||||
}
|
||||
if (_rootCAfile)
|
||||
{
|
||||
free(_rootCAfile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,12 +84,26 @@ void BrokerSendTask::initialize(int argc, char** argv)
|
||||
}
|
||||
if (_gateway->getParam("BrokerPortNo", param) == 0)
|
||||
{
|
||||
_service = strdup(param);
|
||||
_port = strdup(param);
|
||||
}
|
||||
if (_gateway->getParam("BrokerSecurePortNo", param) == 0)
|
||||
{
|
||||
_serviceSecure = strdup(param);
|
||||
}
|
||||
{
|
||||
_portSecure = strdup(param);
|
||||
}
|
||||
|
||||
if (_gateway->getParam("CertsDirectory", param) == 0)
|
||||
{
|
||||
_certDirectory = strdup(param);
|
||||
}
|
||||
if (_gateway->getParam("RootCApath", param) == 0)
|
||||
{
|
||||
_rootCApath = strdup(param);
|
||||
}
|
||||
if (_gateway->getParam("RootCAfile", param) == 0)
|
||||
{
|
||||
_rootCAfile = strdup(param);
|
||||
}
|
||||
|
||||
_light = _gateway->getLightIndicator();
|
||||
}
|
||||
|
||||
@@ -93,7 +123,7 @@ void BrokerSendTask::run()
|
||||
client = ev->getClient();
|
||||
packet = ev->getMQTTGWPacket();
|
||||
|
||||
if ( client->getNetwork()->isValid() && packet->getType() == CONNECT )
|
||||
if ( client->getNetwork()->isValid() && !client->getNetwork()->isSecure() && packet->getType() == CONNECT )
|
||||
{
|
||||
client->getNetwork()->close();
|
||||
}
|
||||
@@ -101,16 +131,37 @@ void BrokerSendTask::run()
|
||||
if ( !client->getNetwork()->isValid() )
|
||||
{
|
||||
/* connect to the broker and send a packet */
|
||||
char* service = _service;
|
||||
char* portNo = _port;
|
||||
const char* cert = 0;
|
||||
const char* keyFile = 0;
|
||||
string certFile;
|
||||
string privateKeyFile;
|
||||
|
||||
if (client->isSecureNetwork())
|
||||
{
|
||||
service = _serviceSecure;
|
||||
portNo = _portSecure;
|
||||
if ( _certDirectory )
|
||||
{
|
||||
certFile = _certDirectory;
|
||||
certFile += client->getClientId();
|
||||
certFile += ".crt";
|
||||
cert = certFile.c_str();
|
||||
privateKeyFile = _certDirectory;
|
||||
privateKeyFile += client->getClientId();
|
||||
privateKeyFile += ".key";
|
||||
keyFile = privateKeyFile.c_str();
|
||||
}
|
||||
rc = client->getNetwork()->connect(_host, portNo, _rootCApath, _rootCAfile, cert, keyFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = client->getNetwork()->connect(_host, portNo);
|
||||
}
|
||||
|
||||
if ( !client->getNetwork()->connect(_host, service) )
|
||||
if ( !rc )
|
||||
{
|
||||
/* disconnect the broker and chage the client's status */
|
||||
WRITELOG("%s BrokerSendTask can't open the socket. errno=%d %s%s\n",
|
||||
/* disconnect the broker and change the client's status */
|
||||
WRITELOG("%s BrokerSendTask can't connect to the broker. errno=%d %s%s\n",
|
||||
ERRMSG_HEADER, rc == -1 ? errno : 0, client->getClientId(), ERRMSG_FOOTER);
|
||||
client->disconnected();
|
||||
client->getNetwork()->disconnect();
|
||||
@@ -151,7 +202,7 @@ void BrokerSendTask::run()
|
||||
*/
|
||||
void BrokerSendTask::log(Client* client, MQTTGWPacket* packet)
|
||||
{
|
||||
char pbuf[(SIZEOF_LOG_PACKET + 5 )* 3];
|
||||
char pbuf[(SIZE_OF_LOG_PACKET + 5 )* 3];
|
||||
char msgId[6];
|
||||
|
||||
switch (packet->getType())
|
||||
|
||||
@@ -39,8 +39,11 @@ private:
|
||||
|
||||
Gateway* _gateway;
|
||||
char* _host;
|
||||
char* _service;
|
||||
char* _serviceSecure;
|
||||
char* _port;
|
||||
char* _portSecure;
|
||||
char* _rootCApath;
|
||||
char* _rootCAfile;
|
||||
char* _certDirectory;
|
||||
LightIndicator* _light;
|
||||
};
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@ Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
|
||||
}
|
||||
|
||||
/* anonimous clients */
|
||||
if ( _clientCnt > DEFAULT_MAX_CLIENTS )
|
||||
if ( _clientCnt > MAX_CLIENTS )
|
||||
{
|
||||
return 0; // full of clients
|
||||
}
|
||||
@@ -951,14 +951,7 @@ TopicIdMapelement::~TopicIdMapelement()
|
||||
|
||||
TopicIdMap::TopicIdMap()
|
||||
{
|
||||
char param[MQTTSNGW_PARAM_MAX];
|
||||
|
||||
_maxInflight = DEFAULT_INFLIGHTMESSAGE;
|
||||
if ( theProcess->getParam("MaxInflightMsg", param) == 0 )
|
||||
{
|
||||
_maxInflight = atoi(param);
|
||||
}
|
||||
|
||||
_maxInflight = MAX_INFLIGHTMESSAGES;
|
||||
_msgIds = 0;
|
||||
_first = 0;
|
||||
_end = 0;
|
||||
|
||||
@@ -312,7 +312,7 @@ private:
|
||||
uint8_t _snMsgId;
|
||||
|
||||
Network* _network; // Broker
|
||||
bool _secureNetwork; // SSL
|
||||
bool _secureNetwork; // SSL
|
||||
bool _sensorNetype; // false: unstable network like a G3
|
||||
SensorNetAddress _sensorNetAddr;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "MQTTSNGWClientRecvTask.h"
|
||||
#include "MQTTSNGateway.h"
|
||||
#include <string.h>
|
||||
char* currentDateTime(void);
|
||||
/*=====================================
|
||||
Class ClientRecvTask
|
||||
@@ -107,7 +108,7 @@ void ClientRecvTask::run()
|
||||
packet->getCONNECT(&data);
|
||||
|
||||
/* create a client */
|
||||
client = _gateway->getClientList()->createClient(_sensorNetwork->getSenderAddress(), &data.clientID, false, _gateway->getGWParams()->secureConnection);
|
||||
client = _gateway->getClientList()->createClient(_sensorNetwork->getSenderAddress(), &data.clientID, false, false); //_gateway->getGWParams()->secureConnection);
|
||||
|
||||
if (!client)
|
||||
{
|
||||
@@ -139,7 +140,7 @@ void ClientRecvTask::run()
|
||||
|
||||
void ClientRecvTask::log(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
char pbuf[SIZEOF_LOG_PACKET * 3];
|
||||
char pbuf[SIZE_OF_LOG_PACKET * 3];
|
||||
char msgId[6];
|
||||
const char* clientId = client ? (const char*)client->getClientId() :"Non Active Client !" ;
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ void ClientSendTask::run()
|
||||
|
||||
void ClientSendTask::log(Client* client, MQTTSNPacket* packet)
|
||||
{
|
||||
char pbuf[SIZEOF_LOG_PACKET * 3];
|
||||
char pbuf[SIZE_OF_LOG_PACKET * 3];
|
||||
char msgId[6];
|
||||
|
||||
switch (packet->getType())
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "MQTTSNGateway.h"
|
||||
#include "MQTTSNGWPacket.h"
|
||||
#include "MQTTGWPacket.h"
|
||||
#include <string.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace MQTTSNGW;
|
||||
@@ -54,7 +55,7 @@ void MQTTSNConnectionHandler::handleSearchgw(MQTTSNPacket* packet)
|
||||
{
|
||||
if (packet->getType() == MQTTSN_SEARCHGW)
|
||||
{
|
||||
if (_gateway->getClientList()->getClientCount() < DEFAULT_MAX_CLIENTS)
|
||||
if (_gateway->getClientList()->getClientCount() < MAX_CLIENTS)
|
||||
{
|
||||
MQTTSNPacket* gwinfo = new MQTTSNPacket();
|
||||
gwinfo->setGWINFO(_gateway->getGWParams()->gatewayId);
|
||||
|
||||
@@ -27,13 +27,13 @@ namespace MQTTSNGW
|
||||
//#define DEBUG_NWSTACK // print out SensorNetwork log
|
||||
|
||||
/*=================================
|
||||
* Parametrs
|
||||
* MQTT-SN Parametrs
|
||||
==================================*/
|
||||
#define MAX_CLIENTS (100) // Number of Clients can be handled.
|
||||
#define MAX_CLIENTID_LENGTH (64) // Max length of clientID
|
||||
#define MAX_INFLIGHTMESSAGES (10) // Number of inflight messages
|
||||
#define MQTTSNGW_MAX_PACKET_SIZE (1024) // Max Packet size (5+2+TopicLen+PayloadLen)
|
||||
#define SIZEOF_LOG_PACKET (500) // Length of the packet log in bytes
|
||||
|
||||
#define MQTTSNGW_TLS_CA_DIR "/etc/ssl/certs"
|
||||
#define SIZE_OF_LOG_PACKET (500) // Length of the packet log in bytes
|
||||
|
||||
/*=================================
|
||||
* Data Type
|
||||
|
||||
@@ -354,7 +354,7 @@ char* MQTTSNPacket::print(char* pbuf)
|
||||
int value = 0;
|
||||
|
||||
int i = MQTTSNPacket_decode(_buf, _bufLen, &value);
|
||||
int size = _bufLen > SIZEOF_LOG_PACKET ? SIZEOF_LOG_PACKET : _bufLen;
|
||||
int size = _bufLen > SIZE_OF_LOG_PACKET ? SIZE_OF_LOG_PACKET : _bufLen;
|
||||
|
||||
for (; i < size; i++)
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "MQTTSNGWConnectionHandler.h"
|
||||
#include "MQTTSNGWPublishHandler.h"
|
||||
#include "MQTTSNGWSubscribeHandler.h"
|
||||
#include <string.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace MQTTSNGW;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "MQTTGWPacket.h"
|
||||
#include "MQTTSNGateway.h"
|
||||
#include "MQTTSNGWClient.h"
|
||||
|
||||
#include <string.h>
|
||||
using namespace std;
|
||||
using namespace MQTTSNGW;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "MQTTSNGateway.h"
|
||||
#include "SensorNetwork.h"
|
||||
#include "MQTTSNGWProcess.h"
|
||||
|
||||
#include <string.h>
|
||||
using namespace MQTTSNGW;
|
||||
|
||||
char* currentDateTime(void);
|
||||
@@ -31,7 +31,7 @@ Gateway::Gateway()
|
||||
theProcess = this;
|
||||
_params.loginId = 0;
|
||||
_params.password = 0;
|
||||
_packetEventQue.setMaxSize(DEFAULT_INFLIGHTMESSAGE * DEFAULT_MAX_CLIENTS);
|
||||
_packetEventQue.setMaxSize(MAX_INFLIGHTMESSAGES * MAX_CLIENTS);
|
||||
}
|
||||
|
||||
Gateway::~Gateway()
|
||||
@@ -107,7 +107,7 @@ void Gateway::initialize(int argc, char** argv)
|
||||
string fileName;
|
||||
if (!strcasecmp(param, "YES"))
|
||||
{
|
||||
if (getParam("ClientList", param) == 0)
|
||||
if (getParam("ClientsList", param) == 0)
|
||||
{
|
||||
fileName = string(param);
|
||||
}
|
||||
@@ -118,20 +118,10 @@ void Gateway::initialize(int argc, char** argv)
|
||||
|
||||
if (!_clientList.authorize(fileName.c_str()))
|
||||
{
|
||||
throw Exception("Gateway::initialize: No client list which defined by configuration.");
|
||||
throw Exception("Gateway::initialize: No client list defined by configuration.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getParam("SecureConnection", param) == 0)
|
||||
{
|
||||
_params.secureConnection = !strcasecmp(param, "YES");
|
||||
}
|
||||
else
|
||||
{
|
||||
_params.secureConnection = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Gateway::run(void)
|
||||
|
||||
@@ -26,14 +26,12 @@ namespace MQTTSNGW
|
||||
* Gateway default parameters
|
||||
===========================================================*/
|
||||
#define DEFAULT_KEEP_ALIVE_TIME (900) // 900 secs = 15 mins
|
||||
#define DEFAULT_MAX_CLIENTS (100) // Number of Clients can be handled.
|
||||
#define DEFAULT_MQTT_VERSION (4) // Defualt MQTT version
|
||||
#define DEFAULT_INFLIGHTMESSAGE (10) // Number of inflight messages
|
||||
|
||||
/*=================================
|
||||
* Starting prompt
|
||||
==================================*/
|
||||
#define GATEWAY_VERSION " * Version: 0.3.3"
|
||||
#define GATEWAY_VERSION " * Version: 0.4.0"
|
||||
|
||||
#define PAHO_COPYRIGHT0 " * MQTT-SN Transparent Gateway"
|
||||
#define PAHO_COPYRIGHT1 " * Part of Project Paho in Eclipse"
|
||||
@@ -155,7 +153,6 @@ typedef struct
|
||||
uint8_t mqttVersion;
|
||||
uint16_t maxInflightMsgs;
|
||||
uint8_t* gatewayName;
|
||||
bool secureConnection;
|
||||
}GatewayParams;
|
||||
|
||||
/*=====================================
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <error.h>
|
||||
#include <regex>
|
||||
|
||||
#include "Network.h"
|
||||
#include "MQTTSNGWDefines.h"
|
||||
@@ -232,54 +233,27 @@ int TCPStack::getSock()
|
||||
=======================================*/
|
||||
int Network::_numOfInstance = 0;
|
||||
SSL_CTX* Network::_ctx = 0;
|
||||
SSL_SESSION* Network::_session = 0;
|
||||
|
||||
Network::Network(bool secure) :
|
||||
TCPStack()
|
||||
{
|
||||
char error[256];
|
||||
if (secure)
|
||||
{
|
||||
_numOfInstance++;
|
||||
if (_ctx == 0)
|
||||
{
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
_ctx = SSL_CTX_new(TLSv1_2_client_method());
|
||||
if (_ctx == 0)
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), error, sizeof(error));
|
||||
WRITELOG("SSL_CTX_new() %s\n", error);
|
||||
throw Exception( ERR_get_error(), "Network can't create SSL context.");
|
||||
}
|
||||
if (!SSL_CTX_load_verify_locations(_ctx, 0, MQTTSNGW_TLS_CA_DIR))
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), error, sizeof(error));
|
||||
WRITELOG("SSL_CTX_load_verify_locations() %s\n", error);
|
||||
throw Exception( ERR_get_error(), "Network can't load CA_LIST.");
|
||||
}
|
||||
}
|
||||
}
|
||||
_ssl = 0;
|
||||
_disconReq = false;
|
||||
_secureFlg = secure;
|
||||
_busy = false;
|
||||
_session = 0;
|
||||
_sslValid = false;
|
||||
}
|
||||
|
||||
Network::~Network()
|
||||
{
|
||||
if (_secureFlg)
|
||||
{
|
||||
_numOfInstance--;
|
||||
}
|
||||
if (_ssl)
|
||||
{
|
||||
SSL_free(_ssl);
|
||||
_numOfInstance--;
|
||||
}
|
||||
if (_session && _numOfInstance == 0)
|
||||
if (_session )
|
||||
{
|
||||
SSL_SESSION_free(_session);
|
||||
_session = 0;
|
||||
}
|
||||
if (_ctx && _numOfInstance == 0)
|
||||
{
|
||||
@@ -289,78 +263,172 @@ Network::~Network()
|
||||
}
|
||||
}
|
||||
|
||||
bool Network::connect(const char* host, const char* service)
|
||||
bool Network::connect(const char* host, const char* port)
|
||||
{
|
||||
if (_secureFlg)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getSock() == 0)
|
||||
{
|
||||
if (!TCPStack::connect(host, port))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Network::connect(const char* host, const char* port, const char* caPath, const char* caFile, const char* cert, const char* prvkey)
|
||||
{
|
||||
char errmsg[256];
|
||||
int rc = 0;
|
||||
char peer_CN[256];
|
||||
SSL_SESSION* sess = 0;
|
||||
X509* peer;
|
||||
int rc = 0;
|
||||
|
||||
if (isValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!TCPStack::connect(host, service))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!_secureFlg)
|
||||
{
|
||||
return true;
|
||||
WRITELOG("TLS is not required.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
SSL* ssl = SSL_new(_ctx);
|
||||
if (ssl == 0)
|
||||
if (_ctx == 0)
|
||||
{
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
_ctx = SSL_CTX_new(TLS_client_method());
|
||||
if (_ctx == 0)
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
WRITELOG("SSL_CTX_new() %s\n", errmsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SSL_CTX_load_verify_locations(_ctx, caFile, caPath))
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
WRITELOG("SSL_CTX_load_verify_locations() %s\n", errmsg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_sslValid)
|
||||
{
|
||||
if ( !TCPStack::connect(host, port) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
if ( _ssl )
|
||||
{
|
||||
if (!SSL_set_fd(_ssl, getSock()))
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
WRITELOG("SSL_set_fd() %s\n", errmsg);
|
||||
SSL_free(_ssl);
|
||||
}
|
||||
else
|
||||
{
|
||||
_sslValid = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
_ssl = SSL_new(_ctx);
|
||||
if (_ssl == 0)
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
WRITELOG("SSL_new() %s\n", errmsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
rc = SSL_set_fd(ssl, TCPStack::getSock());
|
||||
if (rc == 0)
|
||||
if (!SSL_set_fd(_ssl, getSock()))
|
||||
{
|
||||
SSL_free(ssl);
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
WRITELOG("SSL_set_fd() %s\n", errmsg);
|
||||
SSL_free(_ssl);
|
||||
}
|
||||
|
||||
SSL_set_options(_ssl, SSL_OP_NO_TICKET);
|
||||
|
||||
if ( cert )
|
||||
{
|
||||
if ( SSL_use_certificate_file(_ssl, cert, SSL_FILETYPE_PEM) <= 0 )
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
WRITELOG("SSL_use_certificate_file() %s %s\n", cert, errmsg);
|
||||
SSL_free(_ssl);
|
||||
_ssl = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( prvkey )
|
||||
{
|
||||
if ( SSL_use_PrivateKey_file(_ssl, prvkey, SSL_FILETYPE_PEM) <= 0 )
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
WRITELOG("SSL_use_PrivateKey_file() %s %s\n", prvkey, errmsg);
|
||||
SSL_free(_ssl);
|
||||
_ssl = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SSL_set_fd(_ssl, TCPStack::getSock()))
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
WRITELOG("SSL_set_fd() %s\n", errmsg);
|
||||
SSL_free(_ssl);
|
||||
_ssl = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_session)
|
||||
{
|
||||
rc = SSL_set_session(ssl, sess);
|
||||
rc = SSL_set_session(_ssl, _session);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = SSL_connect(ssl);
|
||||
}
|
||||
if (rc != 1)
|
||||
|
||||
if (SSL_connect(_ssl) != 1)
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
WRITELOG("SSL_connect() %s\n", errmsg);
|
||||
SSL_free(ssl);
|
||||
SSL_free(_ssl);
|
||||
_ssl = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SSL_get_verify_result(ssl) != X509_V_OK)
|
||||
if ( (rc = SSL_get_verify_result(_ssl)) != X509_V_OK)
|
||||
{
|
||||
WRITELOG("SSL_get_verify_result() error: Certificate doesn't verify.\n");
|
||||
SSL_free(ssl);
|
||||
WRITELOG("SSL_get_verify_result() error: %s.\n", X509_verify_cert_error_string(rc));
|
||||
SSL_free(_ssl);
|
||||
_ssl = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
peer = SSL_get_peer_certificate(ssl);
|
||||
X509* peer = SSL_get_peer_certificate(_ssl);
|
||||
X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, peer_CN, 256);
|
||||
if (strcasecmp(peer_CN, host))
|
||||
char* pos = peer_CN;
|
||||
if ( *pos == '*')
|
||||
{
|
||||
WRITELOG("SSL_get_peer_certificate() error: Broker dosen't much host name.\n");
|
||||
SSL_free(ssl);
|
||||
while (*host++ != '.');
|
||||
pos += 2;
|
||||
}
|
||||
if ( strcmp(host, pos))
|
||||
{
|
||||
WRITELOG("SSL_get_peer_certificate() error: Broker %s dosen't match the host name %s\n", peer_CN, host);
|
||||
SSL_free(_ssl);
|
||||
_ssl = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_session == 0)
|
||||
{
|
||||
_session = sess;
|
||||
_session = SSL_get1_session(_ssl);
|
||||
}
|
||||
_ssl = ssl;
|
||||
_numOfInstance++;
|
||||
_sslValid = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -372,7 +440,11 @@ int Network::send(const uint8_t* buf, uint16_t length)
|
||||
bool writeBlockedOnRead = false;
|
||||
int bpos = 0;
|
||||
|
||||
if (_secureFlg)
|
||||
if (!_secureFlg)
|
||||
{
|
||||
return TCPStack::send(buf, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mutex.lock();
|
||||
_busy = true;
|
||||
@@ -387,7 +459,7 @@ int Network::send(const uint8_t* buf, uint16_t length)
|
||||
int activity = select(getSock() + 1, &rset, &wset, 0, 0);
|
||||
if (activity > 0)
|
||||
{
|
||||
if (FD_ISSET(getSock(), &wset) || (writeBlockedOnRead && FD_ISSET(getSock(), &rset)))
|
||||
if (FD_ISSET(getSock(), &wset) || (writeBlockedOnRead && FD_ISSET(getSock(), &rset)))
|
||||
{
|
||||
|
||||
writeBlockedOnRead = false;
|
||||
@@ -421,10 +493,6 @@ int Network::send(const uint8_t* buf, uint16_t length)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return TCPStack::send(buf, length);
|
||||
}
|
||||
}
|
||||
|
||||
int Network::recv(uint8_t* buf, uint16_t len)
|
||||
@@ -438,92 +506,107 @@ int Network::recv(uint8_t* buf, uint16_t len)
|
||||
fd_set rset;
|
||||
fd_set wset;
|
||||
|
||||
if (_secureFlg)
|
||||
if (!_secureFlg)
|
||||
{
|
||||
if (_busy)
|
||||
return TCPStack::recv(buf, len);
|
||||
}
|
||||
|
||||
if (_busy)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
_mutex.lock();
|
||||
_busy = true;
|
||||
|
||||
loop: do
|
||||
{
|
||||
readBlockedOnWrite = false;
|
||||
readBlocked = false;
|
||||
|
||||
rlen = SSL_read(_ssl, buf + bpos, len - bpos);
|
||||
|
||||
switch (SSL_get_error(_ssl, rlen))
|
||||
{
|
||||
return 0;
|
||||
case SSL_ERROR_NONE:
|
||||
_busy = false;
|
||||
_mutex.unlock();
|
||||
return rlen + bpos;
|
||||
break;
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
SSL_shutdown(_ssl);
|
||||
_ssl = 0;
|
||||
TCPStack::close();
|
||||
_busy = false;
|
||||
_mutex.unlock();
|
||||
return -1;
|
||||
break;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
readBlocked = true;
|
||||
break;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
readBlockedOnWrite = true;
|
||||
break;
|
||||
default:
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
WRITELOG("Network::recv() %s\n", errmsg);
|
||||
_busy = false;
|
||||
_mutex.unlock();
|
||||
return -1;
|
||||
}
|
||||
_mutex.lock();
|
||||
_busy = true;
|
||||
} while (SSL_pending(_ssl) && !readBlocked);
|
||||
|
||||
loop: do
|
||||
bpos += rlen;
|
||||
while (true)
|
||||
{
|
||||
FD_ZERO(&rset);
|
||||
FD_ZERO(&wset);
|
||||
FD_SET(getSock(), &rset);
|
||||
FD_SET(getSock(), &wset);
|
||||
|
||||
int activity = select(getSock() + 1, &rset, &wset, 0, 0);
|
||||
if (activity > 0)
|
||||
{
|
||||
readBlockedOnWrite = false;
|
||||
readBlocked = false;
|
||||
|
||||
rlen = SSL_read(_ssl, buf + bpos, len - bpos);
|
||||
|
||||
switch (SSL_get_error(_ssl, rlen))
|
||||
if ((FD_ISSET(getSock(),&rset) && !writeBlockedOnRead)
|
||||
|| (readBlockedOnWrite && FD_ISSET(getSock(), &wset)))
|
||||
{
|
||||
case SSL_ERROR_NONE:
|
||||
_busy = false;
|
||||
_mutex.unlock();
|
||||
return rlen + bpos;
|
||||
break;
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
SSL_shutdown(_ssl);
|
||||
_ssl = 0;
|
||||
TCPStack::close();
|
||||
_busy = false;
|
||||
_mutex.unlock();
|
||||
return -1;
|
||||
break;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
readBlocked = true;
|
||||
break;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
readBlockedOnWrite = true;
|
||||
break;
|
||||
default:
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
WRITELOG("TLSStack::recv() default %s\n", errmsg);
|
||||
_busy = false;
|
||||
_mutex.unlock();
|
||||
return -1;
|
||||
goto loop;
|
||||
}
|
||||
} while (SSL_pending(_ssl) && !readBlocked);
|
||||
|
||||
bpos += rlen;
|
||||
while (true)
|
||||
}
|
||||
else
|
||||
{
|
||||
FD_ZERO(&rset);
|
||||
FD_ZERO(&wset);
|
||||
FD_SET(getSock(), &rset);
|
||||
FD_SET(getSock(), &wset);
|
||||
|
||||
int activity = select(getSock() + 1, &rset, &wset, 0, 0);
|
||||
if (activity > 0)
|
||||
{
|
||||
if ((FD_ISSET(getSock(),&rset) && !writeBlockedOnRead)
|
||||
|| (readBlockedOnWrite && FD_ISSET(getSock(), &wset)))
|
||||
{
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
WRITELOG("TLSStack::recv() select %s\n", errmsg);
|
||||
_busy = false;
|
||||
_mutex.unlock();
|
||||
return -1;
|
||||
}
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
WRITELOG("TLSStack::recv() select %s\n", errmsg);
|
||||
_busy = false;
|
||||
_mutex.unlock();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return TCPStack::recv(buf, len);
|
||||
}
|
||||
|
||||
void Network::close(void)
|
||||
{
|
||||
if (_secureFlg)
|
||||
{
|
||||
_sslValid = false;
|
||||
SSL_free(_ssl);
|
||||
_ssl = 0;
|
||||
}
|
||||
TCPStack::close();
|
||||
}
|
||||
|
||||
bool Network::isValid()
|
||||
{
|
||||
if (!_secureFlg)
|
||||
if (_secureFlg)
|
||||
{
|
||||
if (_sslValid && !_busy)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return TCPStack::isValid();
|
||||
}
|
||||
if (_ssl)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -533,12 +616,11 @@ void Network::disconnect()
|
||||
{
|
||||
SSL_shutdown(_ssl);
|
||||
_ssl = 0;
|
||||
TCPStack::close();
|
||||
}
|
||||
else
|
||||
{
|
||||
TCPStack::close();
|
||||
}
|
||||
_sslValid = false;
|
||||
_busy = false;
|
||||
TCPStack::close();
|
||||
|
||||
}
|
||||
|
||||
int Network::getSock()
|
||||
@@ -546,18 +628,6 @@ int Network::getSock()
|
||||
return TCPStack::getSock();
|
||||
}
|
||||
|
||||
SSL* Network::getSSL()
|
||||
{
|
||||
if (_secureFlg)
|
||||
{
|
||||
return _ssl;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool Network::isSecure()
|
||||
{
|
||||
return _secureFlg;
|
||||
|
||||
@@ -71,26 +71,27 @@ public:
|
||||
Network(bool secure);
|
||||
virtual ~Network();
|
||||
|
||||
bool connect(const char* host, const char* service);
|
||||
void disconnect();
|
||||
int send(const uint8_t* buf, uint16_t length);
|
||||
int recv(uint8_t* buf, uint16_t len);
|
||||
bool connect(const char* host, const char* port, const char* caPath, const char* caFile, const char* sert, const char* prvkey);
|
||||
bool connect(const char* host, const char* port);
|
||||
void disconnect(void);
|
||||
void close(void);
|
||||
int send(const uint8_t* buf, uint16_t length);
|
||||
int recv(uint8_t* buf, uint16_t len);
|
||||
|
||||
bool isValid();
|
||||
bool isSecure();
|
||||
int getSock();
|
||||
SSL* getSSL();
|
||||
bool isValid(void);
|
||||
bool isSecure(void);
|
||||
int getSock(void);
|
||||
|
||||
private:
|
||||
static SSL_CTX* _ctx;
|
||||
static int _numOfInstance;
|
||||
static SSL_SESSION* _session;
|
||||
|
||||
SSL_SESSION* _session;
|
||||
SSL* _ssl;
|
||||
bool _secureFlg;
|
||||
bool _disconReq;
|
||||
Mutex _mutex;
|
||||
bool _busy;
|
||||
bool _sslValid;
|
||||
};
|
||||
|
||||
#endif /* NETWORK_H_ */
|
||||
|
||||
@@ -24,9 +24,6 @@ using namespace MQTTSNGW;
|
||||
|
||||
/*
|
||||
* Gateway Process
|
||||
*
|
||||
* Certificate file "/etc/ssl/certs"
|
||||
* This is defined in MQTTSNGWDefines.h
|
||||
*/
|
||||
Gateway* gateway = new Gateway();
|
||||
PacketHandleTask* t0 = new PacketHandleTask(gateway);
|
||||
|
||||
Reference in New Issue
Block a user