aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2009-08-19 21:22:04 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2009-08-19 21:22:04 +0000
commitb402d3a0efd53fb2ba52785e47db9d73d444f466 (patch)
treebf95f5cb701ffd9090e63270774cd2c977c71ed0 /channels
parent45bd3ef8028ef0d5363b2da67a15c892ba50be1e (diff)
Merged revisions 213098 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk ........ r213098 | tilghman | 2009-08-19 16:05:17 -0500 (Wed, 19 Aug 2009) | 9 lines Better parsing for the "register" line Allows characters that are otherwise used as delimiters to be used within certain fields (like the secret). (closes issue #15008, closes issue #15672) Reported by: tilghman Patches: 20090818__issue15008.diff.txt uploaded by tilghman (license 14) Tested by: lmadsen, tilghman ........ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.2@213117 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_sip.c173
1 files changed, 112 insertions, 61 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 611feb9c3..47f1ac849 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -271,6 +271,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/ast_version.h"
#include "asterisk/event.h"
#include "asterisk/tcptls.h"
+#include "asterisk/strings.h"
/*** DOCUMENTATION
<application name="SIPDtmfMode" language="en_US">
@@ -7091,60 +7092,118 @@ static int sip_register(const char *value, int lineno)
enum sip_transport transport = SIP_TRANSPORT_UDP;
char buf[256] = "";
char *username = NULL;
- char *hostname=NULL, *secret=NULL, *authuser=NULL, *expire=NULL, *tmp=NULL;
- char *callback=NULL, *peername=NULL;
+ char *tmp = NULL, *transport_str = NULL;
+ char *peername = NULL;
+ /* register => [peer?][transport://]user[@domain][:secret[:authuser]]@host[:port][/extension][~expiry] */
+ AST_DECLARE_APP_ARGS(parts,
+ AST_APP_ARG(userpart);
+ AST_APP_ARG(hostpart);
+ );
+ AST_DECLARE_APP_ARGS(user1,
+ AST_APP_ARG(userpart);
+ AST_APP_ARG(secret);
+ AST_APP_ARG(authuser);
+ );
+ AST_DECLARE_APP_ARGS(host1,
+ AST_APP_ARG(hostpart);
+ AST_APP_ARG(expiry);
+ );
+ AST_DECLARE_APP_ARGS(host2,
+ AST_APP_ARG(hostpart);
+ AST_APP_ARG(extension);
+ );
+ AST_DECLARE_APP_ARGS(host3,
+ AST_APP_ARG(host);
+ AST_APP_ARG(port);
+ );
if (!value)
return -1;
ast_copy_string(buf, value, sizeof(buf));
- tmp = strrchr(buf, '@');
-
- /* split [/extension][~expiry] */
- expire = strchr(tmp, '~');
- if (expire)
- *expire++ = '\0';
- callback = strrchr(tmp, '/');
- if (callback)
- *callback++ = '\0';
- if (ast_strlen_zero(callback))
- callback = "s";
-
- /* split [peername?][transport://] */
- tmp = strchr(buf, '?');
- if (tmp) {
- *tmp++ = '\0';
- peername = buf;
- } else {
- tmp = buf;
+
+ /*! register => [peer?][transport://]user[@domain][:secret[:authuser]]@host[:port][/extension][~expiry]
+ * becomes
+ * parts.userpart => [peer?][transport://]user[@domain][:secret[:authuser]]
+ * parts.hostpart => host[:port][/extension][~expiry]
+ */
+ AST_NONSTANDARD_RAW_ARGS(parts, buf, '@');
+ /*!
+ * user1.userpart => [peer?][transport://]user[@domain]
+ * user1.secret => secret
+ * user1.authuser => authuser
+ * parts.hostpart => host[:port][/extension][~expiry]
+ */
+ AST_NONSTANDARD_RAW_ARGS(user1, parts.userpart, ':');
+
+ /*!
+ * user1.userpart => [peer?][transport://]user[@domain]
+ * user1.secret => secret
+ * user1.authuser => authuser
+ * host1.hostpart => host[:port][/extension]
+ * host1.expiry => [expiry]
+ */
+ AST_NONSTANDARD_RAW_ARGS(host1, parts.hostpart, '~');
+
+ /*!
+ * user1.userpart => [peer?][transport://]user[@domain]
+ * user1.secret => secret
+ * user1.authuser => authuser
+ * host2.hostpart => host[:port]
+ * host2.extension => [extension]
+ * host1.expiry => [expiry]
+ */
+ AST_NONSTANDARD_RAW_ARGS(host2, parts.hostpart, '/');
+
+ /*!
+ * user1.userpart => [peer?][transport://]user[@domain]
+ * user1.secret => secret
+ * user1.authuser => authuser
+ * host3.host => host
+ * host3.port => port
+ * host2.extension => extension
+ * host1.expiry => expiry
+ */
+ AST_NONSTANDARD_RAW_ARGS(host3, parts.hostpart, ':');
+
+ if ((tmp = strchr(user1.userpart, '?'))) {
+ *tmp = '\0';
+ peername = user1.userpart;
+ user1.userpart = tmp + 1;
}
- /* tmp is set at the beginning of [transport://] */
- sip_parse_host(tmp, lineno, &username, &portnum, &transport);
- /* First split around the last '@' then parse the two components. */
- hostname = strrchr(username, '@'); /* allow @ in the first part */
- if (hostname)
- *hostname++ = '\0';
- if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
- ast_log(LOG_WARNING, "Format for registration is [transport://]user[@domain][:secret[:authuser]]@host[:port][/extension][~expiry] at line %d\n", lineno);
- return -1;
+ if ((tmp = strstr(user1.userpart, "://"))) {
+ *tmp = '\0';
+ transport_str = user1.userpart;
+ username = tmp + 3;
+ } else {
+ username = user1.userpart;
}
- /* split user[:secret[:authuser]] from the end to allow : character in user portion*/
- authuser = strrchr(username, ':');
- if (authuser) {
- *authuser++ = '\0';
- secret = strrchr(username, ':');
- if (secret)
- *secret++ = '\0';
- else {
- secret = authuser;
- authuser = NULL;
+ if (host3.port) {
+ if (sscanf(host3.port, "%5u", &portnum) != 1 || portnum > 65535) {
+ ast_log(LOG_NOTICE, "'%s' is not a valid port number on line %d of sip.conf. using default.\n", host3.port, lineno);
+ portnum = -1;
}
}
- if ((authuser) && (ast_strlen_zero(authuser)))
- authuser = NULL;
- if ((secret) && (ast_strlen_zero(secret)))
- secret = NULL;
+
+ if (!transport_str) {
+ transport = SIP_TRANSPORT_UDP;
+ } else if (!strncasecmp(transport_str, "tcp", 3)) {
+ transport = SIP_TRANSPORT_TCP;
+ } else if (!strncasecmp(transport_str, "tls", 3)) {
+ transport = SIP_TRANSPORT_TLS;
+ if (portnum < 0) {
+ portnum = STANDARD_TLS_PORT;
+ }
+ } else if (!strncasecmp(transport_str, "udp", 3)) {
+ transport = SIP_TRANSPORT_UDP;
+ } else {
+ ast_log(LOG_NOTICE, "'%.3s' is not a valid transport type on line %d of sip.conf. defaulting to udp.\n", transport_str, lineno);
+ }
+
+ if (portnum < 0) {
+ portnum = STANDARD_SIP_PORT;
+ }
if (!(reg = ast_calloc(1, sizeof(*reg)))) {
ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
@@ -7159,24 +7218,16 @@ static int sip_register(const char *value, int lineno)
ast_atomic_fetchadd_int(&regobjs, 1);
ASTOBJ_INIT(reg);
- ast_string_field_set(reg, callback, callback);
- if (!ast_strlen_zero(username))
- ast_string_field_set(reg, username, username);
- if (hostname)
- ast_string_field_set(reg, hostname, hostname);
- if (authuser)
- ast_string_field_set(reg, authuser, authuser);
- if (secret)
- ast_string_field_set(reg, secret, secret);
- if (peername) {
- ast_string_field_set(reg, peername, peername);
- }
+ ast_string_field_set(reg, callback, ast_strip_quoted(S_OR(host2.extension, ""), "\"", "\""));
+ ast_string_field_set(reg, username, ast_strip_quoted(S_OR(username, ""), "\"", "\""));
+ ast_string_field_set(reg, hostname, ast_strip_quoted(S_OR(host3.host, ""), "\"", "\""));
+ ast_string_field_set(reg, authuser, ast_strip_quoted(S_OR(user1.authuser, ""), "\"", "\""));
+ ast_string_field_set(reg, secret, ast_strip_quoted(S_OR(user1.secret, ""), "\"", "\""));
+ ast_string_field_set(reg, peername, ast_strip_quoted(S_OR(peername, ""), "\"", "\""));
+
reg->transport = transport;
- reg->expire = -1;
- reg->configured_expiry = (expire ? atoi(expire) : default_expiry);
- reg->expiry = reg->configured_expiry;
- reg->timeout = -1;
- reg->refresh = reg->expiry;
+ reg->timeout = reg->expire = -1;
+ reg->refresh = reg->expiry = reg->configured_expiry = (host1.expiry ? atoi(ast_strip_quoted(host1.expiry, "\"", "\"")) : default_expiry);
reg->portno = portnum;
reg->callid_valid = FALSE;
reg->ocseq = INITIAL_CSEQ;