Revision 38109c95

View differences:

conf/janus.plugin.sip.cfg.sample
15 15

  
16 16
; User-Agent string to be used
17 17
; user_agent = Cool WebRTC Gateway
18

  
18 19
; Expiration time for registrations
19 20
register_ttl = 3600
20 21

  
conf/janus.plugin.sipre.cfg.sample
3 3
; guessed from the system
4 4
;local_ip = 1.2.3.4
5 5

  
6
; Enable local keep-alives to keep the registration open. Keep-alives are
7
; sent in the form of OPTIONS requests, at the given interval inseconds.
8
; (0 to disable)
9
keepalive_interval = 120
10

  
11
; Indicate if the server is behind NAT. If so, the server will use STUN
12
; to guess its own public IP address and use it in the Contact header of
13
; outgoing requests
14
behind_nat = no
15

  
16 6
; User-Agent string to be used
17 7
; user_agent = Cool WebRTC Gateway
8

  
18 9
; Expiration time for registrations
19 10
register_ttl = 3600
20 11

  
html/sipretest.html
11 11
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.2/js/bootstrap.min.js"></script>
12 12
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.1.0/bootbox.min.js"></script>
13 13
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/spin.js/2.3.2/spin.min.js"></script>
14
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-md5/2.6.0/js/md5.min.js"></script>
15 14
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.3/toastr.min.js"></script>
16 15
<script type="text/javascript" src="janus.js" ></script>
17 16
<script type="text/javascript" src="sipretest.js"></script>
......
103 102
									</button>
104 103
									<ul id="registerlist" class="dropdown-menu" role="menu">
105 104
										<li><a href='#' id='secret'>Register using plain secret</a></li>
106
										<li class="disabled"><a href='#' id='ha1secret'>Register using HA1 secret</a></li>
107 105
										<li><a href='#' id='guest'>Register as a guest (no secret)</a></li>
108 106
									</ul>
109 107
								</div>
html/sipretest.js
104 104
											case "secret":
105 105
												bootbox.alert("Using this approach you'll provide a plain secret to REGISTER");
106 106
												break;
107
											case "ha1secret":
108
												bootbox.alert("Using this approach might not work with Asterisk because the generated HA1 secret could have the wrong realm");
109
												break;
110 107
											case "guest":
111 108
												bootbox.alert("Using this approach you'll try to REGISTER as a guest, that is without providing any secret");
112 109
												break;
......
548 545
	if(displayname !== "") {
549 546
		register.display_name = displayname;
550 547
	}
551
	if(selectedApproach === "secret") {
552
		// Use the plain secret
553
		register["secret"] = password;
554
	} else if(selectedApproach === "ha1secret") {
555
		var sip_user = username.substring(4, username.indexOf('@'));    /* skip sip: */
556
		var sip_domain = username.substring(username.indexOf('@')+1);
557
		register["ha1_secret"] = md5(sip_user+':'+sip_domain+':'+password);
558
	}
548
	// Use the plain secret
549
	register["secret"] = password;
