Index: channels/chan_sip.c =================================================================== RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v retrieving revision 1.658 diff -u -r1.658 chan_sip.c --- channels/chan_sip.c 13 Feb 2005 18:40:50 -0000 1.658 +++ channels/chan_sip.c 13 Feb 2005 21:14:22 -0000 @@ -72,9 +72,8 @@ /* #define VOCAL_DATA_HACK */ -#define SIPDUMPER -#define DEFAULT_DEFAULT_EXPIRY 120 -#define DEFAULT_MAX_EXPIRY 3600 +#define DEFAULT_DEFAULT_EXPIRY 120 +#define DEFAULT_MAX_EXPIRY 3600 #define DEFAULT_REGISTRATION_TIMEOUT 20 /* guard limit must be larger than guard secs */ @@ -465,9 +464,10 @@ char md5secret[80]; /* Password in MD5 */ char context[80]; /* Default context for incoming calls */ char username[80]; /* Temporary username until registration */ + char authuser[80]; /* Who we *authenticate* as */ char accountcode[20]; /* Account code */ int amaflags; /* AMA Flags (for billing) */ - char tohost[80]; /* If not dynamic, IP address */ + char tohost[180]; /* If not dynamic, IP address */ char regexten[AST_MAX_EXTENSION]; /* Extension to register (if regcontext is used) */ char fromuser[80]; /* From: user when calling this peer */ char fromdomain[80]; /* From: domain when calling this peer */ @@ -509,6 +509,7 @@ struct sockaddr_in defaddr; /* Default IP address, used until registration */ struct ast_ha *ha; /* Access control list */ struct ast_variable *chanvars; /* Variables to set for channel created by user */ + struct sip_registry *registry; /* If this peer REGISTER, to which registry */ int lastmsg; }; @@ -552,6 +553,7 @@ char domain[256]; /* Authorization domain */ char opaque[256]; /* Opaque nonsense */ char qop[80]; /* Quality of Protection. */ + struct sip_peer *owner; /* Peer that owns this registration (if any) */ char lastmsg[256]; /* Last Message sent/received */ }; @@ -2504,7 +2506,7 @@ } /*--- sip_register: Parse register=> line in sip.conf and add to registry */ -static int sip_register(char *value, int lineno) +static int sip_register(char *value, int lineno, struct sip_peer *owner) { struct sip_registry *reg; char copy[256] = ""; @@ -2512,17 +2514,34 @@ char *porta=NULL; char *contact=NULL; char *stringp=NULL; + + if (owner && ast_test_flag(owner, SIP_DYNAMIC)) { + ast_log(LOG_WARNING, "You can not register with a dynamic peer.\n"); + return -1; + } if (!value) return -1; strncpy(copy, value, sizeof(copy)-1); stringp=copy; username = stringp; - hostname = strrchr(stringp, '@'); + hostname = strrchr(stringp, '@'); /* Really SIP domain or hostname */ if (hostname) { *hostname = '\0'; hostname++; + } else if (owner) { /* Within peer we can skip the stuff before t@ and go for hostname directly */ + hostname = username; + username = NULL; + } + if (owner && !username) { + if (owner->fromuser) + username = owner->fromuser; + else + username = owner->username; } + //if (option_debug > 3) + ast_log(LOG_DEBUG, "====> Username: %s Hostname %s\n",username, hostname); + if (!username || ast_strlen_zero(username) || !hostname || ast_strlen_zero(hostname)) { ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d", lineno); return -1; @@ -2534,6 +2553,13 @@ if (secret) authuser = strsep(&stringp, ":"); } + /* No secret in register, use peer secret */ + if (owner && !secret && !ast_strlen_zero(owner->secret)) + secret = owner->secret; + + /* If there's an auth user in the peer, use that as a backup */ + if (owner && !authuser && !ast_strlen_zero(owner->authuser)) + authuser = owner->authuser; stringp = hostname; hostname = strsep(&stringp, "/"); if (hostname) @@ -2568,6 +2594,10 @@ reg->portno = porta ? atoi(porta) : 0; reg->callid_valid = 0; reg->ocseq = 101; + if (owner) { + reg->owner = owner; /* SIP peer that owns this */ + owner->registry = reg; + } ASTOBJ_CONTAINER_LINK(®l, reg); ASTOBJ_UNREF(reg,sip_registry_destroy); } else { @@ -5815,7 +5845,10 @@ if (peer->incominglimit) ast_set_flag(p, SIP_CALL_LIMIT); strncpy(p->peername, peer->name, sizeof(p->peername) - 1); - strncpy(p->authname, peer->name, sizeof(p->authname) - 1); + if (!ast_strlen_zero(peer->authuser)) + strncpy(p->authname, peer->authuser, sizeof(p->authname) - 1); + else + strncpy(p->authname, peer->name, sizeof(p->authname) - 1); /* copy channel vars */ for (v = peer->chanvars ; v ; v = v->next) { if((tmpvar = ast_variable_new(v->name, v->value))) { @@ -6400,17 +6433,17 @@ /*--- sip_show_registry: Show SIP Registry (registrations with other SIP proxies ---*/ static int sip_show_registry(int fd, int argc, char *argv[]) { -#define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s\n" -#define FORMAT "%-30.30s %-12.12s %8d %-20.20s\n" +#define FORMAT2 "%-30.30s %-12.12s %8.8s %-20.20s %-10.10s\n" +#define FORMAT "%-30.30s %-12.12s %8d %-20.20s %-10.10s\n" char host[80]; if (argc != 3) return RESULT_SHOWUSAGE; - ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State"); + ast_cli(fd, FORMAT2, "Host", "Username", "Refresh", "State", "Peer name"); ASTOBJ_CONTAINER_TRAVERSE(®l, 1, do { ASTOBJ_RDLOCK(iterator); snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : DEFAULT_SIP_PORT); - ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate)); + ast_cli(fd, FORMAT, host, iterator->username, iterator->refresh, regstate2str(iterator->regstate), iterator->owner?iterator->owner->name:""); ASTOBJ_UNLOCK(iterator); } while(0)); return RESULT_SUCCESS; @@ -9226,6 +9259,8 @@ strncpy(peer->fromdomain, v->value, sizeof(peer->fromdomain)-1); else if (!strcasecmp(v->name, "usereqphone")) ast_set2_flag(peer, ast_true(v->value), SIP_USEREQPHONE); + else if (!strcasecmp(v->name, "authuser")) + strncpy(peer->authuser, v->value, sizeof(peer->authuser)-1); else if (!strcasecmp(v->name, "fromuser")) strncpy(peer->fromuser, v->value, sizeof(peer->fromuser)-1); else if (!strcasecmp(v->name, "host") || !strcasecmp(v->name, "outboundproxy")) { @@ -9353,6 +9388,8 @@ ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", peer->name, v->lineno); peer->maxms = 0; } + } else if (!strcasecmp(v->name, "register")) { + sip_register(v->value, v->lineno, peer); } /* else if (strcasecmp(v->name,"type")) * ast_log(LOG_WARNING, "Ignoring %s\n", v->name); @@ -9584,7 +9621,7 @@ } else if (!strcasecmp(v->name, "disallow")) { ast_parse_allow_disallow(&prefs, &global_capability, v->value, 0); } else if (!strcasecmp(v->name, "register")) { - sip_register(v->value, v->lineno); + sip_register(v->value, v->lineno, NULL); } else if (!strcasecmp(v->name, "recordhistory")) { recordhistory = ast_true(v->value); } else if (!strcasecmp(v->name, "tos")) { Index: configs/sip.conf.sample =================================================================== RCS file: /usr/cvsroot/asterisk/configs/sip.conf.sample,v retrieving revision 1.59 diff -u -r1.59 sip.conf.sample --- configs/sip.conf.sample 13 Feb 2005 16:40:56 -0000 1.59 +++ configs/sip.conf.sample 13 Feb 2005 21:14:22 -0000 @@ -212,6 +212,8 @@ ; defaultip ; rtptimeout ; rtpholdtimeout +; register +; authuser ;[sip_proxy] ; For incoming calls only. Example: FWD (Free World Dialup) @@ -229,6 +231,11 @@ ;fromdomain=provider.sip.domain ;host=box.provider.com ;usereqphone=yes ; This provider requires ";user=phone" on URI +; ; You can register within a peer as well +;register = 1234:password@provider.sip.domain/1234 +; ; This will use the fromuser and secret in the peer +;register = provider.sip.domain/3444 +;authuser = userid ; If you use another username for authentication ;------------------------------------------------------------------------------ ; Definitions of locally connected SIP phones