1 /*
2 Copyright (c) 2011-2020 Roger Light <roger@atchoo.org>
3 
4 All rights reserved. This program and the accompanying materials
5 are made available under the terms of the Eclipse Public License v1.0
6 and Eclipse Distribution License v1.0 which accompany this distribution.
7 
8 The Eclipse Public License is available at
9    http://www.eclipse.org/legal/epl-v10.html
10 and the Eclipse Distribution License is available at
11   http://www.eclipse.org/org/documents/edl-v10.php.
12 
13 Contributors:
14    Roger Light - initial implementation and documentation.
15 */
16 
17 #include "config.h"
18 
19 #include <ctype.h>
20 #include <stdio.h>
21 #include <string.h>
22 
23 #include "mosquitto_broker_internal.h"
24 #include "memory_mosq.h"
25 #include "mqtt_protocol.h"
26 #include "send_mosq.h"
27 #include "misc_mosq.h"
28 #include "util_mosq.h"
29 
30 static int aclfile__parse(struct mosquitto_db *db, struct mosquitto__security_options *security_opts);
31 static int unpwd__file_parse(struct mosquitto__unpwd **unpwd, const char *password_file);
32 static int acl__cleanup(struct mosquitto_db *db, bool reload);
33 static int unpwd__cleanup(struct mosquitto__unpwd **unpwd, bool reload);
34 static int psk__file_parse(struct mosquitto_db *db, struct mosquitto__unpwd **psk_id, const char *psk_file);
35 #ifdef WITH_TLS
36 static int pw__digest(const char *password, const unsigned char *salt, unsigned int salt_len, unsigned char *hash, unsigned int *hash_len);
37 static int base64__decode(char *in, unsigned char **decoded, unsigned int *decoded_len);
38 static int mosquitto__memcmp_const(const void *ptr1, const void *b, size_t len);
39 #endif
40 
41 
42 
mosquitto_security_init_default(struct mosquitto_db * db,bool reload)43 int mosquitto_security_init_default(struct mosquitto_db *db, bool reload)
44 {
45 	int rc;
46 	int i;
47 	char *pwf;
48 	char *pskf;
49 
50 	UNUSED(reload);
51 
52 	/* Load username/password data if required. */
53 	if(db->config->per_listener_settings){
54 		for(i=0; i<db->config->listener_count; i++){
55 			pwf = db->config->listeners[i].security_options.password_file;
56 			if(pwf){
57 				rc = unpwd__file_parse(&db->config->listeners[i].unpwd, pwf);
58 				if(rc){
59 					log__printf(NULL, MOSQ_LOG_ERR, "Error opening password file \"%s\".", pwf);
60 					return rc;
61 				}
62 			}
63 		}
64 	}else{
65 		if(db->config->security_options.password_file){
66 			pwf = db->config->security_options.password_file;
67 			if(pwf){
68 				rc = unpwd__file_parse(&db->unpwd, pwf);
69 				if(rc){
70 					log__printf(NULL, MOSQ_LOG_ERR, "Error opening password file \"%s\".", pwf);
71 					return rc;
72 				}
73 			}
74 		}
75 	}
76 
77 	/* Load acl data if required. */
78 	if(db->config->per_listener_settings){
79 		for(i=0; i<db->config->listener_count; i++){
80 			if(db->config->listeners[i].security_options.acl_file){
81 				rc = aclfile__parse(db, &db->config->listeners[i].security_options);
82 				if(rc){
83 					log__printf(NULL, MOSQ_LOG_ERR, "Error opening acl file \"%s\".", db->config->listeners[i].security_options.acl_file);
84 					return rc;
85 				}
86 			}
87 		}
88 	}else{
89 		if(db->config->security_options.acl_file){
90 			rc = aclfile__parse(db, &db->config->security_options);
91 			if(rc){
92 				log__printf(NULL, MOSQ_LOG_ERR, "Error opening acl file \"%s\".", db->config->security_options.acl_file);
93 				return rc;
94 			}
95 		}
96 	}
97 
98 	/* Load psk data if required. */
99 	if(db->config->per_listener_settings){
100 		for(i=0; i<db->config->listener_count; i++){
101 			pskf = db->config->listeners[i].security_options.psk_file;
102 			if(pskf){
103 				rc = psk__file_parse(db, &db->config->listeners[i].psk_id, pskf);
104 				if(rc){
105 					log__printf(NULL, MOSQ_LOG_ERR, "Error opening psk file \"%s\".", pskf);
106 					return rc;
107 				}
108 			}
109 		}
110 	}else{
111 		char *pskf = db->config->security_options.psk_file;
112 		if(pskf){
113 			rc = psk__file_parse(db, &db->psk_id, pskf);
114 			if(rc){
115 				log__printf(NULL, MOSQ_LOG_ERR, "Error opening psk file \"%s\".", pskf);
116 				return rc;
117 			}
118 		}
119 	}
120 
121 	return MOSQ_ERR_SUCCESS;
122 }
123 
mosquitto_security_cleanup_default(struct mosquitto_db * db,bool reload)124 int mosquitto_security_cleanup_default(struct mosquitto_db *db, bool reload)
125 {
126 	int rc;
127 	int i;
128 
129 	rc = acl__cleanup(db, reload);
130 	if(rc != MOSQ_ERR_SUCCESS) return rc;
131 
132 	rc = unpwd__cleanup(&db->unpwd, reload);
133 	if(rc != MOSQ_ERR_SUCCESS) return rc;
134 
135 	for(i=0; i<db->config->listener_count; i++){
136 		if(db->config->listeners[i].unpwd){
137 			rc = unpwd__cleanup(&db->config->listeners[i].unpwd, reload);
138 			if(rc != MOSQ_ERR_SUCCESS) return rc;
139 		}
140 	}
141 
142 	rc = unpwd__cleanup(&db->psk_id, reload);
143 	if(rc != MOSQ_ERR_SUCCESS) return rc;
144 
145 	for(i=0; i<db->config->listener_count; i++){
146 		if(db->config->listeners[i].psk_id){
147 			rc = unpwd__cleanup(&db->config->listeners[i].psk_id, reload);
148 			if(rc != MOSQ_ERR_SUCCESS) return rc;
149 		}
150 	}
151 
152 	return MOSQ_ERR_SUCCESS;
153 }
154 
155 
add__acl(struct mosquitto__security_options * security_opts,const char * user,const char * topic,int access)156 int add__acl(struct mosquitto__security_options *security_opts, const char *user, const char *topic, int access)
157 {
158 	struct mosquitto__acl_user *acl_user=NULL, *user_tail;
159 	struct mosquitto__acl *acl, *acl_tail;
160 	char *local_topic;
161 	bool new_user = false;
162 
163 	if(!security_opts || !topic) return MOSQ_ERR_INVAL;
164 
165 	local_topic = mosquitto__strdup(topic);
166 	if(!local_topic){
167 		return MOSQ_ERR_NOMEM;
168 	}
169 
170 	if(security_opts->acl_list){
171 		user_tail = security_opts->acl_list;
172 		while(user_tail){
173 			if(user == NULL){
174 				if(user_tail->username == NULL){
175 					acl_user = user_tail;
176 					break;
177 				}
178 			}else if(user_tail->username && !strcmp(user_tail->username, user)){
179 				acl_user = user_tail;
180 				break;
181 			}
182 			user_tail = user_tail->next;
183 		}
184 	}
185 	if(!acl_user){
186 		acl_user = mosquitto__malloc(sizeof(struct mosquitto__acl_user));
187 		if(!acl_user){
188 			mosquitto__free(local_topic);
189 			return MOSQ_ERR_NOMEM;
190 		}
191 		new_user = true;
192 		if(user){
193 			acl_user->username = mosquitto__strdup(user);
194 			if(!acl_user->username){
195 				mosquitto__free(local_topic);
196 				mosquitto__free(acl_user);
197 				return MOSQ_ERR_NOMEM;
198 			}
199 		}else{
200 			acl_user->username = NULL;
201 		}
202 		acl_user->next = NULL;
203 		acl_user->acl = NULL;
204 	}
205 
206 	acl = mosquitto__malloc(sizeof(struct mosquitto__acl));
207 	if(!acl){
208 		mosquitto__free(local_topic);
209 		mosquitto__free(acl_user->username);
210 		mosquitto__free(acl_user);
211 		return MOSQ_ERR_NOMEM;
212 	}
213 	acl->access = access;
214 	acl->topic = local_topic;
215 	acl->next = NULL;
216 	acl->ccount = 0;
217 	acl->ucount = 0;
218 
219 	/* Add acl to user acl list */
220 	if(acl_user->acl){
221 		acl_tail = acl_user->acl;
222 		while(acl_tail->next){
223 			acl_tail = acl_tail->next;
224 		}
225 		acl_tail->next = acl;
226 	}else{
227 		acl_user->acl = acl;
228 	}
229 
230 	if(new_user){
231 		/* Add to end of list */
232 		if(security_opts->acl_list){
233 			user_tail = security_opts->acl_list;
234 			while(user_tail->next){
235 				user_tail = user_tail->next;
236 			}
237 			user_tail->next = acl_user;
238 		}else{
239 			security_opts->acl_list = acl_user;
240 		}
241 	}
242 
243 	return MOSQ_ERR_SUCCESS;
244 }
245 
add__acl_pattern(struct mosquitto__security_options * security_opts,const char * topic,int access)246 int add__acl_pattern(struct mosquitto__security_options *security_opts, const char *topic, int access)
247 {
248 	struct mosquitto__acl *acl, *acl_tail;
249 	char *local_topic;
250 	char *s;
251 
252 	if(!security_opts| !topic) return MOSQ_ERR_INVAL;
253 
254 	local_topic = mosquitto__strdup(topic);
255 	if(!local_topic){
256 		return MOSQ_ERR_NOMEM;
257 	}
258 
259 	acl = mosquitto__malloc(sizeof(struct mosquitto__acl));
260 	if(!acl){
261 		mosquitto__free(local_topic);
262 		return MOSQ_ERR_NOMEM;
263 	}
264 	acl->access = access;
265 	acl->topic = local_topic;
266 	acl->next = NULL;
267 
268 	acl->ccount = 0;
269 	s = local_topic;
270 	while(s){
271 		s = strstr(s, "%c");
272 		if(s){
273 			acl->ccount++;
274 			s+=2;
275 		}
276 	}
277 
278 	acl->ucount = 0;
279 	s = local_topic;
280 	while(s){
281 		s = strstr(s, "%u");
282 		if(s){
283 			acl->ucount++;
284 			s+=2;
285 		}
286 	}
287 
288 	if(acl->ccount == 0 && acl->ucount == 0){
289 		log__printf(NULL, MOSQ_LOG_WARNING,
290 				"Warning: ACL pattern '%s' does not contain '%%c' or '%%u'.",
291 				topic);
292 	}
293 
294 	if(security_opts->acl_patterns){
295 		acl_tail = security_opts->acl_patterns;
296 		while(acl_tail->next){
297 			acl_tail = acl_tail->next;
298 		}
299 		acl_tail->next = acl;
300 	}else{
301 		security_opts->acl_patterns = acl;
302 	}
303 
304 	return MOSQ_ERR_SUCCESS;
305 }
306 
mosquitto_acl_check_default(struct mosquitto_db * db,struct mosquitto * context,const char * topic,int access)307 int mosquitto_acl_check_default(struct mosquitto_db *db, struct mosquitto *context, const char *topic, int access)
308 {
309 	char *local_acl;
310 	struct mosquitto__acl *acl_root;
311 	bool result;
312 	int i;
313 	int len, tlen, clen, ulen;
314 	char *s;
315 	struct mosquitto__security_options *security_opts = NULL;
316 
317 	if(!db || !context || !topic) return MOSQ_ERR_INVAL;
318 	if(context->bridge) return MOSQ_ERR_SUCCESS;
319 
320 	if(db->config->per_listener_settings){
321 		if(!context->listener) return MOSQ_ERR_ACL_DENIED;
322 		security_opts = &context->listener->security_options;
323 	}else{
324 		security_opts = &db->config->security_options;
325 	}
326 	if(!security_opts->acl_file && !security_opts->acl_list && !security_opts->acl_patterns){
327 			return MOSQ_ERR_PLUGIN_DEFER;
328 	}
329 
330 	if(access == MOSQ_ACL_SUBSCRIBE) return MOSQ_ERR_SUCCESS; /* FIXME - implement ACL subscription strings. */
331 	if(!context->acl_list && !security_opts->acl_patterns) return MOSQ_ERR_ACL_DENIED;
332 
333 	if(context->acl_list){
334 		acl_root = context->acl_list->acl;
335 	}else{
336 		acl_root = NULL;
337 	}
338 
339 	/* Loop through all ACLs for this client. */
340 	while(acl_root){
341 		/* Loop through the topic looking for matches to this ACL. */
342 
343 		/* If subscription starts with $, acl_root->topic must also start with $. */
344 		if(topic[0] == '$' && acl_root->topic[0] != '$'){
345 			acl_root = acl_root->next;
346 			continue;
347 		}
348 		mosquitto_topic_matches_sub(acl_root->topic, topic, &result);
349 		if(result){
350 			if(access & acl_root->access){
351 				/* And access is allowed. */
352 				return MOSQ_ERR_SUCCESS;
353 			}
354 		}
355 		acl_root = acl_root->next;
356 	}
357 
358 	acl_root = security_opts->acl_patterns;
359 
360 	if(acl_root){
361 		/* We are using pattern based acls. Check whether the username or
362 		 * client id contains a + or # and if so deny access.
363 		 *
364 		 * Without this, a malicious client may configure its username/client
365 		 * id to bypass ACL checks (or have a username/client id that cannot
366 		 * publish or receive messages to its own place in the hierarchy).
367 		 */
368 		if(context->username && strpbrk(context->username, "+#")){
369 			log__printf(NULL, MOSQ_LOG_NOTICE, "ACL denying access to client with dangerous username \"%s\"", context->username);
370 			return MOSQ_ERR_ACL_DENIED;
371 		}
372 
373 		if(context->id && strpbrk(context->id, "+#")){
374 			log__printf(NULL, MOSQ_LOG_NOTICE, "ACL denying access to client with dangerous client id \"%s\"", context->id);
375 			return MOSQ_ERR_ACL_DENIED;
376 		}
377 	}
378 
379 	/* Loop through all pattern ACLs. */
380 	if(!context->id) return MOSQ_ERR_ACL_DENIED;
381 	clen = strlen(context->id);
382 
383 	while(acl_root){
384 		tlen = strlen(acl_root->topic);
385 
386 		if(acl_root->ucount && !context->username){
387 			acl_root = acl_root->next;
388 			continue;
389 		}
390 
391 		if(context->username){
392 			ulen = strlen(context->username);
393 			len = tlen + acl_root->ccount*(clen-2) + acl_root->ucount*(ulen-2);
394 		}else{
395 			ulen = 0;
396 			len = tlen + acl_root->ccount*(clen-2);
397 		}
398 		local_acl = mosquitto__malloc(len+1);
399 		if(!local_acl) return 1; // FIXME
400 		s = local_acl;
401 		for(i=0; i<tlen; i++){
402 			if(i<tlen-1 && acl_root->topic[i] == '%'){
403 				if(acl_root->topic[i+1] == 'c'){
404 					i++;
405 					strncpy(s, context->id, clen);
406 					s+=clen;
407 					continue;
408 				}else if(context->username && acl_root->topic[i+1] == 'u'){
409 					i++;
410 					strncpy(s, context->username, ulen);
411 					s+=ulen;
412 					continue;
413 				}
414 			}
415 			s[0] = acl_root->topic[i];
416 			s++;
417 		}
418 		local_acl[len] = '\0';
419 
420 		mosquitto_topic_matches_sub(local_acl, topic, &result);
421 		mosquitto__free(local_acl);
422 		if(result){
423 			if(access & acl_root->access){
424 				/* And access is allowed. */
425 				return MOSQ_ERR_SUCCESS;
426 			}
427 		}
428 
429 		acl_root = acl_root->next;
430 	}
431 
432 	return MOSQ_ERR_ACL_DENIED;
433 }
434 
435 
aclfile__parse(struct mosquitto_db * db,struct mosquitto__security_options * security_opts)436 static int aclfile__parse(struct mosquitto_db *db, struct mosquitto__security_options *security_opts)
437 {
438 	FILE *aclfptr = NULL;
439 	char *token;
440 	char *user = NULL;
441 	char *topic;
442 	char *access_s;
443 	int access;
444 	int rc = MOSQ_ERR_SUCCESS;
445 	int slen;
446 	int topic_pattern;
447 	char *saveptr = NULL;
448 	char *buf = NULL;
449 	int buflen = 256;
450 
451 	if(!db || !db->config) return MOSQ_ERR_INVAL;
452 	if(!security_opts) return MOSQ_ERR_INVAL;
453 	if(!security_opts->acl_file) return MOSQ_ERR_SUCCESS;
454 
455 	buf = mosquitto__malloc(buflen);
456 	if(buf == NULL){
457 		log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
458 		return 1;
459 	}
460 
461 	aclfptr = mosquitto__fopen(security_opts->acl_file, "rt", false);
462 	if(!aclfptr){
463 		mosquitto__free(buf);
464 		log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open acl_file \"%s\".", security_opts->acl_file);
465 		return 1;
466 	}
467 
468 	// topic [read|write] <topic>
469 	// user <user>
470 
471 	while(fgets_extending(&buf, &buflen, aclfptr)){
472 		slen = strlen(buf);
473 		while(slen > 0 && isspace(buf[slen-1])){
474 			buf[slen-1] = '\0';
475 			slen = strlen(buf);
476 		}
477 		if(buf[0] == '#'){
478 			continue;
479 		}
480 		token = strtok_r(buf, " ", &saveptr);
481 		if(token){
482 			if(!strcmp(token, "topic") || !strcmp(token, "pattern")){
483 				if(!strcmp(token, "topic")){
484 					topic_pattern = 0;
485 				}else{
486 					topic_pattern = 1;
487 				}
488 
489 				access_s = strtok_r(NULL, " ", &saveptr);
490 				if(!access_s){
491 					log__printf(NULL, MOSQ_LOG_ERR, "Error: Empty topic in acl_file \"%s\".", security_opts->acl_file);
492 					rc = MOSQ_ERR_INVAL;
493 					break;
494 				}
495 				token = strtok_r(NULL, "", &saveptr);
496 				if(token){
497 					topic = misc__trimblanks(token);
498 				}else{
499 					topic = access_s;
500 					access_s = NULL;
501 				}
502 				if(access_s){
503 					if(!strcmp(access_s, "read")){
504 						access = MOSQ_ACL_READ;
505 					}else if(!strcmp(access_s, "write")){
506 						access = MOSQ_ACL_WRITE;
507 					}else if(!strcmp(access_s, "readwrite")){
508 						access = MOSQ_ACL_READ | MOSQ_ACL_WRITE;
509 					}else{
510 						log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid topic access type \"%s\" in acl_file \"%s\".", access_s, security_opts->acl_file);
511 						rc = MOSQ_ERR_INVAL;
512 						break;
513 					}
514 				}else{
515 					access = MOSQ_ACL_READ | MOSQ_ACL_WRITE;
516 				}
517 				rc = mosquitto_sub_topic_check(topic);
518 				if(rc != MOSQ_ERR_SUCCESS){
519 					log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid ACL topic \"%s\" in acl_file \"%s\".", topic, security_opts->acl_file);
520 					rc = MOSQ_ERR_INVAL;
521 					break;
522 				}
523 
524 				if(topic_pattern == 0){
525 					rc = add__acl(security_opts, user, topic, access);
526 				}else{
527 					rc = add__acl_pattern(security_opts, topic, access);
528 				}
529 				if(rc){
530 					break;
531 				}
532 			}else if(!strcmp(token, "user")){
533 				token = strtok_r(NULL, "", &saveptr);
534 				if(token){
535 					token = misc__trimblanks(token);
536 					if(slen == 0){
537 						log__printf(NULL, MOSQ_LOG_ERR, "Error: Missing username in acl_file \"%s\".", security_opts->acl_file);
538 						rc = MOSQ_ERR_INVAL;
539 						break;
540 					}
541 					mosquitto__free(user);
542 					user = mosquitto__strdup(token);
543 					if(!user){
544 						rc = MOSQ_ERR_NOMEM;
545 						break;
546 					}
547 				}else{
548 					log__printf(NULL, MOSQ_LOG_ERR, "Error: Missing username in acl_file \"%s\".", security_opts->acl_file);
549 					rc = MOSQ_ERR_INVAL;
550 					break;
551 				}
552 			}else{
553 				log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid line in acl_file \"%s\": %s.", security_opts->acl_file, buf);
554 				rc = MOSQ_ERR_INVAL;
555 				break;
556 			}
557 		}
558 	}
559 
560 	mosquitto__free(buf);
561 	mosquitto__free(user);
562 	fclose(aclfptr);
563 
564 	return rc;
565 }
566 
free__acl(struct mosquitto__acl * acl)567 static void free__acl(struct mosquitto__acl *acl)
568 {
569 	if(!acl) return;
570 
571 	if(acl->next){
572 		free__acl(acl->next);
573 	}
574 	mosquitto__free(acl->topic);
575 	mosquitto__free(acl);
576 }
577 
578 
acl__cleanup_single(struct mosquitto__security_options * security_opts)579 static void acl__cleanup_single(struct mosquitto__security_options *security_opts)
580 {
581 	struct mosquitto__acl_user *user_tail;
582 
583 	while(security_opts->acl_list){
584 		user_tail = security_opts->acl_list->next;
585 
586 		free__acl(security_opts->acl_list->acl);
587 		mosquitto__free(security_opts->acl_list->username);
588 		mosquitto__free(security_opts->acl_list);
589 
590 		security_opts->acl_list = user_tail;
591 	}
592 
593 	if(security_opts->acl_patterns){
594 		free__acl(security_opts->acl_patterns);
595 		security_opts->acl_patterns = NULL;
596 	}
597 }
598 
599 
acl__cleanup(struct mosquitto_db * db,bool reload)600 static int acl__cleanup(struct mosquitto_db *db, bool reload)
601 {
602 	struct mosquitto *context, *ctxt_tmp;
603 	int i;
604 
605 	UNUSED(reload);
606 
607 	if(!db) return MOSQ_ERR_INVAL;
608 
609 	/* As we're freeing ACLs, we must clear context->acl_list to ensure no
610 	 * invalid memory accesses take place later.
611 	 * This *requires* the ACLs to be reapplied after acl__cleanup()
612 	 * is called if we are reloading the config. If this is not done, all
613 	 * access will be denied to currently connected clients.
614 	 */
615 	HASH_ITER(hh_id, db->contexts_by_id, context, ctxt_tmp){
616 		context->acl_list = NULL;
617 	}
618 
619 	if(db->config->per_listener_settings){
620 		for(i=0; i<db->config->listener_count; i++){
621 			acl__cleanup_single(&db->config->listeners[i].security_options);
622 		}
623 	}else{
624 		acl__cleanup_single(&db->config->security_options);
625 	}
626 
627 	return MOSQ_ERR_SUCCESS;
628 }
629 
630 
acl__find_acls(struct mosquitto_db * db,struct mosquitto * context)631 int acl__find_acls(struct mosquitto_db *db, struct mosquitto *context)
632 {
633 	struct mosquitto__acl_user *acl_tail;
634 	struct mosquitto__security_options *security_opts;
635 
636 	/* Associate user with its ACL, assuming we have ACLs loaded. */
637 	if(db->config->per_listener_settings){
638 		if(!context->listener){
639 			return MOSQ_ERR_INVAL;
640 		}
641 		security_opts = &context->listener->security_options;
642 	}else{
643 		security_opts = &db->config->security_options;
644 	}
645 
646 	if(security_opts->acl_list){
647 		acl_tail = security_opts->acl_list;
648 		while(acl_tail){
649 			if(context->username){
650 				if(acl_tail->username && !strcmp(context->username, acl_tail->username)){
651 					context->acl_list = acl_tail;
652 					break;
653 				}
654 			}else{
655 				if(acl_tail->username == NULL){
656 					context->acl_list = acl_tail;
657 					break;
658 				}
659 			}
660 			acl_tail = acl_tail->next;
661 		}
662 	}else{
663 		context->acl_list = NULL;
664 	}
665 
666 	return MOSQ_ERR_SUCCESS;
667 }
668 
669 
pwfile__parse(const char * file,struct mosquitto__unpwd ** root)670 static int pwfile__parse(const char *file, struct mosquitto__unpwd **root)
671 {
672 	FILE *pwfile;
673 	struct mosquitto__unpwd *unpwd;
674 	char *username, *password;
675 	char *saveptr = NULL;
676 	char *buf;
677 	int buflen = 256;
678 
679 	buf = mosquitto__malloc(buflen);
680 	if(buf == NULL){
681 		log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
682 		return 1;
683 	}
684 
685 	pwfile = mosquitto__fopen(file, "rt", false);
686 	if(!pwfile){
687 		log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open pwfile \"%s\".", file);
688 		mosquitto__free(buf);
689 		return 1;
690 	}
691 
692 	while(!feof(pwfile)){
693 		if(fgets_extending(&buf, &buflen, pwfile)){
694 			if(buf[0] == '#') continue;
695 			if(!strchr(buf, ':')) continue;
696 
697 			username = strtok_r(buf, ":", &saveptr);
698 			if(username){
699 				unpwd = mosquitto__calloc(1, sizeof(struct mosquitto__unpwd));
700 				if(!unpwd){
701 					fclose(pwfile);
702 					mosquitto__free(buf);
703 					return MOSQ_ERR_NOMEM;
704 				}
705 				username = misc__trimblanks(username);
706 				if(strlen(username) > 65535){
707 					log__printf(NULL, MOSQ_LOG_NOTICE, "Warning: Invalid line in password file '%s', username too long.", file);
708 					mosquitto__free(unpwd);
709 					continue;
710 				}
711 
712 				unpwd->username = mosquitto__strdup(username);
713 				if(!unpwd->username){
714 					mosquitto__free(unpwd);
715 					mosquitto__free(buf);
716 					fclose(pwfile);
717 					return MOSQ_ERR_NOMEM;
718 				}
719 				password = strtok_r(NULL, ":", &saveptr);
720 				if(password){
721 					password = misc__trimblanks(password);
722 
723 					if(strlen(password) > 65535){
724 						log__printf(NULL, MOSQ_LOG_NOTICE, "Warning: Invalid line in password file '%s', password too long.", file);
725 						mosquitto__free(unpwd->username);
726 						mosquitto__free(unpwd);
727 						continue;
728 					}
729 
730 					unpwd->password = mosquitto__strdup(password);
731 					if(!unpwd->password){
732 						fclose(pwfile);
733 						mosquitto__free(unpwd->username);
734 						mosquitto__free(unpwd);
735 						mosquitto__free(buf);
736 						return MOSQ_ERR_NOMEM;
737 					}
738 
739 					HASH_ADD_KEYPTR(hh, *root, unpwd->username, strlen(unpwd->username), unpwd);
740 				}else{
741 					log__printf(NULL, MOSQ_LOG_NOTICE, "Warning: Invalid line in password file '%s': %s", file, buf);
742 					mosquitto__free(unpwd->username);
743 					mosquitto__free(unpwd);
744 				}
745 			}
746 		}
747 	}
748 	fclose(pwfile);
749 	mosquitto__free(buf);
750 
751 	return MOSQ_ERR_SUCCESS;
752 }
753 
754 
755 #ifdef WITH_TLS
756 
unpwd__free_item(struct mosquitto__unpwd ** unpwd,struct mosquitto__unpwd * item)757 static void unpwd__free_item(struct mosquitto__unpwd **unpwd, struct mosquitto__unpwd *item)
758 {
759 	mosquitto__free(item->username);
760 	mosquitto__free(item->password);
761 	mosquitto__free(item->salt);
762 	HASH_DEL(*unpwd, item);
763 	mosquitto__free(item);
764 }
765 
766 
unpwd__decode_passwords(struct mosquitto__unpwd ** unpwd)767 static int unpwd__decode_passwords(struct mosquitto__unpwd **unpwd)
768 {
769 	struct mosquitto__unpwd *u, *tmp;
770 	char *token;
771 	unsigned char *salt;
772 	unsigned int salt_len;
773 	unsigned char *password;
774 	unsigned int password_len;
775 	int rc;
776 
777 	HASH_ITER(hh, *unpwd, u, tmp){
778 		/* Need to decode password into hashed data + salt. */
779 		if(u->password){
780 			token = strtok(u->password, "$");
781 			if(token && !strcmp(token, "6")){
782 				token = strtok(NULL, "$");
783 				if(token){
784 					rc = base64__decode(token, &salt, &salt_len);
785 					if(rc == MOSQ_ERR_SUCCESS && salt_len == 12){
786 						u->salt = salt;
787 						u->salt_len = salt_len;
788 						token = strtok(NULL, "$");
789 						if(token){
790 							rc = base64__decode(token, &password, &password_len);
791 							if(rc == MOSQ_ERR_SUCCESS && password_len == 64){
792 								mosquitto__free(u->password);
793 								u->password = (char *)password;
794 								u->password_len = password_len;
795 							}else{
796 								log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to decode password for user %s, removing entry.", u->username);
797 								unpwd__free_item(unpwd, u);
798 							}
799 						}else{
800 							log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid password hash for user %s, removing entry.", u->username);
801 							unpwd__free_item(unpwd, u);
802 						}
803 					}else{
804 						log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to decode password salt for user %s, removing entry.", u->username);
805 						unpwd__free_item(unpwd, u);
806 					}
807 				}else{
808 					log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid password hash for user %s, removing entry.", u->username);
809 					unpwd__free_item(unpwd, u);
810 				}
811 			}else{
812 				log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid password hash for user %s, removing entry.", u->username);
813 				unpwd__free_item(unpwd, u);
814 			}
815 		}else{
816 			log__printf(NULL, MOSQ_LOG_ERR, "Error: Missing password hash for user %s, removing entry.", u->username);
817 			unpwd__free_item(unpwd, u);
818 		}
819 	}
820 
821 	return MOSQ_ERR_SUCCESS;
822 }
823 #endif
824 
825 
unpwd__file_parse(struct mosquitto__unpwd ** unpwd,const char * password_file)826 static int unpwd__file_parse(struct mosquitto__unpwd **unpwd, const char *password_file)
827 {
828 	int rc;
829 	if(!unpwd) return MOSQ_ERR_INVAL;
830 
831 	if(!password_file) return MOSQ_ERR_SUCCESS;
832 
833 	rc = pwfile__parse(password_file, unpwd);
834 
835 #ifdef WITH_TLS
836 	if(rc) return rc;
837 	rc = unpwd__decode_passwords(unpwd);
838 #endif
839 
840 	return rc;
841 }
842 
psk__file_parse(struct mosquitto_db * db,struct mosquitto__unpwd ** psk_id,const char * psk_file)843 static int psk__file_parse(struct mosquitto_db *db, struct mosquitto__unpwd **psk_id, const char *psk_file)
844 {
845 	int rc;
846 	struct mosquitto__unpwd *u, *tmp;
847 
848 	if(!db || !db->config || !psk_id) return MOSQ_ERR_INVAL;
849 
850 	/* We haven't been asked to parse a psk file. */
851 	if(!psk_file) return MOSQ_ERR_SUCCESS;
852 
853 	rc = pwfile__parse(psk_file, psk_id);
854 	if(rc) return rc;
855 
856 	HASH_ITER(hh, (*psk_id), u, tmp){
857 		/* Check for hex only digits */
858 		if(!u->password){
859 			log__printf(NULL, MOSQ_LOG_ERR, "Error: Empty psk for identity \"%s\".", u->username);
860 			return MOSQ_ERR_INVAL;
861 		}
862 		if(strspn(u->password, "0123456789abcdefABCDEF") < strlen(u->password)){
863 			log__printf(NULL, MOSQ_LOG_ERR, "Error: psk for identity \"%s\" contains non-hexadecimal characters.", u->username);
864 			return MOSQ_ERR_INVAL;
865 		}
866 	}
867 	return MOSQ_ERR_SUCCESS;
868 }
869 
870 
871 #ifdef WITH_TLS
mosquitto__memcmp_const(const void * a,const void * b,size_t len)872 static int mosquitto__memcmp_const(const void *a, const void *b, size_t len)
873 {
874 	size_t i;
875 	int rc = 0;
876 
877 	if(!a || !b) return 1;
878 
879 	for(i=0; i<len; i++){
880 		if( ((char *)a)[i] != ((char *)b)[i] ){
881 			rc = 1;
882 		}
883 	}
884 	return rc;
885 }
886 #endif
887 
888 
mosquitto_unpwd_check_default(struct mosquitto_db * db,struct mosquitto * context,const char * username,const char * password)889 int mosquitto_unpwd_check_default(struct mosquitto_db *db, struct mosquitto *context, const char *username, const char *password)
890 {
891 	struct mosquitto__unpwd *u, *tmp;
892 	struct mosquitto__unpwd *unpwd_ref;
893 #ifdef WITH_TLS
894 	unsigned char hash[EVP_MAX_MD_SIZE];
895 	unsigned int hash_len;
896 	int rc;
897 #endif
898 
899 	if(!db) return MOSQ_ERR_INVAL;
900 
901 	if(db->config->per_listener_settings){
902 		if(context->bridge) return MOSQ_ERR_SUCCESS;
903 		if(!context->listener) return MOSQ_ERR_INVAL;
904 		if(context->listener->security_options.password_file == NULL) return MOSQ_ERR_PLUGIN_DEFER;
905 		unpwd_ref = context->listener->unpwd;
906 	}else{
907 		if(db->config->security_options.password_file == NULL) return MOSQ_ERR_PLUGIN_DEFER;
908 		unpwd_ref = db->unpwd;
909 	}
910 	if(!username){
911 		/* Check must be made only after checking unpwd_ref.
912 		 * This is DENY here, because in MQTT v5 username can be missing when
913 		 * password is present, but we don't support that. */
914 		return MOSQ_ERR_AUTH;
915 	}
916 
917 	HASH_ITER(hh, unpwd_ref, u, tmp){
918 		if(!strcmp(u->username, username)){
919 			if(u->password){
920 				if(password){
921 #ifdef WITH_TLS
922 					rc = pw__digest(password, u->salt, u->salt_len, hash, &hash_len);
923 					if(rc == MOSQ_ERR_SUCCESS){
924 						if(hash_len == u->password_len && !mosquitto__memcmp_const(u->password, hash, hash_len)){
925 							return MOSQ_ERR_SUCCESS;
926 						}else{
927 							return MOSQ_ERR_AUTH;
928 						}
929 					}else{
930 						return rc;
931 					}
932 #else
933 					if(!strcmp(u->password, password)){
934 						return MOSQ_ERR_SUCCESS;
935 					}
936 #endif
937 				}else{
938 					return MOSQ_ERR_AUTH;
939 				}
940 			}else{
941 				return MOSQ_ERR_SUCCESS;
942 			}
943 		}
944 	}
945 
946 	return MOSQ_ERR_AUTH;
947 }
948 
unpwd__cleanup(struct mosquitto__unpwd ** root,bool reload)949 static int unpwd__cleanup(struct mosquitto__unpwd **root, bool reload)
950 {
951 	struct mosquitto__unpwd *u, *tmp;
952 
953 	UNUSED(reload);
954 
955 	if(!root) return MOSQ_ERR_INVAL;
956 
957 	HASH_ITER(hh, *root, u, tmp){
958 		HASH_DEL(*root, u);
959 		mosquitto__free(u->password);
960 		mosquitto__free(u->username);
961 #ifdef WITH_TLS
962 		mosquitto__free(u->salt);
963 #endif
964 		mosquitto__free(u);
965 	}
966 
967 	*root = NULL;
968 
969 	return MOSQ_ERR_SUCCESS;
970 }
971 
972 
973 #ifdef WITH_TLS
security__disconnect_auth(struct mosquitto_db * db,struct mosquitto * context)974 static void security__disconnect_auth(struct mosquitto_db *db, struct mosquitto *context)
975 {
976 	if(context->protocol == mosq_p_mqtt5){
977 		send__disconnect(context, MQTT_RC_ADMINISTRATIVE_ACTION, NULL);
978 	}
979 	mosquitto__set_state(context, mosq_cs_disconnecting);
980 	do_disconnect(db, context, MOSQ_ERR_AUTH);
981 }
982 #endif
983 
984 /* Apply security settings after a reload.
985  * Includes:
986  * - Disconnecting anonymous users if appropriate
987  * - Disconnecting users with invalid passwords
988  * - Reapplying ACLs
989  */
mosquitto_security_apply_default(struct mosquitto_db * db)990 int mosquitto_security_apply_default(struct mosquitto_db *db)
991 {
992 	struct mosquitto *context, *ctxt_tmp;
993 	struct mosquitto__acl_user *acl_user_tail;
994 	bool allow_anonymous;
995 	struct mosquitto__security_options *security_opts = NULL;
996 #ifdef WITH_TLS
997 	int i;
998 	X509 *client_cert = NULL;
999 	X509_NAME *name;
1000 	X509_NAME_ENTRY *name_entry;
1001 	ASN1_STRING *name_asn1 = NULL;
1002 	struct mosquitto__listener *listener;
1003 #endif
1004 
1005 	if(!db) return MOSQ_ERR_INVAL;
1006 
1007 #ifdef WITH_TLS
1008 	for(i=0; i<db->config->listener_count; i++){
1009 		listener = &db->config->listeners[i];
1010 		if(listener && listener->ssl_ctx && (listener->cafile || listener->capath) && listener->crlfile && listener->require_certificate){
1011 			if(net__tls_server_ctx(listener)){
1012 				return 1;
1013 			}
1014 
1015 			if(net__tls_load_verify(listener)){
1016 				return 1;
1017 			}
1018 		}
1019 	}
1020 #endif
1021 
1022 	HASH_ITER(hh_id, db->contexts_by_id, context, ctxt_tmp){
1023 		/* Check for anonymous clients when allow_anonymous is false */
1024 		if(db->config->per_listener_settings){
1025 			if(context->listener){
1026 				allow_anonymous = context->listener->security_options.allow_anonymous;
1027 			}else{
1028 				/* Client not currently connected, so defer judgement until it does connect */
1029 				allow_anonymous = true;
1030 			}
1031 		}else{
1032 			allow_anonymous = db->config->security_options.allow_anonymous;
1033 		}
1034 
1035 		if(!allow_anonymous && !context->username){
1036 			mosquitto__set_state(context, mosq_cs_disconnecting);
1037 			do_disconnect(db, context, MOSQ_ERR_AUTH);
1038 			continue;
1039 		}
1040 
1041 		/* Check for connected clients that are no longer authorised */
1042 #ifdef WITH_TLS
1043 		if(context->listener && context->listener->ssl_ctx && (context->listener->use_identity_as_username || context->listener->use_subject_as_username)){
1044 			/* Client must have either a valid certificate, or valid PSK used as a username. */
1045 			if(!context->ssl){
1046 				if(context->protocol == mosq_p_mqtt5){
1047 					send__disconnect(context, MQTT_RC_ADMINISTRATIVE_ACTION, NULL);
1048 				}
1049 				mosquitto__set_state(context, mosq_cs_disconnecting);
1050 				do_disconnect(db, context, MOSQ_ERR_AUTH);
1051 				continue;
1052 			}
1053 #ifdef FINAL_WITH_TLS_PSK
1054 			if(context->listener->psk_hint){
1055 				/* Client should have provided an identity to get this far. */
1056 				if(!context->username){
1057 					security__disconnect_auth(db, context);
1058 					continue;
1059 				}
1060 			}else
1061 #endif /* FINAL_WITH_TLS_PSK */
1062 			{
1063 				/* Free existing credentials and then recover them. */
1064 				mosquitto__free(context->username);
1065 				context->username = NULL;
1066 				mosquitto__free(context->password);
1067 				context->password = NULL;
1068 
1069 				client_cert = SSL_get_peer_certificate(context->ssl);
1070 				if(!client_cert){
1071 					security__disconnect_auth(db, context);
1072 					continue;
1073 				}
1074 				name = X509_get_subject_name(client_cert);
1075 				if(!name){
1076 					X509_free(client_cert);
1077 					client_cert = NULL;
1078 					security__disconnect_auth(db, context);
1079 					continue;
1080 				}
1081 				if (context->listener->use_identity_as_username) { //use_identity_as_username
1082 					i = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
1083 					if(i == -1){
1084 						X509_free(client_cert);
1085 						client_cert = NULL;
1086 						security__disconnect_auth(db, context);
1087 						continue;
1088 					}
1089 					name_entry = X509_NAME_get_entry(name, i);
1090 					if(name_entry){
1091 						name_asn1 = X509_NAME_ENTRY_get_data(name_entry);
1092 						if (name_asn1 == NULL) {
1093 							X509_free(client_cert);
1094 							client_cert = NULL;
1095 							security__disconnect_auth(db, context);
1096 							continue;
1097 						}
1098 #if OPENSSL_VERSION_NUMBER < 0x10100000L
1099 						context->username = mosquitto__strdup((char *) ASN1_STRING_data(name_asn1));
1100 #else
1101 						context->username = mosquitto__strdup((char *) ASN1_STRING_get0_data(name_asn1));
1102 #endif
1103 						if(!context->username){
1104 							X509_free(client_cert);
1105 							client_cert = NULL;
1106 							security__disconnect_auth(db, context);
1107 							continue;
1108 						}
1109 						/* Make sure there isn't an embedded NUL character in the CN */
1110 						if ((size_t)ASN1_STRING_length(name_asn1) != strlen(context->username)) {
1111 							X509_free(client_cert);
1112 							client_cert = NULL;
1113 							security__disconnect_auth(db, context);
1114 							continue;
1115 						}
1116 					}
1117 				} else { // use_subject_as_username
1118 					BIO *subject_bio = BIO_new(BIO_s_mem());
1119 					X509_NAME_print_ex(subject_bio, X509_get_subject_name(client_cert), 0, XN_FLAG_RFC2253);
1120 					char *data_start = NULL;
1121 					long name_length = BIO_get_mem_data(subject_bio, &data_start);
1122 					char *subject = mosquitto__malloc(sizeof(char)*name_length+1);
1123 					if(!subject){
1124 						BIO_free(subject_bio);
1125 						X509_free(client_cert);
1126 						client_cert = NULL;
1127 						security__disconnect_auth(db, context);
1128 						continue;
1129 					}
1130 					memcpy(subject, data_start, name_length);
1131 					subject[name_length] = '\0';
1132 					BIO_free(subject_bio);
1133 					context->username = subject;
1134 				}
1135 				if(!context->username){
1136 					X509_free(client_cert);
1137 					client_cert = NULL;
1138 					security__disconnect_auth(db, context);
1139 					continue;
1140 				}
1141 				X509_free(client_cert);
1142 				client_cert = NULL;
1143 			}
1144 		}else
1145 #endif
1146 		{
1147 			/* Username/password check only if the identity/subject check not used */
1148 			if(mosquitto_unpwd_check(db, context, context->username, context->password) != MOSQ_ERR_SUCCESS){
1149 				mosquitto__set_state(context, mosq_cs_disconnecting);
1150 				do_disconnect(db, context, MOSQ_ERR_AUTH);
1151 				continue;
1152 			}
1153 		}
1154 
1155 
1156 		/* Check for ACLs and apply to user. */
1157 		if(db->config->per_listener_settings){
1158 			if(context->listener){
1159 				security_opts = &context->listener->security_options;
1160 			}else{
1161 				if(context->state != mosq_cs_active){
1162 					mosquitto__set_state(context, mosq_cs_disconnecting);
1163 					do_disconnect(db, context, MOSQ_ERR_AUTH);
1164 					continue;
1165 				}
1166 			}
1167 		}else{
1168 			security_opts = &db->config->security_options;
1169 		}
1170 
1171 		if(security_opts && security_opts->acl_list){
1172 			acl_user_tail = security_opts->acl_list;
1173 			while(acl_user_tail){
1174 				if(acl_user_tail->username){
1175 					if(context->username){
1176 						if(!strcmp(acl_user_tail->username, context->username)){
1177 							context->acl_list = acl_user_tail;
1178 							break;
1179 						}
1180 					}
1181 				}else{
1182 					if(!context->username){
1183 						context->acl_list = acl_user_tail;
1184 						break;
1185 					}
1186 				}
1187 				acl_user_tail = acl_user_tail->next;
1188 			}
1189 		}
1190 	}
1191 	return MOSQ_ERR_SUCCESS;
1192 }
1193 
mosquitto_psk_key_get_default(struct mosquitto_db * db,struct mosquitto * context,const char * hint,const char * identity,char * key,int max_key_len)1194 int mosquitto_psk_key_get_default(struct mosquitto_db *db, struct mosquitto *context, const char *hint, const char *identity, char *key, int max_key_len)
1195 {
1196 	struct mosquitto__unpwd *u, *tmp;
1197 	struct mosquitto__unpwd *psk_id_ref = NULL;
1198 
1199 	if(!db || !hint || !identity || !key) return MOSQ_ERR_INVAL;
1200 
1201 	if(db->config->per_listener_settings){
1202 		if(!context->listener) return MOSQ_ERR_INVAL;
1203 		if(!context->listener->psk_id) return MOSQ_ERR_PLUGIN_DEFER;
1204 		psk_id_ref = context->listener->psk_id;
1205 	}else{
1206 		if(!db->psk_id) return MOSQ_ERR_PLUGIN_DEFER;
1207 		psk_id_ref = db->psk_id;
1208 	}
1209 	if(!psk_id_ref) return MOSQ_ERR_PLUGIN_DEFER;
1210 
1211 	HASH_ITER(hh, psk_id_ref, u, tmp){
1212 		if(!strcmp(u->username, identity)){
1213 			strncpy(key, u->password, max_key_len);
1214 			return MOSQ_ERR_SUCCESS;
1215 		}
1216 	}
1217 
1218 	return MOSQ_ERR_AUTH;
1219 }
1220 
1221 #ifdef WITH_TLS
pw__digest(const char * password,const unsigned char * salt,unsigned int salt_len,unsigned char * hash,unsigned int * hash_len)1222 int pw__digest(const char *password, const unsigned char *salt, unsigned int salt_len, unsigned char *hash, unsigned int *hash_len)
1223 {
1224 	const EVP_MD *digest;
1225 #if OPENSSL_VERSION_NUMBER < 0x10100000L
1226 	EVP_MD_CTX context;
1227 
1228 	digest = EVP_get_digestbyname("sha512");
1229 	if(!digest){
1230 		// FIXME fprintf(stderr, "Error: Unable to create openssl digest.\n");
1231 		return 1;
1232 	}
1233 
1234 	EVP_MD_CTX_init(&context);
1235 	EVP_DigestInit_ex(&context, digest, NULL);
1236 	EVP_DigestUpdate(&context, password, strlen(password));
1237 	EVP_DigestUpdate(&context, salt, salt_len);
1238 	/* hash is assumed to be EVP_MAX_MD_SIZE bytes long. */
1239 	EVP_DigestFinal_ex(&context, hash, hash_len);
1240 	EVP_MD_CTX_cleanup(&context);
1241 #else
1242 	EVP_MD_CTX *context;
1243 
1244 	digest = EVP_get_digestbyname("sha512");
1245 	if(!digest){
1246 		// FIXME fprintf(stderr, "Error: Unable to create openssl digest.\n");
1247 		return 1;
1248 	}
1249 
1250 	context = EVP_MD_CTX_new();
1251 	EVP_DigestInit_ex(context, digest, NULL);
1252 	EVP_DigestUpdate(context, password, strlen(password));
1253 	EVP_DigestUpdate(context, salt, salt_len);
1254 	/* hash is assumed to be EVP_MAX_MD_SIZE bytes long. */
1255 	EVP_DigestFinal_ex(context, hash, hash_len);
1256 	EVP_MD_CTX_free(context);
1257 #endif
1258 
1259 	return MOSQ_ERR_SUCCESS;
1260 }
1261 
base64__decode(char * in,unsigned char ** decoded,unsigned int * decoded_len)1262 int base64__decode(char *in, unsigned char **decoded, unsigned int *decoded_len)
1263 {
1264 	BIO *bmem, *b64;
1265 	int slen;
1266 
1267 	slen = strlen(in);
1268 
1269 	b64 = BIO_new(BIO_f_base64());
1270 	if(!b64){
1271 		return 1;
1272 	}
1273 	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
1274 
1275 	bmem = BIO_new(BIO_s_mem());
1276 	if(!bmem){
1277 		BIO_free_all(b64);
1278 		return 1;
1279 	}
1280 	b64 = BIO_push(b64, bmem);
1281 	BIO_write(bmem, in, slen);
1282 
1283 	if(BIO_flush(bmem) != 1){
1284 		BIO_free_all(b64);
1285 		return 1;
1286 	}
1287 	*decoded = mosquitto__calloc(slen, 1);
1288 	if(!(*decoded)){
1289 		BIO_free_all(b64);
1290 		return 1;
1291 	}
1292 	*decoded_len =  BIO_read(b64, *decoded, slen);
1293 	BIO_free_all(b64);
1294 
1295 	if(*decoded_len <= 0){
1296 		mosquitto__free(*decoded);
1297 		*decoded = NULL;
1298 		*decoded_len = 0;
1299 		return 1;
1300 	}
1301 
1302 	return 0;
1303 }
1304 
1305 #endif
1306