559 550
	if(sipserver === "") {
560 551
		bootbox.confirm("You didn't specify a SIP Registrar to use: this will cause the plugin to try and conduct a standard (<a href='https://tools.ietf.org/html/rfc3263' target='_blank'>RFC3263</a>) lookup. If this is not what you want or you don't know what this means, hit Cancel and provide a SIP Registrar instead'",
561 552
			function(result) {
plugins/janus_sipre.c
148 148
	{"sips", JANUS_JSON_BOOL, 0},
149 149
	{"username", JANUS_JSON_STRING, JANUS_JSON_PARAM_REQUIRED},
150 150
	{"secret", JANUS_JSON_STRING, 0},
151
	{"ha1_secret", JANUS_JSON_STRING, 0},
152 151
	{"authuser", JANUS_JSON_STRING, 0},
153 152
	{"headers", JANUS_JSON_OBJECT, 0},
154 153
	{"refresh", JANUS_JSON_BOOL, 0}
......
192 191
static janus_callbacks *gateway = NULL;
193 192

  
194 193
static char *local_ip = NULL;
195
static int keepalive_interval = 120;
196 194
static gboolean behind_nat = FALSE;
197 195
static char *user_agent;
198 196
#define JANUS_DEFAULT_REGISTER_TTL	3600
......
438 436

  
439 437
typedef struct janus_sipre_account {
440 438
	char *identity;
441
	char *user_agent;		/* Used to override the general UA string */
442 439
	gboolean sips;
443 440
	char *username;
444 441
	char *display_name;		/* Used for outgoing calls in the From header */
......
743 740
					old_sessions = g_list_delete_link(old_sessions, sl);
744 741
					sl = rm;
745 742
					sipsess_close_all(session->stack.sess_sock);
746
					mem_deref(session->stack.dns_client);
747
					mem_deref(session->stack.sipstack);
743
					sip_close(session->stack.sipstack, FALSE);
744
					session->stack.sipstack = NULL;
748 745
					if(session->account.identity) {
749 746
					    g_hash_table_remove(identities, session->account.identity);
750 747
					    g_free(session->account.identity);
......
771 768
					    g_free(session->account.display_name);
772 769
					    session->account.display_name = NULL;
773 770
					}
774
					if(session->account.user_agent) {
775
					    g_free(session->account.user_agent);
776
					    session->account.user_agent = NULL;
777
					}
778 771
					if(session->account.authuser) {
779 772
					    g_free(session->account.authuser);
780 773
					    session->account.authuser = NULL;
......
891 884
			}
892 885
		}
893 886

  
894
		item = janus_config_get_item_drilldown(config, "general", "keepalive_interval");
895
		if(item && item->value) {
896
			keepalive_interval = atoi(item->value);
897
		}
898
		JANUS_LOG(LOG_VERB, "SIPre keep-alive interval set to %d seconds\n", keepalive_interval);
899

  
900 887
		item = janus_config_get_item_drilldown(config, "general", "register_ttl");
901 888
		if(item && item->value) {
902 889
			register_ttl = atol(item->value);
890
			if(register_ttl <= 0) {
891
				JANUS_LOG(LOG_WARN, "Invalid value of register_ttl, using default instead\n");
892
				register_ttl = JANUS_DEFAULT_REGISTER_TTL;
893
			}
903 894
		}
904 895
		JANUS_LOG(LOG_VERB, "SIPre registration TTL set to %d seconds\n", register_ttl);
905 896

  
......
1075 1066
	session->account.sips = TRUE;
1076 1067
	session->account.username = NULL;
1077 1068
	session->account.display_name = NULL;
1078
	session->account.user_agent = NULL;
1079 1069
	session->account.authuser = NULL;
1080 1070
	session->account.secret = NULL;
1081 1071
	session->account.secret_type = janus_sipre_secret_type_unknown;
......
1189 1179
	json_t *info = json_object();
1190 1180
	json_object_set_new(info, "username", session->account.username ? json_string(session->account.username) : NULL);
1191 1181
	json_object_set_new(info, "display_name", session->account.display_name ? json_string(session->account.display_name) : NULL);
1192
	json_object_set_new(info, "user_agent", session->account.user_agent ? json_string(session->account.user_agent) : NULL);
1193 1182
	json_object_set_new(info, "identity", session->account.identity ? json_string(session->account.identity) : NULL);
1194 1183
	json_object_set_new(info, "registration_status", json_string(janus_sipre_registration_status_string(session->account.registration_status)));
1195 1184
	json_object_set_new(info, "call_status", json_string(janus_sipre_call_status_string(session->status)));
......
1542 1531
			if(reg_ttl && json_is_integer(reg_ttl))
1543 1532
				ttl = json_integer_value(reg_ttl);
1544 1533
			if(ttl <= 0)
1545
				ttl = JANUS_DEFAULT_REGISTER_TTL;
1534
				ttl = register_ttl;
1546 1535
			session->stack.expires = ttl;
1547 1536

  
1548 1537
			/* Parse display name */
......
1551 1540
			if(display_name && json_is_string(display_name))
1552 1541
				display_name_text = json_string_value(display_name);
1553 1542

  
1554
			/* Parse user agent */
1555
			const char* user_agent_text = NULL;
1556
			json_t *user_agent = json_object_get(root, "user_agent");
1557
			if(user_agent && json_is_string(user_agent))
1558
				user_agent_text = json_string_value(user_agent);
1559

  
1560 1543
			/* Now the user part (always needed, even for the guest case) */
1561 1544
			json_t *username = json_object_get(root, "username");
1562 1545
			if(!username) {
......
1589 1572
				send_register = FALSE;
1590 1573
			} else {
1591 1574
				json_t *secret = json_object_get(root, "secret");
1592
				json_t *ha1_secret = json_object_get(root, "ha1_secret");
1593 1575
				json_t *authuser = json_object_get(root, "authuser");
1594
				if(!secret && !ha1_secret) {
1576
				if(!secret) {
1595 1577
					g_free(user_id);
1596 1578
					g_free(user_host);
1597
					JANUS_LOG(LOG_ERR, "Missing element (secret or ha1_secret)\n");
1579
					JANUS_LOG(LOG_ERR, "Missing element (secret)\n");
1598 1580
					error_code = JANUS_SIPRE_ERROR_MISSING_ELEMENT;
1599
					g_snprintf(error_cause, 512, "Missing element (secret or ha1_secret)");
1600
					goto error;
1601
				}
1602
				if(secret && ha1_secret) {
1603
					g_free(user_id);
1604
					g_free(user_host);
1605
					JANUS_LOG(LOG_ERR, "Conflicting elements specified (secret and ha1_secret)\n");
1606
					error_code = JANUS_SIPRE_ERROR_INVALID_ELEMENT;
1607
					g_snprintf(error_cause, 512, "Conflicting elements specified (secret and ha1_secret)");
1581
					g_snprintf(error_cause, 512, "Missing element (secret)");
1608 1582
					goto error;
1609 1583
				}
1610
				if(secret) {
1611
					secret_text = json_string_value(secret);
1612
					secret_type = janus_sipre_secret_type_plaintext;
1613
				} else {
1614
					secret_text = json_string_value(ha1_secret);
1615
					secret_type = janus_sipre_secret_type_hashed;
1616
				}
1584
				secret_text = json_string_value(secret);
1585
				secret_type = janus_sipre_secret_type_plaintext;
1617 1586
				if(authuser) {
1618 1587
					authuser_text = json_string_value(authuser);
1619 1588
				}
......
1653 1622
				if(session->account.outbound_proxy != NULL)
1654 1623
					g_free(session->account.outbound_proxy);
1655 1624
				session->account.outbound_proxy = NULL;
1656
				if(session->account.user_agent != NULL)
1657
					g_free(session->account.user_agent);
1658
				session->account.user_agent = NULL;
1659 1625
				session->account.registration_status = janus_sipre_registration_status_unregistered;
1660 1626
			}
1661 1627
			session->account.identity = g_strdup(username_text);
......
1668 1634
			if(display_name_text) {
1669 1635
				session->account.display_name = g_strdup(display_name_text);
1670 1636
			}
1671
			if(user_agent_text) {
1672
				session->account.user_agent = g_strdup(user_agent_text);
1673
			}
1674 1637
			if(proxy_text) {
1675 1638
				session->account.proxy = g_strdup(proxy_text);
1676 1639
			} else {
......
3777 3740
				return;
3778 3741
			}
3779 3742
			/* Let's allocate the stack now */
3780
			err = sip_alloc(&session->stack.sipstack, session->stack.dns_client, 32, 32, 32, JANUS_SIPRE_NAME, janus_sipre_cb_exit, session);
3743
			err = sip_alloc(&session->stack.sipstack, session->stack.dns_client, 32, 32, 32,
3744
				(user_agent ? user_agent : JANUS_SIPRE_NAME), janus_sipre_cb_exit, session);
3781 3745
			if(err) {
3782 3746
				JANUS_LOG(LOG_ERR, "Failed to initialize libre SIP stack: %d (%s)\n", err, strerror(err));
3783 3747
				mem_deref(session->stack.dns_client);
......
3801 3765
			err |= sip_transp_add(session->stack.sipstack, SIP_TRANSP_TLS, &laddrs, session->stack.tls);
3802 3766
			err |= sipsess_listen(&session->stack.sess_sock, session->stack.sipstack, 32, janus_sipre_cb_incoming, session);
3803 3767
			if(err) {
3804
				mem_deref(session->stack.sipstack);
3768
				sip_close(session->stack.sipstack, TRUE);
3805 3769
				session->stack.sipstack = NULL;
3806 3770
				mem_deref(session->stack.tls);
3807 3771
				session->stack.tls = NULL;

Also available in: Unified diff