1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 | #include <config.h>
|
31 |
|
32 | #ifndef WIN32
|
33 | #include <netdb.h>
|
34 | #include <unistd.h>
|
35 | #include <arpa/inet.h>
|
36 | #include <sys/socket.h>
|
37 | #else
|
38 | #include <winsock2.h>
|
39 | #include <ws2tcpip.h>
|
40 | #endif
|
41 |
|
42 | #include <assert.h>
|
43 | #include <errno.h>
|
44 | #include <fcntl.h>
|
45 | #include <stdio.h>
|
46 | #include <string.h>
|
47 | #ifdef WITH_WRAP
|
48 | #include <tcpd.h>
|
49 | #endif
|
50 |
|
51 | #ifdef __FreeBSD__
|
52 | # include <netinet/in.h>
|
53 | # include <sys/socket.h>
|
54 | #endif
|
55 |
|
56 | #ifdef __QNX__
|
57 | #include <netinet/in.h>
|
58 | #include <net/netbyte.h>
|
59 | #include <sys/socket.h>
|
60 | #endif
|
61 |
|
62 | #include <mosquitto_broker.h>
|
63 | #include <mqtt3_protocol.h>
|
64 | #include <memory_mosq.h>
|
65 | #include <net_mosq.h>
|
66 | #include <util_mosq.h>
|
67 |
|
68 | #ifdef WITH_TLS
|
69 | #include "tls_mosq.h"
|
70 | #include <openssl/err.h>
|
71 | static int tls_ex_index_context = -1;
|
72 | static int tls_ex_index_listener = -1;
|
73 | #endif
|
74 |
|
75 | #ifdef WITH_SYS_TREE
|
76 | extern unsigned int g_socket_connections;
|
77 | #endif
|
78 |
|
79 | int mqtt3_socket_accept(struct mosquitto_db *db, int listensock)
|
80 | {
|
81 | int i;
|
82 | int j;
|
83 | int new_sock = -1;
|
84 | struct mosquitto **tmp_contexts = NULL;
|
85 | struct mosquitto *new_context;
|
86 | #ifdef WITH_TLS
|
87 | BIO *bio;
|
88 | int rc;
|
89 | char ebuf[256];
|
90 | unsigned long e;
|
91 | #endif
|
92 | #ifdef WITH_WRAP
|
93 | struct request_info wrap_req;
|
94 | char address[1024];
|
95 | #endif
|
96 |
|
97 | new_sock = accept(listensock, NULL, 0);
|
98 | if(new_sock == INVALID_SOCKET) return -1;
|
99 |
|
100 | #ifdef WITH_SYS_TREE
|
101 | g_socket_connections++;
|
102 | #endif
|
103 |
|
104 | if(_mosquitto_socket_nonblock(new_sock)){
|
105 | return INVALID_SOCKET;
|
106 | }
|
107 |
|
108 | #ifdef WITH_WRAP
|
109 |
|
110 | request_init(&wrap_req, RQ_FILE, new_sock, RQ_DAEMON, "mosquitto", 0);
|
111 | fromhost(&wrap_req);
|
112 | if(!hosts_access(&wrap_req)){
|
113 |
|
114 | if(!_mosquitto_socket_get_address(new_sock, address, 1024)){
|
115 | _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Client connection from %s denied access by tcpd.", address);
|
116 | }
|
117 | COMPAT_CLOSE(new_sock);
|
118 | return -1;
|
119 | }else{
|
120 | #endif
|
121 | new_context = mqtt3_context_init(new_sock);
|
122 | if(!new_context){
|
123 | COMPAT_CLOSE(new_sock);
|
124 | return -1;
|
125 | }
|
126 | for(i=0; i<db->config->listener_count; i++){
|
127 | for(j=0; j<db->config->listeners[i].sock_count; j++){
|
128 | if(db->config->listeners[i].socks[j] == listensock){
|
129 | new_context->listener = &db->config->listeners[i];
|
130 | new_context->listener->client_count++;
|
131 | break;
|
132 | }
|
133 | }
|
134 | }
|
135 | if(!new_context->listener){
|
136 | mqtt3_context_cleanup(NULL, new_context, true);
|
137 | return -1;
|
138 | }
|
139 |
|
140 | if(new_context->listener->max_connections > 0 && new_context->listener->client_count > new_context->listener->max_connections){
|
141 | _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Client connection from %s denied: max_connections exceeded.", new_context->address);
|
142 | mqtt3_context_cleanup(NULL, new_context, true);
|
143 | return -1;
|
144 | }
|
145 |
|
146 | #ifdef WITH_TLS
|
147 |
|
148 | for(i=0; i<db->config->listener_count; i++){
|
149 | for(j=0; j<db->config->listeners[i].sock_count; j++){
|
150 | if(db->config->listeners[i].socks[j] == listensock){
|
151 | if(db->config->listeners[i].ssl_ctx){
|
152 | new_context->ssl = SSL_new(db->config->listeners[i].ssl_ctx);
|
153 | if(!new_context->ssl){
|
154 | mqtt3_context_cleanup(NULL, new_context, true);
|
155 | return -1;
|
156 | }
|
157 | SSL_set_ex_data(new_context->ssl, tls_ex_index_context, new_context);
|
158 | SSL_set_ex_data(new_context->ssl, tls_ex_index_listener, &db->config->listeners[i]);
|
159 | new_context->want_write = true;
|
160 | bio = BIO_new_socket(new_sock, BIO_NOCLOSE);
|
161 | SSL_set_bio(new_context->ssl, bio, bio);
|
162 | rc = SSL_accept(new_context->ssl);
|
163 | if(rc != 1){
|
164 | rc = SSL_get_error(new_context->ssl, rc);
|
165 | if(rc == SSL_ERROR_WANT_READ){
|
166 |
|
167 | }else if(rc == SSL_ERROR_WANT_WRITE){
|
168 | new_context->want_write = true;
|
169 | }else{
|
170 | e = ERR_get_error();
|
171 | while(e){
|
172 | _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE,
|
173 | "Client connection from %s failed: %s.",
|
174 | new_context->address, ERR_error_string(e, ebuf));
|
175 | e = ERR_get_error();
|
176 | }
|
177 | mqtt3_context_cleanup(NULL, new_context, true);
|
178 | return -1;
|
179 | }
|
180 | }
|
181 | }
|
182 | }
|
183 | }
|
184 | }
|
185 | #endif
|
186 |
|
187 | _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "New connection from %s on port %d.", new_context->address, new_context->listener->port);
|
188 | for(i=0; i<db->context_count; i++){
|
189 | if(db->contexts[i] == NULL){
|
190 | db->contexts[i] = new_context;
|
191 | break;
|
192 | }
|
193 | }
|
194 | if(i==db->context_count){
|
195 | tmp_contexts = _mosquitto_realloc(db->contexts, sizeof(struct mosquitto*)*(db->context_count+1));
|
196 | if(tmp_contexts){
|
197 | db->context_count++;
|
198 | db->contexts = tmp_contexts;
|
199 | db->contexts[i] = new_context;
|
200 | }else{
|
201 |
|
202 | mqtt3_context_cleanup(NULL, new_context, true);
|
203 | return -1;
|
204 | }
|
205 | }
|
206 |
|
207 | new_context->db_index = i;
|
208 |
|
209 | #ifdef WITH_WRAP
|
210 | }
|
211 | #endif
|
212 | return new_sock;
|
213 | }
|
214 |
|
215 | #ifdef WITH_TLS
|
216 | static int client_certificate_verify(int preverify_ok, X509_STORE_CTX *ctx)
|
217 | {
|
218 |
|
219 | return preverify_ok;
|
220 | }
|
221 | #endif
|
222 |
|
223 | #ifdef REAL_WITH_TLS_PSK
|
224 | static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned char *psk, unsigned int max_psk_len)
|
225 | {
|
226 | struct mosquitto_db *db;
|
227 | struct mosquitto *context;
|
228 | struct _mqtt3_listener *listener;
|
229 | char *psk_key = NULL;
|
230 | int len;
|
231 | const char *psk_hint;
|
232 |
|
233 | if(!identity) return 0;
|
234 |
|
235 | db = _mosquitto_get_db();
|
236 |
|
237 | context = SSL_get_ex_data(ssl, tls_ex_index_context);
|
238 | if(!context) return 0;
|
239 |
|
240 | listener = SSL_get_ex_data(ssl, tls_ex_index_listener);
|
241 | if(!listener) return 0;
|
242 |
|
243 | psk_hint = listener->psk_hint;
|
244 |
|
245 | |
246 |
|
247 | psk_key = _mosquitto_calloc(1, max_psk_len*2 + 1);
|
248 | if(!psk_key) return 0;
|
249 |
|
250 | if(mosquitto_psk_key_get(db, psk_hint, identity, psk_key, max_psk_len*2) != MOSQ_ERR_SUCCESS){
|
251 | return 0;
|
252 | }
|
253 |
|
254 | len = _mosquitto_hex2bin(psk_key, psk, max_psk_len);
|
255 | if (len < 0) return 0;
|
256 |
|
257 | if(listener->use_identity_as_username){
|
258 | context->username = _mosquitto_strdup(identity);
|
259 | if(!context->username) return 0;
|
260 | }
|
261 |
|
262 | return len;
|
263 | }
|
264 | #endif
|
265 |
|
266 |
|
267 |
|
268 |
|
269 |
|
270 | int mqtt3_socket_listen(struct _mqtt3_listener *listener)
|
271 | {
|
272 | int sock = -1;
|
273 | struct addrinfo hints;
|
274 | struct addrinfo *ainfo, *rp;
|
275 | char service[10];
|
276 | #ifndef WIN32
|
277 | int ss_opt = 1;
|
278 | #else
|
279 | char ss_opt = 1;
|
280 | #endif
|
281 | #ifdef WITH_TLS
|
282 | int rc;
|
283 | X509_STORE *store;
|
284 | X509_LOOKUP *lookup;
|
285 | int ssl_options = 0;
|
286 | #endif
|
287 | char buf[256];
|
288 |
|
289 | if(!listener) return MOSQ_ERR_INVAL;
|
290 |
|
291 | snprintf(service, 10, "%d", listener->port);
|
292 | memset(&hints, 0, sizeof(struct addrinfo));
|
293 | hints.ai_family = PF_UNSPEC;
|
294 | hints.ai_flags = AI_PASSIVE;
|
295 | hints.ai_socktype = SOCK_STREAM;
|
296 |
|
297 | if(getaddrinfo(listener->host, service, &hints, &ainfo)) return INVALID_SOCKET;
|
298 |
|
299 | listener->sock_count = 0;
|
300 | listener->socks = NULL;
|
301 |
|
302 | for(rp = ainfo; rp; rp = rp->ai_next){
|
303 | if(rp->ai_family == AF_INET){
|
304 | _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Opening ipv4 listen socket on port %d.", ntohs(((struct sockaddr_in *)rp->ai_addr)->sin_port));
|
305 | }else if(rp->ai_family == AF_INET6){
|
306 | _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Opening ipv6 listen socket on port %d.", ntohs(((struct sockaddr_in6 *)rp->ai_addr)->sin6_port));
|
307 | }else{
|
308 | continue;
|
309 | }
|
310 |
|
311 | sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
312 | if(sock == -1){
|
313 | strerror_r(errno, buf, 256);
|
314 | _mosquitto_log_printf(NULL, MOSQ_LOG_WARNING, "Warning: %s", buf);
|
315 | continue;
|
316 | }
|
317 | listener->sock_count++;
|
318 | listener->socks = _mosquitto_realloc(listener->socks, sizeof(int)*listener->sock_count);
|
319 | if(!listener->socks){
|
320 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
|
321 | return MOSQ_ERR_NOMEM;
|
322 | }
|
323 | listener->socks[listener->sock_count-1] = sock;
|
324 |
|
325 | #ifndef WIN32
|
326 | ss_opt = 1;
|
327 | setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &ss_opt, sizeof(ss_opt));
|
328 | #endif
|
329 | ss_opt = 1;
|
330 | setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &ss_opt, sizeof(ss_opt));
|
331 |
|
332 | if(_mosquitto_socket_nonblock(sock)){
|
333 | return 1;
|
334 | }
|
335 |
|
336 | if(bind(sock, rp->ai_addr, rp->ai_addrlen) == -1){
|
337 | strerror_r(errno, buf, 256);
|
338 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: %s", buf);
|
339 | COMPAT_CLOSE(sock);
|
340 | return 1;
|
341 | }
|
342 |
|
343 | if(listen(sock, 100) == -1){
|
344 | strerror_r(errno, buf, 256);
|
345 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: %s", buf);
|
346 | COMPAT_CLOSE(sock);
|
347 | return 1;
|
348 | }
|
349 | }
|
350 | freeaddrinfo(ainfo);
|
351 |
|
352 |
|
353 | if(listener->sock_count > 0){
|
354 | #ifdef WITH_TLS
|
355 | if((listener->cafile || listener->capath) && listener->certfile && listener->keyfile){
|
356 | #if OPENSSL_VERSION_NUMBER >= 0x10001000L
|
357 | if(listener->tls_version == NULL){
|
358 | listener->ssl_ctx = SSL_CTX_new(TLSv1_2_server_method());
|
359 | }else if(!strcmp(listener->tls_version, "tlsv1.2")){
|
360 | listener->ssl_ctx = SSL_CTX_new(TLSv1_2_server_method());
|
361 | }else if(!strcmp(listener->tls_version, "tlsv1.1")){
|
362 | listener->ssl_ctx = SSL_CTX_new(TLSv1_1_server_method());
|
363 | }else if(!strcmp(listener->tls_version, "tlsv1")){
|
364 | listener->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
|
365 | }
|
366 | #else
|
367 | listener->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
|
368 | #endif
|
369 | if(!listener->ssl_ctx){
|
370 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to create TLS context.");
|
371 | COMPAT_CLOSE(sock);
|
372 | return 1;
|
373 | }
|
374 |
|
375 |
|
376 | ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
|
377 | #ifdef SSL_OP_NO_COMPRESSION
|
378 |
|
379 | ssl_options |= SSL_OP_NO_COMPRESSION;
|
380 | #endif
|
381 | #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
|
382 |
|
383 | ssl_options |= SSL_OP_CIPHER_SERVER_PREFERENCE;
|
384 | #endif
|
385 | SSL_CTX_set_options(listener->ssl_ctx, ssl_options);
|
386 |
|
387 | #ifdef SSL_MODE_RELEASE_BUFFERS
|
388 |
|
389 | SSL_CTX_set_mode(listener->ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
390 | #endif
|
391 | snprintf(buf, 256, "mosquitto-%d", listener->port);
|
392 | SSL_CTX_set_session_id_context(listener->ssl_ctx, (unsigned char *)buf, strlen(buf));
|
393 |
|
394 | if(listener->ciphers){
|
395 | rc = SSL_CTX_set_cipher_list(listener->ssl_ctx, listener->ciphers);
|
396 | if(rc == 0){
|
397 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to set TLS ciphers. Check cipher list \"%s\".", listener->ciphers);
|
398 | COMPAT_CLOSE(sock);
|
399 | return 1;
|
400 | }
|
401 | }else{
|
402 | rc = SSL_CTX_set_cipher_list(listener->ssl_ctx, "DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2:@STRENGTH");
|
403 | if(rc == 0){
|
404 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to set TLS ciphers. Check cipher list \"%s\".", listener->ciphers);
|
405 | COMPAT_CLOSE(sock);
|
406 | return 1;
|
407 | }
|
408 | }
|
409 | rc = SSL_CTX_load_verify_locations(listener->ssl_ctx, listener->cafile, listener->capath);
|
410 | if(rc == 0){
|
411 | if(listener->cafile && listener->capath){
|
412 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load CA certificates. Check cafile \"%s\" and capath \"%s\".", listener->cafile, listener->capath);
|
413 | }else if(listener->cafile){
|
414 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load CA certificates. Check cafile \"%s\".", listener->cafile);
|
415 | }else{
|
416 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load CA certificates. Check capath \"%s\".", listener->capath);
|
417 | }
|
418 | COMPAT_CLOSE(sock);
|
419 | return 1;
|
420 | }
|
421 |
|
422 | if(listener->require_certificate){
|
423 | SSL_CTX_set_verify(listener->ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, client_certificate_verify);
|
424 | }else{
|
425 | SSL_CTX_set_verify(listener->ssl_ctx, SSL_VERIFY_PEER, client_certificate_verify);
|
426 | }
|
427 | rc = SSL_CTX_use_certificate_chain_file(listener->ssl_ctx, listener->certfile);
|
428 | if(rc != 1){
|
429 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load server certificate \"%s\". Check certfile.", listener->certfile);
|
430 | COMPAT_CLOSE(sock);
|
431 | return 1;
|
432 | }
|
433 | rc = SSL_CTX_use_PrivateKey_file(listener->ssl_ctx, listener->keyfile, SSL_FILETYPE_PEM);
|
434 | if(rc != 1){
|
435 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load server key file \"%s\". Check keyfile.", listener->keyfile);
|
436 | COMPAT_CLOSE(sock);
|
437 | return 1;
|
438 | }
|
439 | rc = SSL_CTX_check_private_key(listener->ssl_ctx);
|
440 | if(rc != 1){
|
441 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Server certificate/key are inconsistent.");
|
442 | COMPAT_CLOSE(sock);
|
443 | return 1;
|
444 | }
|
445 |
|
446 | if(listener->crlfile){
|
447 | store = SSL_CTX_get_cert_store(listener->ssl_ctx);
|
448 | if(!store){
|
449 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to obtain TLS store.");
|
450 | COMPAT_CLOSE(sock);
|
451 | return 1;
|
452 | }
|
453 | lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
|
454 | rc = X509_load_crl_file(lookup, listener->crlfile, X509_FILETYPE_PEM);
|
455 | if(rc != 1){
|
456 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to load certificate revocation file \"%s\". Check crlfile.", listener->crlfile);
|
457 | COMPAT_CLOSE(sock);
|
458 | return 1;
|
459 | }
|
460 | X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK);
|
461 | }
|
462 |
|
463 | # ifdef REAL_WITH_TLS_PSK
|
464 | }else if(listener->psk_hint){
|
465 | if(tls_ex_index_context == -1){
|
466 | tls_ex_index_context = SSL_get_ex_new_index(0, "client context", NULL, NULL, NULL);
|
467 | }
|
468 | if(tls_ex_index_listener == -1){
|
469 | tls_ex_index_listener = SSL_get_ex_new_index(0, "listener", NULL, NULL, NULL);
|
470 | }
|
471 |
|
472 | #if OPENSSL_VERSION_NUMBER >= 0x10001000L
|
473 | if(listener->tls_version == NULL){
|
474 | listener->ssl_ctx = SSL_CTX_new(TLSv1_2_server_method());
|
475 | }else if(!strcmp(listener->tls_version, "tlsv1.2")){
|
476 | listener->ssl_ctx = SSL_CTX_new(TLSv1_2_server_method());
|
477 | }else if(!strcmp(listener->tls_version, "tlsv1.1")){
|
478 | listener->ssl_ctx = SSL_CTX_new(TLSv1_1_server_method());
|
479 | }else if(!strcmp(listener->tls_version, "tlsv1")){
|
480 | listener->ssl_ctx = SSL_CTX_new(TLSv1_server_method());
|
481 | }
|
482 | #else
|
483 | listener->ssl_ctx = SSL_CTX_new(TLSv1_server_method());
|
484 | #endif
|
485 | if(!listener->ssl_ctx){
|
486 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to create TLS context.");
|
487 | COMPAT_CLOSE(sock);
|
488 | return 1;
|
489 | }
|
490 | SSL_CTX_set_psk_server_callback(listener->ssl_ctx, psk_server_callback);
|
491 | if(listener->psk_hint){
|
492 | rc = SSL_CTX_use_psk_identity_hint(listener->ssl_ctx, listener->psk_hint);
|
493 | if(rc == 0){
|
494 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to set TLS PSK hint.");
|
495 | COMPAT_CLOSE(sock);
|
496 | return 1;
|
497 | }
|
498 | }
|
499 | if(listener->ciphers){
|
500 | rc = SSL_CTX_set_cipher_list(listener->ssl_ctx, listener->ciphers);
|
501 | if(rc == 0){
|
502 | _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to set TLS ciphers. Check cipher list \"%s\".", listener->ciphers);
|
503 | COMPAT_CLOSE(sock);
|
504 | return 1;
|
505 | }
|
506 | }
|
507 | # endif
|
508 | }
|
509 | #endif
|
510 | return 0;
|
511 | }else{
|
512 | return 1;
|
513 | }
|
514 | }
|
515 |
|
516 | int _mosquitto_socket_get_address(int sock, char *buf, int len)
|
517 | {
|
518 | struct sockaddr_storage addr;
|
519 | socklen_t addrlen;
|
520 |
|
521 | addrlen = sizeof(addr);
|
522 | if(!getpeername(sock, (struct sockaddr *)&addr, &addrlen)){
|
523 | if(addr.ss_family == AF_INET){
|
524 | if(inet_ntop(AF_INET, &((struct sockaddr_in *)&addr)->sin_addr.s_addr, buf, len)){
|
525 | return 0;
|
526 | }
|
527 | }else if(addr.ss_family == AF_INET6){
|
528 | if(inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&addr)->sin6_addr.s6_addr, buf, len)){
|
529 | return 0;
|
530 | }
|
531 | }
|
532 | }
|
533 | return 1;
|
534 | }
|