mirror of
https://github.com/eclipse/paho.mqtt-sn.embedded-c.git
synced 2025-12-13 15:36: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:
@@ -28,11 +28,14 @@ $ ./MQTT-SNGateway [-f Config file name]
|
||||
|
||||
BrokerName=iot.eclipse.org
|
||||
BrokerPortNo=1883
|
||||
SecureConnection=NO
|
||||
#BrokerPortNo=8883
|
||||
#SecureConnection=YES
|
||||
BrokerSecurePortNo=8883
|
||||
|
||||
ClientAuthentication=NO
|
||||
ClientList=clients.conf
|
||||
#ClientsList=/path/to/your_clients.conf
|
||||
|
||||
RootCAfile=/path/to/your_Root_CA.crt
|
||||
RootCApath=/path/to/your_certs_directory/
|
||||
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
KeepAlive=900
|
||||
@@ -49,12 +52,12 @@ Baudrate=38400
|
||||
SerialDevice=/dev/ttyUSB0
|
||||
```
|
||||
|
||||
**BrokerName** to specify a domain name of the Broker, and **BrokerPortNo** is a port No of the Broker. If the Broker have to connected via TLS, set BrokerPortNo=8883 and **SecureConnection=YES**.
|
||||
**BrokerName** to specify a domain name of the Broker, and **BrokerPortNo** is a port No of the Broker. **BrokerSecurePortNo** is for TLS connection.
|
||||
**MulticastIP** and **MulticastPortNo** is a multicast address for ADVERTISE, GWSEARCH and GWINFO messages. Gateway is waiting GWSEARCH multicast message and when receiving it send GWINFO message via Broadcast address. Clients can get the gateway address (Gateway IP address and **GatewayPortNo**) from GWINFO message by means of std::recvfrom(),
|
||||
Client should know the BroadcastIP and PortNo to send a SEARCHGW message.
|
||||
**GatewayId** is defined by GWSEARCH message.
|
||||
**KeepAlive** is a duration of ADVERTISE message in seconds.
|
||||
when **ClientAuthentication** is YES, see MQTTSNGWClient.cpp line53, clients file specified by ClientList is required. This file defines connect allowed clients by ClientId, IPaddress and PortNo.
|
||||
when **ClientAuthentication** is YES, see MQTTSNGWClient.cpp line53, clients file specified by ClientsList is required. This file defines connect allowed clients by ClientId, IPaddress and PortNo.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -16,14 +16,18 @@
|
||||
BrokerName=iot.eclipse.org
|
||||
BrokerPortNo=1883
|
||||
BrokerSecurePortNo=8883
|
||||
#SecureConnection=YES
|
||||
|
||||
ClientAuthentication=NO
|
||||
ClientList=clients.conf
|
||||
#ClientsList=/path/to/your_clients.conf
|
||||
|
||||
RootCAfile=/usr/share/ca-certificates/ISRG_Root_X1.crt
|
||||
RootCApath=/etc/ssl/certs/
|
||||
|
||||
GatewayID=1
|
||||
GatewayName=PahoGateway-01
|
||||
KeepAlive=900
|
||||
#LoginID=
|
||||
#Password=
|
||||
#LoginID=your_ID
|
||||
#Password=your_Password
|
||||
|
||||
# UDP
|
||||
GatewayPortNo=10000
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
char errmsg[256];
|
||||
int rc = 0;
|
||||
char peer_CN[256];
|
||||
SSL_SESSION* sess = 0;
|
||||
X509* peer;
|
||||
if (_secureFlg)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isValid())
|
||||
if (getSock() == 0)
|
||||
{
|
||||
if (!TCPStack::connect(host, port))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!TCPStack::connect(host, service))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!_secureFlg)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
SSL* ssl = SSL_new(_ctx);
|
||||
if (ssl == 0)
|
||||
bool Network::connect(const char* host, const char* port, const char* caPath, const char* caFile, const char* cert, const char* prvkey)
|
||||
{
|
||||
char errmsg[256];
|
||||
char peer_CN[256];
|
||||
int rc = 0;
|
||||
|
||||
if (!_secureFlg)
|
||||
{
|
||||
WRITELOG("TLS is not required.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -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,8 +506,11 @@ int Network::recv(uint8_t* buf, uint16_t len)
|
||||
fd_set rset;
|
||||
fd_set wset;
|
||||
|
||||
if (_secureFlg)
|
||||
if (!_secureFlg)
|
||||
{
|
||||
return TCPStack::recv(buf, len);
|
||||
}
|
||||
|
||||
if (_busy)
|
||||
{
|
||||
return 0;
|
||||
@@ -477,7 +548,7 @@ int Network::recv(uint8_t* buf, uint16_t len)
|
||||
break;
|
||||
default:
|
||||
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
|
||||
WRITELOG("TLSStack::recv() default %s\n", errmsg);
|
||||
WRITELOG("Network::recv() %s\n", errmsg);
|
||||
_busy = false;
|
||||
_mutex.unlock();
|
||||
return -1;
|
||||
@@ -511,19 +582,31 @@ int Network::recv(uint8_t* buf, uint16_t len)
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
return TCPStack::isValid();
|
||||
}
|
||||
if (_ssl)
|
||||
if (_sslValid && !_busy)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return TCPStack::isValid();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -533,12 +616,11 @@ void Network::disconnect()
|
||||
{
|
||||
SSL_shutdown(_ssl);
|
||||
_ssl = 0;
|
||||
TCPStack::close();
|
||||
}
|
||||
else
|
||||
{
|
||||
_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();
|
||||
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