diff --git a/lib/socks_mosq.c b/lib/socks_mosq.c index 1930cc7325..737a1aef6c 100644 --- a/lib/socks_mosq.c +++ b/lib/socks_mosq.c @@ -18,6 +18,8 @@ and the Eclipse Distribution License is available at #include #include +#include +#include #include "mosquitto_internal.h" #include "memory_mosq.h" @@ -75,8 +77,10 @@ int mosquitto_socks5_set(struct mosquitto *mosq, const char *host, int port, con if(password){ mosq->socks5_password = mosquitto__strdup(password); - mosquitto__free(mosq->socks5_username); - return MOSQ_ERR_NOMEM; + if(!mosq->socks5_password){ + mosquitto__free(mosq->socks5_username); + return MOSQ_ERR_NOMEM; + } } } @@ -133,20 +137,43 @@ int socks5__send(struct mosquitto *mosq) packet = mosquitto__calloc(1, sizeof(struct mosquitto__packet)); if(!packet) return MOSQ_ERR_NOMEM; - packet->packet_length = 7+strlen(mosq->host); - packet->payload = mosquitto__malloc(sizeof(uint8_t)*packet->packet_length); + struct in_addr addr_ipv4; + struct in6_addr addr_ipv6; - slen = strlen(mosq->host); + int ipv4_pton_result = inet_pton(AF_INET, mosq->host, &addr_ipv4); + int ipv6_pton_result = inet_pton(AF_INET6, mosq->host, &addr_ipv6); packet->payload[0] = 0x05; - packet->payload[1] = 1; - packet->payload[2] = 0; - packet->payload[3] = SOCKS_ATYPE_DOMAINNAME; - packet->payload[4] = slen; - memcpy(&(packet->payload[5]), mosq->host, slen); - packet->payload[5+slen] = MOSQ_MSB(mosq->port); - packet->payload[6+slen] = MOSQ_LSB(mosq->port); - + packet->payload[1] = 0x01; + packet->payload[2] = 0x00; + + if(ipv4_pton_result == 1){ + packet->packet_length = 10; + packet->payload = mosquitto__malloc(sizeof(uint8_t)*packet->packet_length); + packet->payload[3] = SOCKS_ATYPE_IP_V4; + memcpy(&(packet->payload[4]), (const void*)&addr_ipv4, 4); + packet->payload[4+4] = MOSQ_MSB(mosq->port); + packet->payload[4+4+1] = MOSQ_LSB(mosq->port); + }else if(ipv6_pton_result == 1){ + packet->packet_length = 22; + packet->payload = mosquitto__malloc(sizeof(uint8_t)*packet->packet_length); + packet->payload[3] = SOCKS_ATYPE_IP_V6; + memcpy(&(packet->payload[4]), (const void*)&addr_ipv6, 16); + packet->payload[4+16] = MOSQ_MSB(mosq->port); + packet->payload[4+16+1] = MOSQ_LSB(mosq->port); + }else{ + slen = strlen(mosq->host); + if(slen > UCHAR_MAX){ + return MOSQ_ERR_NOMEM; + } + packet->packet_length = 7 + slen; + packet->payload = mosquitto__malloc(sizeof(uint8_t)*packet->packet_length); + packet->payload[3] = SOCKS_ATYPE_DOMAINNAME; + packet->payload[4] = (uint8_t)slen; + memcpy(&(packet->payload[5]), mosq->host, slen); + packet->payload[5+slen] = MOSQ_MSB(mosq->port); + packet->payload[6+slen] = MOSQ_LSB(mosq->port); + } pthread_mutex_lock(&mosq->state_mutex); mosq->state = mosq_cs_socks5_request; pthread_mutex_unlock(&mosq->state_mutex);