1 /**
2  * @file src/account.c  User-Agent account
3  *
4  * Copyright (C) 2010 Creytiv.com
5  */
6 #include <string.h>
7 #include <re.h>
8 #include <baresip.h>
9 #include "core.h"
10 
11 
12 enum {
13 	REG_INTERVAL    = 3600,
14 };
15 
16 
destructor(void * arg)17 static void destructor(void *arg)
18 {
19 	struct account *acc = arg;
20 	size_t i;
21 
22 	list_clear(&acc->aucodecl);
23 	list_clear(&acc->vidcodecl);
24 	mem_deref(acc->auth_user);
25 	mem_deref(acc->auth_pass);
26 	for (i=0; i<ARRAY_SIZE(acc->outboundv); i++)
27 		mem_deref(acc->outboundv[i]);
28 	mem_deref(acc->regq);
29 	mem_deref(acc->rtpkeep);
30 	mem_deref(acc->sipnat);
31 	mem_deref(acc->stun_user);
32 	mem_deref(acc->stun_pass);
33 	mem_deref(acc->stun_host);
34 	mem_deref(acc->mnatid);
35 	mem_deref(acc->mencid);
36 	mem_deref(acc->aor);
37 	mem_deref(acc->dispname);
38 	mem_deref(acc->buf);
39 }
40 
41 
param_dstr(char ** dstr,const struct pl * params,const char * name)42 static int param_dstr(char **dstr, const struct pl *params, const char *name)
43 {
44 	struct pl pl;
45 
46 	if (msg_param_decode(params, name, &pl))
47 		return 0;
48 
49 	return pl_strdup(dstr, &pl);
50 }
51 
52 
param_u32(uint32_t * v,const struct pl * params,const char * name)53 static int param_u32(uint32_t *v, const struct pl *params, const char *name)
54 {
55 	struct pl pl;
56 
57 	if (msg_param_decode(params, name, &pl))
58 		return 0;
59 
60 	*v = pl_u32(&pl);
61 
62 	return 0;
63 }
64 
65 
66 /*
67  * Decode STUN parameters, inspired by RFC 7064
68  *
69  * See RFC 3986:
70  *
71  *     Use of the format "user:password" in the userinfo field is
72  *     deprecated.
73  *
74  */
stunsrv_decode(struct account * acc,const struct sip_addr * aor)75 static int stunsrv_decode(struct account *acc, const struct sip_addr *aor)
76 {
77 	struct pl srv, tmp;
78 	struct uri uri;
79 	int err;
80 
81 	if (!acc || !aor)
82 		return EINVAL;
83 
84 	memset(&uri, 0, sizeof(uri));
85 
86 	if (0 == msg_param_decode(&aor->params, "stunserver", &srv)) {
87 
88 		info("using stunserver: '%r'\n", &srv);
89 
90 		err = uri_decode(&uri, &srv);
91 		if (err) {
92 			warning("account: %r: decode failed: %m\n", &srv, err);
93 			memset(&uri, 0, sizeof(uri));
94 		}
95 
96 		if (0 != pl_strcasecmp(&uri.scheme, "stun")) {
97 			warning("account: unknown scheme: %r\n", &uri.scheme);
98 			return EINVAL;
99 		}
100 	}
101 
102 	err = 0;
103 
104 	if (0 == msg_param_exists(&aor->params, "stunuser", &tmp))
105 		err |= param_dstr(&acc->stun_user, &aor->params, "stunuser");
106 	else if (pl_isset(&uri.user))
107 		err |= pl_strdup(&acc->stun_user, &uri.user);
108 	else
109 		err |= pl_strdup(&acc->stun_user, &aor->uri.user);
110 
111 	if (0 == msg_param_exists(&aor->params, "stunpass", &tmp))
112 		err |= param_dstr(&acc->stun_pass, &aor->params, "stunpass");
113 	else if (pl_isset(&uri.password))
114 		err |= pl_strdup(&acc->stun_pass, &uri.password);
115 	else if (acc->auth_pass)
116 		err |= str_dup(&acc->stun_pass, acc->auth_pass);
117 
118 	if (pl_isset(&uri.host))
119 		err |= pl_strdup(&acc->stun_host, &uri.host);
120 	else
121 		err |= pl_strdup(&acc->stun_host, &aor->uri.host);
122 
123 	acc->stun_port = uri.port;
124 
125 	return err;
126 }
127 
128 
129 /** Decode media parameters */
media_decode(struct account * acc,const struct pl * prm)130 static int media_decode(struct account *acc, const struct pl *prm)
131 {
132 	int err = 0;
133 
134 	if (!acc || !prm)
135 		return EINVAL;
136 
137 	err |= param_dstr(&acc->mencid,  prm, "mediaenc");
138 	err |= param_dstr(&acc->mnatid,  prm, "medianat");
139 	err |= param_dstr(&acc->rtpkeep, prm, "rtpkeep" );
140 	err |= param_u32(&acc->ptime,    prm, "ptime"   );
141 
142 	return err;
143 }
144 
145 
146 /* Decode answermode parameter */
answermode_decode(struct account * prm,const struct pl * pl)147 static void answermode_decode(struct account *prm, const struct pl *pl)
148 {
149 	struct pl amode;
150 
151 	if (0 == msg_param_decode(pl, "answermode", &amode)) {
152 
153 		if (0 == pl_strcasecmp(&amode, "manual")) {
154 			prm->answermode = ANSWERMODE_MANUAL;
155 		}
156 		else if (0 == pl_strcasecmp(&amode, "early")) {
157 			prm->answermode = ANSWERMODE_EARLY;
158 		}
159 		else if (0 == pl_strcasecmp(&amode, "auto")) {
160 			prm->answermode = ANSWERMODE_AUTO;
161 		}
162 		else {
163 			warning("account: answermode unknown (%r)\n", &amode);
164 			prm->answermode = ANSWERMODE_MANUAL;
165 		}
166 	}
167 }
168 
169 
csl_parse(struct pl * pl,char * str,size_t sz)170 static int csl_parse(struct pl *pl, char *str, size_t sz)
171 {
172 	struct pl ws = PL_INIT, val, ws2 = PL_INIT, cma = PL_INIT;
173 	int err;
174 
175 	err = re_regex(pl->p, pl->l, "[ \t]*[^, \t]+[ \t]*[,]*",
176 		       &ws, &val, &ws2, &cma);
177 	if (err)
178 		return err;
179 
180 	pl_advance(pl, ws.l + val.l + ws2.l + cma.l);
181 
182 	(void)pl_strcpy(&val, str, sz);
183 
184 	return 0;
185 }
186 
187 
audio_codecs_decode(struct account * acc,const struct pl * prm)188 static int audio_codecs_decode(struct account *acc, const struct pl *prm)
189 {
190 	struct list *aucodecl = baresip_aucodecl();
191 	struct pl tmp;
192 
193 	if (!acc || !prm)
194 		return EINVAL;
195 
196 	list_init(&acc->aucodecl);
197 
198 	if (0 == msg_param_exists(prm, "audio_codecs", &tmp)) {
199 		struct pl acs;
200 		char cname[64];
201 		unsigned i = 0;
202 
203 		if (msg_param_decode(prm, "audio_codecs", &acs))
204 			return 0;
205 
206 		while (0 == csl_parse(&acs, cname, sizeof(cname))) {
207 			struct aucodec *ac;
208 			struct pl pl_cname, pl_srate, pl_ch = PL_INIT;
209 			uint32_t srate = 8000;
210 			uint8_t ch = 1;
211 
212 			/* Format: "codec/srate/ch" */
213 			if (0 == re_regex(cname, str_len(cname),
214 					  "[^/]+/[0-9]+[/]*[0-9]*",
215 					  &pl_cname, &pl_srate,
216 					  NULL, &pl_ch)) {
217 				(void)pl_strcpy(&pl_cname, cname,
218 						sizeof(cname));
219 				srate = pl_u32(&pl_srate);
220 				if (pl_isset(&pl_ch))
221 					ch = pl_u32(&pl_ch);
222 			}
223 
224 			ac = (struct aucodec *)aucodec_find(aucodecl,
225 							    cname, srate, ch);
226 			if (!ac) {
227 				warning("account: audio codec not found:"
228 					" %s/%u/%d\n",
229 					cname, srate, ch);
230 				continue;
231 			}
232 
233 			/* NOTE: static list with references to aucodec */
234 			list_append(&acc->aucodecl, &acc->acv[i++], ac);
235 
236 			if (i >= ARRAY_SIZE(acc->acv))
237 				break;
238 		}
239 	}
240 
241 	return 0;
242 }
243 
244 
245 #ifdef USE_VIDEO
video_codecs_decode(struct account * acc,const struct pl * prm)246 static int video_codecs_decode(struct account *acc, const struct pl *prm)
247 {
248 	struct list *vidcodecl = baresip_vidcodecl();
249 	struct pl tmp;
250 
251 	if (!acc || !prm)
252 		return EINVAL;
253 
254 	list_init(&acc->vidcodecl);
255 
256 	if (0 == msg_param_exists(prm, "video_codecs", &tmp)) {
257 		struct pl vcs;
258 		char cname[64];
259 		unsigned i = 0;
260 
261 		if (msg_param_decode(prm, "video_codecs", &vcs))
262 			return 0;
263 
264 		while (0 == csl_parse(&vcs, cname, sizeof(cname))) {
265 			struct vidcodec *vc;
266 
267 			vc = (struct vidcodec *)vidcodec_find(vidcodecl,
268 							      cname, NULL);
269 			if (!vc) {
270 				warning("account: video codec not found: %s\n",
271 					cname);
272 				continue;
273 			}
274 
275 			/* NOTE: static list with references to vidcodec */
276 			list_append(&acc->vidcodecl, &acc->vcv[i++], vc);
277 
278 			if (i >= ARRAY_SIZE(acc->vcv))
279 				break;
280 		}
281 	}
282 
283 	return 0;
284 }
285 #endif
286 
287 
sip_params_decode(struct account * acc,const struct sip_addr * aor)288 static int sip_params_decode(struct account *acc, const struct sip_addr *aor)
289 {
290 	struct pl auth_user;
291 	size_t i;
292 	int err = 0;
293 
294 	if (!acc || !aor)
295 		return EINVAL;
296 
297 	acc->regint = REG_INTERVAL + (rand_u32()&0xff);
298 	err |= param_u32(&acc->regint, &aor->params, "regint");
299 
300 	acc->pubint = 0;
301 	err |= param_u32(&acc->pubint, &aor->params, "pubint");
302 
303 	err |= param_dstr(&acc->regq, &aor->params, "regq");
304 
305 	for (i=0; i<ARRAY_SIZE(acc->outboundv); i++) {
306 
307 		char expr[16] = "outbound";
308 
309 		expr[8] = i + 1 + 0x30;
310 		expr[9] = '\0';
311 
312 		err |= param_dstr(&acc->outboundv[i], &aor->params, expr);
313 	}
314 
315 	/* backwards compat */
316 	if (!acc->outboundv[0]) {
317 		err |= param_dstr(&acc->outboundv[0], &aor->params,
318 				  "outbound");
319 	}
320 
321 	err |= param_dstr(&acc->sipnat, &aor->params, "sipnat");
322 
323 	if (0 == msg_param_decode(&aor->params, "auth_user", &auth_user))
324 		err |= pl_strdup(&acc->auth_user, &auth_user);
325 	else
326 		err |= pl_strdup(&acc->auth_user, &aor->uri.user);
327 
328 	if (pl_isset(&aor->dname))
329 		err |= pl_strdup(&acc->dispname, &aor->dname);
330 
331 	return err;
332 }
333 
334 
encode_uri_user(struct re_printf * pf,const struct uri * uri)335 static int encode_uri_user(struct re_printf *pf, const struct uri *uri)
336 {
337 	struct uri uuri = *uri;
338 
339 	uuri.password = uuri.params = uuri.headers = pl_null;
340 
341 	return uri_encode(pf, &uuri);
342 }
343 
344 
account_alloc(struct account ** accp,const char * sipaddr)345 int account_alloc(struct account **accp, const char *sipaddr)
346 {
347 	struct account *acc;
348 	struct pl pl;
349 	int err = 0;
350 
351 	if (!accp || !sipaddr)
352 		return EINVAL;
353 
354 	acc = mem_zalloc(sizeof(*acc), destructor);
355 	if (!acc)
356 		return ENOMEM;
357 
358 	err = str_dup(&acc->buf, sipaddr);
359 	if (err)
360 		goto out;
361 
362 	pl_set_str(&pl, acc->buf);
363 	err = sip_addr_decode(&acc->laddr, &pl);
364 	if (err) {
365 		warning("account: error parsing SIP address: '%r'\n", &pl);
366 		goto out;
367 	}
368 
369 	acc->luri = acc->laddr.uri;
370 	acc->luri.password = pl_null;
371 
372 	err = re_sdprintf(&acc->aor, "%H", encode_uri_user, &acc->luri);
373 	if (err)
374 		goto out;
375 
376 	/* Decode parameters */
377 	acc->ptime = 20;
378 	err |= sip_params_decode(acc, &acc->laddr);
379 	       answermode_decode(acc, &acc->laddr.params);
380 	err |= audio_codecs_decode(acc, &acc->laddr.params);
381 #ifdef USE_VIDEO
382 	err |= video_codecs_decode(acc, &acc->laddr.params);
383 #endif
384 	err |= media_decode(acc, &acc->laddr.params);
385 	if (err)
386 		goto out;
387 
388 	/* optional password prompt */
389 	if (pl_isset(&acc->laddr.uri.password)) {
390 
391 		warning("account: username:password is now deprecated"
392 			" please use ;auth_pass=xxx instead\n");
393 
394 		err = re_sdprintf(&acc->auth_pass, "%H",
395 				  uri_password_unescape,
396 				  &acc->laddr.uri.password);
397 		if (err)
398 			goto out;
399 	}
400 	else if (0 == msg_param_decode(&acc->laddr.params, "auth_pass", &pl)) {
401 		err = pl_strdup(&acc->auth_pass, &pl);
402 		if (err)
403 			goto out;
404 	}
405 
406 	err = stunsrv_decode(acc, &acc->laddr);
407 	if (err)
408 		goto out;
409 
410 	if (acc->mnatid) {
411 		acc->mnat = mnat_find(baresip_mnatl(), acc->mnatid);
412 		if (!acc->mnat) {
413 			warning("account: medianat not found: `%s'\n",
414 				acc->mnatid);
415 		}
416 	}
417 
418 	if (acc->mencid) {
419 		acc->menc = menc_find(baresip_mencl(), acc->mencid);
420 		if (!acc->menc) {
421 			warning("account: mediaenc not found: `%s'\n",
422 				acc->mencid);
423 		}
424 	}
425 
426  out:
427 	if (err)
428 		mem_deref(acc);
429 	else
430 		*accp = acc;
431 
432 	return err;
433 }
434 
435 
account_set_auth_pass(struct account * acc,const char * pass)436 int account_set_auth_pass(struct account *acc, const char *pass)
437 {
438 	if (!acc)
439 		return EINVAL;
440 
441 	acc->auth_pass = mem_deref(acc->auth_pass);
442 
443 	if (pass)
444 		return str_dup(&acc->auth_pass, pass);
445 
446 	return 0;
447 }
448 
449 
450 /**
451  * Sets the displayed name. Pass null in dname to disable display name
452  *
453  * @param acc      User-Agent account
454  * @param dname    Display name (NULL to disable)
455  *
456  * @return 0 if success, otherwise errorcode
457  */
account_set_display_name(struct account * acc,const char * dname)458 int account_set_display_name(struct account *acc, const char *dname)
459 {
460 	if (!acc)
461 		return EINVAL;
462 
463 	acc->dispname = mem_deref(acc->dispname);
464 
465 	if (dname)
466 		return str_dup(&acc->dispname, dname);
467 
468 	return 0;
469 }
470 
471 
472 /**
473  * Authenticate a User-Agent (UA)
474  *
475  * @param acc      User-Agent account
476  * @param username Pointer to allocated username string
477  * @param password Pointer to allocated password string
478  * @param realm    Realm string
479  *
480  * @return 0 if success, otherwise errorcode
481  */
account_auth(const struct account * acc,char ** username,char ** password,const char * realm)482 int account_auth(const struct account *acc, char **username, char **password,
483 		 const char *realm)
484 {
485 	if (!acc)
486 		return EINVAL;
487 
488 	(void)realm;
489 
490 	*username = mem_ref(acc->auth_user);
491 	*password = mem_ref(acc->auth_pass);
492 
493 	return 0;
494 }
495 
496 
account_aucodecl(const struct account * acc)497 struct list *account_aucodecl(const struct account *acc)
498 {
499 	return (acc && !list_isempty(&acc->aucodecl))
500 		? (struct list *)&acc->aucodecl : baresip_aucodecl();
501 }
502 
503 
504 #ifdef USE_VIDEO
account_vidcodecl(const struct account * acc)505 struct list *account_vidcodecl(const struct account *acc)
506 {
507 	return (acc && !list_isempty(&acc->vidcodecl))
508 		? (struct list *)&acc->vidcodecl : baresip_vidcodecl();
509 }
510 #endif
511 
512 
account_laddr(const struct account * acc)513 struct sip_addr *account_laddr(const struct account *acc)
514 {
515 	return acc ? (struct sip_addr *)&acc->laddr : NULL;
516 }
517 
518 
account_regint(const struct account * acc)519 uint32_t account_regint(const struct account *acc)
520 {
521 	return acc ? acc->regint : 0;
522 }
523 
524 
account_pubint(const struct account * acc)525 uint32_t account_pubint(const struct account *acc)
526 {
527 	return acc ? acc->pubint : 0;
528 }
529 
530 
account_answermode(const struct account * acc)531 enum answermode account_answermode(const struct account *acc)
532 {
533 	return acc ? acc->answermode : ANSWERMODE_MANUAL;
534 }
535 
536 
account_aor(const struct account * acc)537 const char *account_aor(const struct account *acc)
538 {
539 	return acc ? acc->aor : NULL;
540 }
541 
542 
543 /**
544  * Get the authentication username of an account
545  *
546  * @param acc User-Agent account
547  *
548  * @return Authentication username
549  */
account_auth_user(const struct account * acc)550 const char *account_auth_user(const struct account *acc)
551 {
552 	return acc ? acc->auth_user : NULL;
553 }
554 
555 
556 /**
557  * Get the SIP authentication password of an account
558  *
559  * @param acc User-Agent account
560  *
561  * @return Authentication password
562  */
account_auth_pass(const struct account * acc)563 const char *account_auth_pass(const struct account *acc)
564 {
565 	return acc ? acc->auth_pass : NULL;
566 }
567 
568 
569 /**
570  * Get the outbound SIP server of an account
571  *
572  * @param acc User-Agent account
573  * @param ix  Index starting at zero
574  *
575  * @return Outbound SIP proxy, NULL if not configured
576  */
account_outbound(const struct account * acc,unsigned ix)577 const char *account_outbound(const struct account *acc, unsigned ix)
578 {
579 	if (!acc || ix >= ARRAY_SIZE(acc->outboundv))
580 		return NULL;
581 
582 	return acc->outboundv[ix];
583 }
584 
585 
586 /**
587  * Get the audio packet-time (ptime) of an account
588  *
589  * @param acc User-Agent account
590  *
591  * @return Packet-time (ptime)
592  */
account_ptime(const struct account * acc)593 uint32_t account_ptime(const struct account *acc)
594 {
595 	return acc ? acc->ptime : 0;
596 }
597 
598 
599 /**
600  * Get the STUN username of an account
601  *
602  * @param acc User-Agent account
603  *
604  * @return STUN username
605  */
account_stun_user(const struct account * acc)606 const char *account_stun_user(const struct account *acc)
607 {
608 	return acc ? acc->stun_user : NULL;
609 }
610 
611 
612 /**
613  * Get the STUN password of an account
614  *
615  * @param acc User-Agent account
616  *
617  * @return STUN password
618  */
account_stun_pass(const struct account * acc)619 const char *account_stun_pass(const struct account *acc)
620 {
621 	return acc ? acc->stun_pass : NULL;
622 }
623 
624 
625 /**
626  * Get the STUN hostname of an account
627  *
628  * @param acc User-Agent account
629  *
630  * @return STUN hostname
631  */
account_stun_host(const struct account * acc)632 const char *account_stun_host(const struct account *acc)
633 {
634 	return acc ? acc->stun_host : NULL;
635 }
636 
637 
answermode_str(enum answermode mode)638 static const char *answermode_str(enum answermode mode)
639 {
640 	switch (mode) {
641 
642 	case ANSWERMODE_MANUAL: return "manual";
643 	case ANSWERMODE_EARLY:  return "early";
644 	case ANSWERMODE_AUTO:   return "auto";
645 	default: return "???";
646 	}
647 }
648 
649 
account_debug(struct re_printf * pf,const struct account * acc)650 int account_debug(struct re_printf *pf, const struct account *acc)
651 {
652 	struct le *le;
653 	size_t i;
654 	int err = 0;
655 
656 	if (!acc)
657 		return 0;
658 
659 	err |= re_hprintf(pf, "\nAccount:\n");
660 
661 	err |= re_hprintf(pf, " address:      %s\n", acc->buf);
662 	err |= re_hprintf(pf, " luri:         %H\n",
663 			  uri_encode, &acc->luri);
664 	err |= re_hprintf(pf, " aor:          %s\n", acc->aor);
665 	err |= re_hprintf(pf, " dispname:     %s\n", acc->dispname);
666 	err |= re_hprintf(pf, " answermode:   %s\n",
667 			  answermode_str(acc->answermode));
668 	if (!list_isempty(&acc->aucodecl)) {
669 		err |= re_hprintf(pf, " audio_codecs:");
670 		for (le = list_head(&acc->aucodecl); le; le = le->next) {
671 			const struct aucodec *ac = le->data;
672 			err |= re_hprintf(pf, " %s/%u/%u",
673 					  ac->name, ac->srate, ac->ch);
674 		}
675 		err |= re_hprintf(pf, "\n");
676 	}
677 	err |= re_hprintf(pf, " auth_user:    %s\n", acc->auth_user);
678 	err |= re_hprintf(pf, " mediaenc:     %s\n",
679 			  acc->mencid ? acc->mencid : "none");
680 	err |= re_hprintf(pf, " medianat:     %s\n",
681 			  acc->mnatid ? acc->mnatid : "none");
682 	for (i=0; i<ARRAY_SIZE(acc->outboundv); i++) {
683 		if (acc->outboundv[i]) {
684 			err |= re_hprintf(pf, " outbound%d:    %s\n",
685 					  i+1, acc->outboundv[i]);
686 		}
687 	}
688 	err |= re_hprintf(pf, " ptime:        %u\n", acc->ptime);
689 	err |= re_hprintf(pf, " regint:       %u\n", acc->regint);
690 	err |= re_hprintf(pf, " pubint:       %u\n", acc->pubint);
691 	err |= re_hprintf(pf, " regq:         %s\n", acc->regq);
692 	err |= re_hprintf(pf, " rtpkeep:      %s\n", acc->rtpkeep);
693 	err |= re_hprintf(pf, " sipnat:       %s\n", acc->sipnat);
694 	err |= re_hprintf(pf, " stunserver:   stun:%s@%s:%u\n",
695 			  acc->stun_user, acc->stun_host, acc->stun_port);
696 	if (!list_isempty(&acc->vidcodecl)) {
697 		err |= re_hprintf(pf, " video_codecs:");
698 		for (le = list_head(&acc->vidcodecl); le; le = le->next) {
699 			const struct vidcodec *vc = le->data;
700 			err |= re_hprintf(pf, " %s", vc->name);
701 		}
702 		err |= re_hprintf(pf, "\n");
703 	}
704 
705 	return err;
706 }
707