--- channels/chan_sip.c 2005-06-21 18:15:55.000000000 +0400 +++ ../asterisk-1.0.9-patched/channels/chan_sip.c 2005-08-15 17:45:48.000000000 +0400 @@ -203,6 +203,7 @@ static int global_dtmfmode = SIP_DTMF_RFC2833; /* DTMF mode default */ static int recordhistory = 0; static int global_promiscredir; +static int externalauth = 0; static char global_musicclass[MAX_LANGUAGE] = ""; /* Global music on hold class */ static char global_realm[MAXHOSTNAMELEN] = "asterisk"; /* Default realm */ @@ -4702,7 +4712,7 @@ unsigned int osptimelimit; #endif /* Always OK if no secret */ - if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret) + if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret) && (!externalauth) #ifdef OSP_SUPPORT && !p->ospauth #endif @@ -4756,6 +4766,8 @@ sip_scheddestroy(p, 15000); res = 1; } else { + if(!externalauth) + { /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting an example in the spec of just what it is you're doing a hash on. */ char a1[256]; @@ -4805,7 +4817,7 @@ } } else if (!strncasecmp(c, "nonce=", strlen("nonce="))) -{ + { c+= strlen("nonce="); if ((*c == '\"')) { nonce=++c; @@ -4850,6 +4862,8 @@ return 0; } } + } else + res=0; } return res; } @@ -8245,7 +8259,33 @@ like SIP/peername/extension SIP/peername will still use the full contact */ if (ext) { - strncpy(p->username, ext, sizeof(p->username) - 1); + char * tmp; + char * password; + char * authname; + /* parse the username - it could be like user[:password[:authname]] */ + tmp = strchr(ext, ':'); + if(tmp) + { + tmp[0] = 0; + strncpy(p->username, ext, sizeof(p->username) - 1); + password = tmp + 1; + /* we can do it beacause even if it is last character + we'll step one more and get terminating zero */ + tmp = strchr(password, ':'); + if(tmp) + { + tmp[0] = 0; + strncpy(p->peersecret, password, sizeof(p->peersecret) - 1); + authname = tmp + 1; + if(strlen(authname)) + strncpy(p->authname, authname, sizeof(p->authname) - 1); + } else + strncpy(p->peersecret, ext, sizeof(p->peersecret) - 1); + + } else + { + strncpy(p->username, ext, sizeof(p->username) - 1); + } p->fullcontact[0] = 0; } #if 0 @@ -8821,6 +8861,8 @@ ast_parse_allow_disallow(&prefs, &global_capability, v->value, 0); } else if (!strcasecmp(v->name, "register")) { sip_register(v->value, v->lineno); + } else if (!strcasecmp(v->name, "externalauth")) { + externalauth = ast_true(v->value); } else if (!strcasecmp(v->name, "recordhistory")) { recordhistory = ast_true(v->value); } else if (!strcasecmp(v->name, "tos")) { @@ -9018,6 +9060,28 @@ static char *descrip_dtmfmode = "SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n"; static char *app_dtmfmode = "SIPDtmfMode"; +static char *app_sipgetheader = "SIPGetHeader"; +static char *app_sipaddheader = "SIPAddHeader"; + +static char *synopsis_sipgetheader = "Get a SIP header from an incoming call"; +static char *synopsis_sipaddheader = "Add a SIP header to the outbound call"; + +static char *descrip_sipgetheader = "" +" SIPGetHeader(var=headername): \n" +"Sets a channel variable to the content of a SIP header\n" +"Skips to priority+101 if header does not exist\n" +"Otherwise returns 0\n"; + +static char *descrip_sipaddheader = "" +" SIPAddHeader(Header: Content)\n" +"Adds a header to a SIP call placed with DIAL.\n" +"Remember to user the X-header if you are adding non-standard SIP\n" +"headers, like \"X-Asterisk-Accuntcode:\". Use this with care.\n" +"Adding the wrong headers may jeopardize the SIP dialog.\n" +"Always returns 0\n"; + + + /*--- sip_dtmfmode: change the DTMFmode for a SIP call (application) ---*/ static int sip_dtmfmode(struct ast_channel *chan, void *data) { @@ -9063,6 +9127,99 @@ return 0; } +/*--- sip_addheader: Add a SIP header ---*/ +static int sip_addheader(struct ast_channel *chan, void *data) +{ + int arglen; + int no = 0; + int ok = 0; + char *content = (char *) NULL; + char varbuf[128]; + + arglen = strlen(data); + if (!arglen) { + ast_log(LOG_WARNING, "This application requires the argument: Header\n"); + return 0; + } + ast_mutex_lock(&chan->lock); + if (chan->type != type) { + ast_log(LOG_WARNING, "Call this application only on incoming SIP calls\n"); + ast_mutex_unlock(&chan->lock); + return 0; + } + + /* Check for headers */ + while (!ok && no <= 50) { + no++; + sprintf(varbuf, "_SIPADDHEADER%.2d", no); + ast_log(LOG_NOTICE, "Checking for existence of variable %s\n", varbuf); + content = pbx_builtin_getvar_helper(chan, varbuf); + + if (!content) + ok = 1; + } + if (ok) { + pbx_builtin_setvar_helper (chan, varbuf, data); + ast_log(LOG_DEBUG,"SIP Header added \"%s\" as %s\n", (char *) data, varbuf); + } else { + ast_log(LOG_WARNING, "Too many headers added, max 50\n"); + } + ast_mutex_unlock(&chan->lock); + return 0; +} + + + +/*--- sip_getheader: Get a SIP header (dialplan app) ---*/ +static int sip_getheader(struct ast_channel *chan, void *data) +{ + struct sip_pvt *p; + char *argv, *varname = (char *) NULL, *header = (char *) NULL, *content; + int arglen; + + arglen = strlen(data); + argv = alloca (arglen + 1); + if (!argv) { + ast_log(LOG_DEBUG, "Memory allocation failed\n"); + return 0; + } + + if (!arglen) { + ast_log(LOG_WARNING, "This application requires the argument: Headername\n"); + return 0; + } + memcpy (argv, data, arglen + 1); + + if (strchr (argv, '=') ) { /* Pick out argumenet */ + varname = strsep (&argv, "="); + header = strsep (&argv, "\0"); + } + if (!varname || !header) { + ast_log(LOG_DEBUG, "SipGetHeader: Ignoring command, Syntax error in argument\n"); + return 0; + } + + ast_mutex_lock(&chan->lock); + if (chan->type != type) { + ast_log(LOG_WARNING, "Call this application only on incoming SIP calls\n"); + ast_mutex_unlock(&chan->lock); + return 0; + } + + p = chan->pvt->pvt; + content = get_header(&p->initreq, header); /* Get the header */ + if (!ast_strlen_zero(content)) { + pbx_builtin_setvar_helper (chan, varname, content); + } else { + ast_log(LOG_WARNING,"SIP Header %s not found for channel variable %s\n", header, varname); + if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->callerid)) + chan->priority += 100; + } + + ast_mutex_unlock(&chan->lock); + return 0; +} + static int sip_get_codec(struct ast_channel *chan) { struct sip_pvt *p = chan->pvt->pvt; @@ -9257,6 +9414,8 @@ sip_rtp.type = type; ast_rtp_proto_register(&sip_rtp); ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode); + ast_register_application(app_sipgetheader, sip_getheader, synopsis_sipgetheader, descrip_sipgetheader); + ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader); ast_mutex_lock(&peerl.lock); for (peer = peerl.peers; peer; peer = peer->next) sip_poke_peer(peer);