broker access mode added

pull/16/head
Martin Ger 2017-08-21 14:27:07 +02:00
rodzic d262d21b21
commit 3ab2cad6e6
8 zmienionych plików z 66 dodań i 11 usunięć

Wyświetl plik

@ -63,6 +63,7 @@ MQTT broker related command:
- set broker_user _unsername_: sets the username for authentication of MQTT clients ("none" if no auth, default)
- set broker_password _password_: sets the password for authentication of MQTT clients ("none" if empty, default)
- set broker_access _mode_: controls the networks that allow MQTT broker access (0: no access, 1: only internal, 2: only external, 3: both (default))
- set broker_subscriptions _max_: sets the max number of subscription the broker can store (default: 30)
- set broker_retained_messages _max_: sets the max number of retained messages the broker can store (default: 30)
- set script_logging [0|1]: switches logging of script execution on or off (not permanently stored in the configuration)
@ -324,7 +325,8 @@ Your code can locally interact with the broker using the functions:
bool MQTT_local_publish(uint8_t* topic, uint8_t* data, uint16_t data_length, uint8_t qos, uint8_t retain);
bool MQTT_local_subscribe(uint8_t* topic, uint8_t qos);
bool MQTT_local_unsubscribe(uint8_t* topic);
void MQTT_local_onData(MqttDataCallback dataCb);
void MQTT_server_onData(MqttDataCallback dataCb);
```
With these functions you can publish and subscribe topics as a local client like you would with a remote MQTT broker.
@ -332,9 +334,15 @@ With these functions you can publish and subscribe topics as a local client like
Username/password authentication is provided with the following interface:
```c
typedef bool (*MqttAuthCallback)(const char* username, const char *password);
typedef bool (*MqttAuthCallback)(const char* username, const char *password, struct espconn *pesp_conn);
void MQTT_server_onAuth(MqttAuthCallback authCb);
typedef bool (*MqttConnectCallback)(struct espconn *pesp_conn);
void MQTT_server_onConnect(MqttConnectCallback connectCb);
```
If an *MqttAuthCallback* function is provided, it is called on each connect request. Based on username and password the function has to return *true* for authenticated or *false* for rejected. If a request provides no username and or password the strings are empty. If no *MqttAuthCallback* function is set, each request will be admitted.
If an *MqttAuthCallback* function is registered with MQTT_server_onAuth(), it is called on each connect request. Based on username, password, and optionally the connection info (e.g. the IP address) the function has to return *true* for authenticated or *false* for rejected. If a request provides no username and/or password these parameter strings are empty. If no *MqttAuthCallback* function is set, each request will be admitted.
The *MqttConnectCallback* function does a similar check for the connection, but it is called right after the connect request before any internal status is allocated. This is done in order to reject requests from unautorized clients in an early stage.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -14,7 +14,8 @@
#define LOCAL_MQTT_CLIENT ((void*)-1)
typedef bool (*MqttAuthCallback)(const char* username, const char *password);
typedef bool (*MqttAuthCallback)(const char* username, const char *password, struct espconn *pesp_conn);
typedef bool (*MqttConnectCallback)(struct espconn *pesp_conn);
typedef struct _MQTT_ClientCon {
struct espconn *pCon;
@ -40,11 +41,12 @@ typedef struct _MQTT_ClientCon {
extern MQTT_ClientCon *clientcon_list;
bool MQTT_server_start(uint16_t portno, uint16_t max_subscriptions, uint16_t max_retained_topics);
void MQTT_server_onConnect(MqttConnectCallback connectCb);
void MQTT_server_onAuth(MqttAuthCallback authCb);
void MQTT_server_onData(MqttDataCallback dataCb);
bool MQTT_local_publish(uint8_t* topic, uint8_t* data, uint16_t data_length, uint8_t qos, uint8_t retain);
bool MQTT_local_subscribe(uint8_t* topic, uint8_t qos);
bool MQTT_local_unsubscribe(uint8_t* topic);
void MQTT_local_onData(MqttDataCallback dataCb);
#endif /* _MQTT_SERVER_H_ */

Wyświetl plik

@ -36,6 +36,7 @@ LOCAL uint8_t zero_len_id[2] = { 0, 0 };
MQTT_ClientCon *clientcon_list;
LOCAL MqttDataCallback local_data_cb = NULL;
LOCAL MqttConnectCallback local_connect_cb = NULL;
LOCAL MqttAuthCallback local_auth_cb = NULL;
//#define MQTT_INFO os_printf
@ -505,7 +506,8 @@ static void ICACHE_FLASH_ATTR MQTT_ClientCon_recv_cb(void *arg, char *pdata, uns
// Check Auth
if ((local_auth_cb != NULL) &&
local_auth_cb(clientcon->connect_info.username==NULL?"":clientcon->connect_info.username,
clientcon->connect_info.password==NULL?"":clientcon->connect_info.password) == false) {
clientcon->connect_info.password==NULL?"":clientcon->connect_info.password,
clientcon->pCon) == false) {
MQTT_WARNING("MQTT: Authorization failed\r\n");
msg_conn_ret = CONNECTION_REFUSE_NOT_AUTHORIZED;
clientcon->connState = TCP_DISCONNECTING;
@ -763,9 +765,16 @@ static void ICACHE_FLASH_ATTR MQTT_ClientCon_sent_cb(void *arg) {
static void ICACHE_FLASH_ATTR MQTT_ClientCon_connected_cb(void *arg) {
struct espconn *pespconn = (struct espconn *)arg;
MQTT_ClientCon *mqttClientCon;
pespconn->reverse = NULL;
MQTT_INFO("MQTT_ClientCon_connected_cb(): Client connected\r\n");
if (local_connect_cb != NULL && local_connect_cb(pespconn) == false) {
MQTT_INFO("Connected not allowed\r\n");
espconn_disconnect(pespconn);
return;
}
espconn_regist_sentcb(pespconn, MQTT_ClientCon_sent_cb);
espconn_regist_disconcb(pespconn, MQTT_ClientCon_discon_cb);
espconn_regist_recvcb(pespconn, MQTT_ClientCon_recv_cb);
@ -873,10 +882,14 @@ bool ICACHE_FLASH_ATTR MQTT_local_unsubscribe(uint8_t * topic) {
return delete_topic(LOCAL_MQTT_CLIENT, topic);
}
void ICACHE_FLASH_ATTR MQTT_local_onData(MqttDataCallback dataCb) {
void ICACHE_FLASH_ATTR MQTT_server_onData(MqttDataCallback dataCb) {
local_data_cb = dataCb;
}
void ICACHE_FLASH_ATTR MQTT_server_onConnect(MqttConnectCallback connectCb) {
local_connect_cb = connectCb;
}
void ICACHE_FLASH_ATTR MQTT_server_onAuth(MqttAuthCallback authCb) {
local_auth_cb = authCb;
}

Wyświetl plik

@ -41,6 +41,7 @@ void config_load_default(sysconfig_p config) {
config->max_retained_messages = 30;
os_sprintf(config->mqtt_broker_user, "%s", "none");
config->mqtt_broker_password[0] = 0;
config->mqtt_broker_access = LOCAL_ACCESS | REMOTE_ACCESS;
#ifdef MQTT_CLIENT
os_sprintf(config->mqtt_host, "%s", "none");

Wyświetl plik

@ -53,6 +53,7 @@ typedef struct
uint16_t max_retained_messages; // Upper limit of stored retained messages
uint8_t mqtt_broker_user[32]; // Username for client login, "none" if empty
uint8_t mqtt_broker_password[32]; // Password for client login
uint8_t mqtt_broker_access; // Controls the interfaces that allow MQTT access (default LOCAL_ACCESS | REMOTE_ACCESS)
#ifdef MQTT_CLIENT
uint8_t mqtt_host[32]; // IP or hostname of the MQTT broker, "none" if empty

Wyświetl plik

@ -368,7 +368,7 @@ void ICACHE_FLASH_ATTR console_handle_command(struct espconn *pespconn) {
if (strcmp(tokens[0], "help") == 0) {
os_sprintf(response,
"show [config|stats|mqtt|script]\r\n|set [ssid|password|auto_connect|ap_ssid|ap_password|network|dns|ip|netmask|gw|ap_on|ap_open|speed|config_port|config_access|broker_subscriptions|broker_retained_messages|broker_user|broker_password] <val>\r\n|quit|save [config]|reset [factory]|lock [<password>]|unlock <password>");
"show [config|stats|mqtt|script]\r\n|set [ssid|password|auto_connect|ap_ssid|ap_password|network|dns|ip|netmask|gw|ap_on|ap_open|speed|config_port|config_access|broker_subscriptions|broker_retained_messages|broker_user|broker_password|broker_access] <val>\r\n|quit|save [config]|reset [factory]|lock [<password>]|unlock <password>");
to_console(response);
#ifdef SCRIPTED
os_sprintf(response, "|script <port>");
@ -441,6 +441,14 @@ void ICACHE_FLASH_ATTR console_handle_command(struct espconn *pespconn) {
config.locked ? "***" : (char *)config.mqtt_broker_password);
to_console(response);
}
response[0] = '\0';
if (config.mqtt_broker_access == LOCAL_ACCESS)
os_sprintf(response, "MQTT broker: local access only\r\n");
if (config.mqtt_broker_access == REMOTE_ACCESS)
os_sprintf(response, "MQTT broker: remote access only\r\n");
if (config.mqtt_broker_access == 0)
os_sprintf(response, "MQTT broker: no access!!\r\n");
to_console(response);
#ifdef MQTT_CLIENT
os_sprintf(response, "MQTT client %s\r\n", mqtt_enabled ? "enabled" : "disabled");
to_console(response);
@ -898,7 +906,7 @@ void ICACHE_FLASH_ATTR console_handle_command(struct espconn *pespconn) {
if (config.config_access == 0)
os_sprintf(response, "WARNING: if you save this, remote console access will be disabled!\r\n");
else
os_sprintf(response, "Config access set\r\n", config.config_port);
os_sprintf(response, "Config access set\r\n");
goto command_handled;
}
#endif
@ -931,6 +939,12 @@ void ICACHE_FLASH_ATTR console_handle_command(struct espconn *pespconn) {
os_sprintf(response, "Broker password set\r\n");
goto command_handled;
}
if (strcmp(tokens[1], "broker_access") == 0) {
config.mqtt_broker_access = atoi(tokens[2]) & (LOCAL_ACCESS | REMOTE_ACCESS);
os_sprintf(response, "Broker access set\r\n", config.config_port);
goto command_handled;
}
#ifdef SCRIPTED
if (strcmp(tokens[1], "script_logging") == 0) {
lang_logging = atoi(tokens[2]);
@ -1359,7 +1373,9 @@ void ICACHE_FLASH_ATTR user_set_station_config(void) {
}
bool ICACHE_FLASH_ATTR mqtt_broker_auth(const char* username, const char *password) {
bool ICACHE_FLASH_ATTR mqtt_broker_auth(const char* username, const char *password, struct espconn *pesp_conn) {
//os_printf("connect from " IPSTR "\r\n", IP2STR((ip_addr_t *)&(pesp_conn->proto.tcp->remote_ip)));
if (os_strcmp(config.mqtt_broker_user, "none") == 0)
return true;
@ -1372,6 +1388,19 @@ bool ICACHE_FLASH_ATTR mqtt_broker_auth(const char* username, const char *passwo
}
bool ICACHE_FLASH_ATTR mqtt_broker_connect(struct espconn *pesp_conn) {
//os_printf("connect from " IPSTR "\r\n", IP2STR((ip_addr_t *)&(pesp_conn->proto.tcp->remote_ip)));
if (!check_connection_access(pesp_conn, config.mqtt_broker_access)) {
os_printf("Client disconnected - no mqtt access from the address " IPSTR "\r\n",
IP2STR((ip_addr_t *)&(pesp_conn->proto.tcp->remote_ip)));
return false;
}
return true;
}
void user_init() {
struct ip_info info;
@ -1486,7 +1515,8 @@ void user_init() {
espconn_tcp_set_max_con(10);
os_printf("Max number of TCP clients: %d\r\n", espconn_tcp_get_max_con());
MQTT_local_onData(MQTT_local_DataCallback);
MQTT_server_onData(MQTT_local_DataCallback);
MQTT_server_onConnect(mqtt_broker_connect);
MQTT_server_onAuth(mqtt_broker_auth);
MQTT_server_start(1883 /*port */ , config.max_subscriptions,