[asterisk-commits] oej: branch oej/codename-pineapple r44899 - in
/team/oej/codename-pineapple/c...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Wed Oct 11 12:41:08 MST 2006
Author: oej
Date: Wed Oct 11 14:41:08 2006
New Revision: 44899
URL: http://svn.digium.com/view/asterisk?rev=44899&view=rev
Log:
Chopping, cutting, fixing.
Added:
team/oej/codename-pineapple/channels/sip3/sip3_auth.c (with props)
team/oej/codename-pineapple/channels/sip3/sip3_callerid.c (with props)
team/oej/codename-pineapple/channels/sip3/sip3_domain.c (with props)
team/oej/codename-pineapple/channels/sip3/sip3_parse.c (with props)
team/oej/codename-pineapple/channels/sip3/sip3core.h (with props)
team/oej/codename-pineapple/channels/sip3/sip3funcs.h (with props)
Modified:
team/oej/codename-pineapple/channels/Makefile
team/oej/codename-pineapple/channels/chan_sip3.c
team/oej/codename-pineapple/channels/sip3/Makefile
team/oej/codename-pineapple/channels/sip3/sip3.h
team/oej/codename-pineapple/channels/sip3/sip3_network.c
Modified: team/oej/codename-pineapple/channels/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/Makefile?rev=44899&r1=44898&r2=44899&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/Makefile (original)
+++ team/oej/codename-pineapple/channels/Makefile Wed Oct 11 14:41:08 2006
@@ -13,6 +13,8 @@
C_MODS:=$(filter-out $(MENUSELECT_CHANNELS),$(patsubst %.c,%,$(wildcard chan_*.c)))
CC_MODS:=$(filter-out $(MENUSELECT_CHANNELS),$(patsubst %.cc,%,$(wildcard chan_*.cc)))
+SIP3_MODULES=chan_sip3.o sip3/sip3_network.o sip3/sip3_subscribe.o sip3/sip3_refer.o sip3/sip3_domain.o \
+ sip3/sip3_callerid.o sip3/sip3_auth.o
ifeq ($(OSARCH),OpenBSD)
PTLIB=-lpt_OpenBSD_x86_r
@@ -117,6 +119,6 @@
sip3:
$(MAKE) -C sip3
-chan_sip3.so: chan_sip3.o sip3/sip3_network.o sip3/sip3_subscribe.o sip3/sip3_refer.o
+chan_sip3.so: $(SIP3_MODULES)
$(ECHO_PREFIX) echo " [LD] $^ -> $@"
$(CMD_PREFIX) $(CXX) $(SOLINK) -o $@ $<
Modified: team/oej/codename-pineapple/channels/chan_sip3.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/chan_sip3.c?rev=44899&r1=44898&r2=44899&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/chan_sip3.c (original)
+++ team/oej/codename-pineapple/channels/chan_sip3.c Wed Oct 11 14:41:08 2006
@@ -132,6 +132,7 @@
- ... And much more
*/
+#define CHAN_SIP3_MAIN
#include "asterisk.h"
@@ -246,7 +247,6 @@
static struct sched_context *sched; /*!< The scheduling context */
static struct io_context *io; /*!< The IO context */
-static AST_LIST_HEAD_STATIC(domain_list, domain); /*!< The SIP domain list */
AST_LIST_HEAD_NOLOCK(sip_history_head, sip_history); /*!< history list, entry in sip_pvt */
@@ -380,20 +380,12 @@
static int clear_realm_authentication(struct sip_auth *authlist); /* Clear realm authentication list (at reload) */
static struct sip_auth *add_realm_authentication(struct sip_auth *authlist, char *configuration, int lineno); /* Add realm authentication in list */
static struct sip_auth *find_realm_authentication(struct sip_auth *authlist, const char *realm); /* Find authentication for a specific realm */
-static enum check_auth_result check_auth(struct sip_pvt *p, struct sip_request *req, const char *username,
- const char *secret, const char *md5secret, int sipmethod,
- char *uri, enum xmittype reliable, int ignore);
static enum check_auth_result check_user_full(struct sip_pvt *p, struct sip_request *req,
int sipmethod, char *uri, enum xmittype reliable,
struct sockaddr_in *sin, struct sip_peer **authpeer);
static int check_user(struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin);
static int do_proxy_auth(struct sip_pvt *p, struct sip_request *req, char *header, char *respheader, int sipmethod, int init);
static int build_reply_digest(struct sip_pvt *p, int method, char* digest, int digest_len);
-
-/*--- Domain handling */
-static int check_sip_domain(const char *domain, char *context, size_t len); /* Check if domain is one of our local domains */
-static int add_sip_domain(const char *domain, const enum domain_mode mode, const char *context);
-static void clear_sip_domains(void);
/*--- SIP realm authentication */
static struct sip_auth *add_realm_authentication(struct sip_auth *authlist, char *configuration, int lineno);
@@ -438,8 +430,6 @@
static const char *insecure2str(int port, int invite) attribute_const;
static void cleanup_stale_contexts(char *new, char *old);
static void print_codec_to_cli(int fd, struct ast_codec_pref *pref);
-static const char *domain_mode_to_text(const enum domain_mode mode);
-static int sip_show_domains(int fd, int argc, char *argv[]);
static int _sip_show_peer(int type, int fd, struct mansession *s, struct message *m, int argc, char *argv[]);
static int manager_sip_show_peer( struct mansession *s, struct message *m);
static int sip_show_peer(int fd, int argc, char *argv[]);
@@ -470,7 +460,6 @@
static int sip_do_history(int fd, int argc, char *argv[]);
static int sip_no_history(int fd, int argc, char *argv[]);
static int func_header_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len);
-static int func_check_sipdomain(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len);
static int function_sippeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len);
static int function_sipchaninfo_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len);
static int sip_dtmfmode(struct ast_channel *chan, void *data);
@@ -708,19 +697,6 @@
return 0;
return sip_debug_test_addr(sip_real_dst(p));
}
-
-/*! \brief Transmit SIP message */
-static int __sip_xmit(struct sip_pvt *p, char *data, int len)
-{
- int res;
- const struct sockaddr_in *dst = sip_real_dst(p);
- res=sendto(sipnet.sipsock, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
-
- if (res != len)
- ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), res, strerror(errno));
- return res;
-}
-
/*! \brief Build a Via header for a request */
static void build_via(struct sip_pvt *p)
@@ -6338,7 +6314,7 @@
peer->addr.sin_family = AF_INET;
peer->addr.sin_addr = in;
peer->addr.sin_port = htons(port);
- if (sipnet.sipsock < 0) {
+ if (sipsocket_initialized()) {
/* SIP isn't up yet, so schedule a poke only, pretty soon */
if (peer->pokeexpire > -1)
ast_sched_del(sched, peer->pokeexpire);
@@ -6710,168 +6686,6 @@
list_route(p->route);
}
-
-/*! \brief Check user authorization from peer definition
- Some actions, like REGISTER and INVITEs from peers require
- authentication (if peer have secret set)
- \return 0 on success, non-zero on error
-*/
-static enum check_auth_result check_auth(struct sip_pvt *p, struct sip_request *req, const char *username,
- const char *secret, const char *md5secret, int sipmethod,
- char *uri, enum xmittype reliable, int ignore)
-{
- const char *response = "407 Proxy Authentication Required";
- const char *reqheader = "Proxy-Authorization";
- const char *respheader = "Proxy-Authenticate";
- const char *authtoken;
- char a1_hash[256];
- char resp_hash[256]="";
- char tmp[BUFSIZ * 2]; /* Make a large enough buffer */
- char *c;
- int wrongnonce = FALSE;
- int good_response;
- const char *usednonce = p->randdata;
-
- /* table of recognised keywords, and their value in the digest */
- enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
- struct x {
- const char *key;
- const char *s;
- } *i, keys[] = {
- [K_RESP] = { "response=", "" },
- [K_URI] = { "uri=", "" },
- [K_USER] = { "username=", "" },
- [K_NONCE] = { "nonce=", "" },
- [K_LAST] = { NULL, NULL}
- };
-
- /* Always OK if no secret */
- if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret))
- return AUTH_SUCCESSFUL;
- if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
- /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family
- of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in
- different circumstances! What a surprise. */
- response = "401 Unauthorized";
- reqheader = "Authorization";
- respheader = "WWW-Authenticate";
- }
- authtoken = get_header(req, reqheader);
- if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
- /* This is a retransmitted invite/register/etc, don't reconstruct authentication
- information */
- if (!reliable) {
- /* Resend message if this was NOT a reliable delivery. Otherwise the
- retransmission should get it */
- transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
- /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- }
- return AUTH_CHALLENGE_SENT;
- } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
- /* We have no auth, so issue challenge and request authentication */
- ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
- transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
- /* Schedule auto destroy in 32 seconds */
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return AUTH_CHALLENGE_SENT;
- }
-
- /* --- We have auth, so check it */
-
- /* 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. */
-
-
- /* Make a copy of the response and parse it */
- ast_copy_string(tmp, authtoken, sizeof(tmp));
- c = tmp;
-
- while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
- for (i = keys; i->key != NULL; i++) {
- const char *separator = ","; /* default */
-
- if (strncasecmp(c, i->key, strlen(i->key)) != 0)
- continue;
- /* Found. Skip keyword, take text in quotes or up to the separator. */
- c += strlen(i->key);
- if (*c == '"') { /* in quotes. Skip first and look for last */
- c++;
- separator = "\"";
- }
- i->s = c;
- strsep(&c, separator);
- break;
- }
- if (i->key == NULL) /* not found, jump after space or comma */
- strsep(&c, " ,");
- }
-
- /* Verify that digest username matches the username we auth as */
- if (strcmp(username, keys[K_USER].s)) {
- ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
- username, keys[K_USER].s);
- /* Oops, we're trying something here */
- return AUTH_USERNAME_MISMATCH;
- }
-
- /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */
- if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */
- wrongnonce = TRUE;
- usednonce = keys[K_NONCE].s;
- }
-
- if (!ast_strlen_zero(md5secret))
- ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
- else {
- char a1[256];
- snprintf(a1, sizeof(a1), "%s:%s:%s", username, global.realm, secret);
- ast_md5_hash(a1_hash, a1);
- }
-
- /* compute the expected response to compare with what we received */
- {
- char a2[256];
- char a2_hash[256];
- char resp[256];
-
- snprintf(a2, sizeof(a2), "%s:%s", sip_method2txt(sipmethod), S_OR(keys[K_URI].s, uri));
- ast_md5_hash(a2_hash, a2);
- snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
- ast_md5_hash(resp_hash, resp);
- }
-
- good_response = keys[K_RESP].s &&
- !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
- if (wrongnonce) {
- ast_string_field_build(p, randdata, "%08lx", ast_random());
- if (good_response) {
- if (sipdebug)
- ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To"));
- /* We got working auth token, based on stale nonce . */
- transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 1);
- } else {
- /* Everything was wrong, so give the device one more try with a new challenge */
- if (sipdebug)
- ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
- transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
- }
-
- /* Schedule auto destroy in 32 seconds */
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return AUTH_CHALLENGE_SENT;
- }
- if (good_response)
- return AUTH_SUCCESSFUL;
-
- /* Ok, we have a bad username/secret pair */
- /* Challenge again, and again, and again */
- transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
-
- return AUTH_CHALLENGE_SENT;
-}
-
/*! \brief Change onhold state of a peer using a pvt structure */
static void sip_peer_hold(struct sip_pvt *p, int hold)
{
@@ -6970,7 +6784,7 @@
domain = c;
if ((c = strchr(domain, ':'))) /* Remove :port */
*c = '\0';
- if (!AST_LIST_EMPTY(&domain_list)) {
+ if (domains_configured()) {
if (!check_sip_domain(domain, NULL, 0)) {
transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
return AUTH_UNKNOWN_DOMAIN;
@@ -7203,7 +7017,7 @@
ast_string_field_set(p, domain, a);
- if (!AST_LIST_EMPTY(&domain_list)) {
+ if (domains_configured()) {
char domain_context[AST_MAX_EXTENSION];
domain_context[0] = '\0';
@@ -8542,41 +8356,6 @@
ast_cli(fd, "none");
}
-/*! \brief Print domain mode to cli */
-static const char *domain_mode_to_text(const enum domain_mode mode)
-{
- switch (mode) {
- case SIP_DOMAIN_AUTO:
- return "[Automatic]";
- case SIP_DOMAIN_CONFIG:
- return "[Configured]";
- }
-
- return "";
-}
-
-/*! \brief CLI command to list local domains */
-static int sip_show_domains(int fd, int argc, char *argv[])
-{
- struct domain *d;
-#define FORMAT "%-40.40s %-20.20s %-16.16s\n"
-
- if (AST_LIST_EMPTY(&domain_list)) {
- ast_cli(fd, "SIP Domain support not enabled.\n\n");
- return RESULT_SUCCESS;
- } else {
- ast_cli(fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
- AST_LIST_LOCK(&domain_list);
- AST_LIST_TRAVERSE(&domain_list, d, list)
- ast_cli(fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
- domain_mode_to_text(d->mode));
- AST_LIST_UNLOCK(&domain_list);
- ast_cli(fd, "\n");
- return RESULT_SUCCESS;
- }
-}
-#undef FORMAT
-
static char mandescr_show_peer[] =
"Description: Show one SIP peer with details on current status.\n"
"Variables: \n"
@@ -8919,7 +8698,7 @@
ast_cli(fd, " Allow subscriptions: %s\n", ast_test_flag(&global.flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
ast_cli(fd, " Allow overlap dialing: %s\n", ast_test_flag(&global.flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
ast_cli(fd, " Promsic. redir: %s\n", ast_test_flag(&global.flags[0], SIP_PROMISCREDIR) ? "Yes" : "No");
- ast_cli(fd, " SIP domain support: %s\n", AST_LIST_EMPTY(&domain_list) ? "No" : "Yes");
+ ast_cli(fd, " SIP domain support: %s\n", domains_configured() ? "No" : "Yes");
ast_cli(fd, " Call to non-local dom.: %s\n", global.allow_external_domains ? "Yes" : "No");
ast_cli(fd, " URI user is phone no: %s\n", ast_test_flag(&global.flags[0], SIP_USEREQPHONE) ? "Yes" : "No");
ast_cli(fd, " Our auth realm %s\n", global.realm);
@@ -9928,31 +9707,6 @@
"times, SIP_HEADER takes an optional second argument to specify which header with\n"
"that name to retrieve. Headers start at offset 1.\n",
.read = func_header_read,
-};
-
-/*! \brief Dial plan function to check if domain is local */
-static int func_check_sipdomain(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
-{
- if (ast_strlen_zero(data)) {
- ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
- return -1;
- }
- if (check_sip_domain(data, NULL, 0))
- ast_copy_string(buf, data, len);
- else
- buf[0] = '\0';
- return 0;
-}
-
-static struct ast_custom_function checksipdomain_function = {
- .name = "CHECKSIPDOMAIN",
- .synopsis = "Checks if domain is a local domain",
- .syntax = "CHECKSIPDOMAIN(<domain|IP>)",
- .read = func_check_sipdomain,
- .desc = "This function checks if the domain in the argument is configured\n"
- "as a local SIP domain that this Asterisk server is configured to handle.\n"
- "Returns the domain name if it is locally handled, otherwise an empty string.\n"
- "Check the domain= configuration in sip.conf\n",
};
/*! \brief ${SIPPEER()} Dialplan function - reads peer data */
@@ -12355,7 +12109,7 @@
p->refer->localtransfer = 1;
if (sipdebug && option_debug > 2)
ast_log(LOG_DEBUG, "This SIP transfer is local : %s\n", p->refer->refer_to_domain);
- } else if (AST_LIST_EMPTY(&domain_list)) {
+ } else if (domains_configured()) {
/* This PBX don't bother with SIP domains, so all transfers are local */
p->refer->localtransfer = 1;
} else
@@ -13255,7 +13009,7 @@
int reloading;
/* Add an I/O event to our SIP UDP socket */
- if (sipnet.sipsock > -1)
+ if (sipsocket_initialized())
sipnet.read_id = ast_io_add(io, sipnet.sipsock, sipsock_read, AST_IO_IN, NULL);
/* From here on out, we die whenever asked */
@@ -13271,7 +13025,7 @@
sip_do_reload(sip_reloadreason);
/* Change the I/O fd of our UDP socket */
- if (sipnet.sipsock > -1)
+ if (sipsocket_initialized())
sipnet.read_id = ast_io_change(io, sipnet.read_id, sipnet.sipsock, NULL, 0, NULL);
}
/* Check for interfaces needing to be killed */
@@ -13790,70 +13544,6 @@
return res;
}
-
-/*! \brief Add SIP domain to list of domains we are responsible for */
-static int add_sip_domain(const char *domain, const enum domain_mode mode, const char *context)
-{
- struct domain *d;
-
- if (ast_strlen_zero(domain)) {
- ast_log(LOG_WARNING, "Zero length domain.\n");
- return 1;
- }
-
- if (!(d = ast_calloc(1, sizeof(*d))))
- return 0;
-
- ast_copy_string(d->domain, domain, sizeof(d->domain));
-
- if (!ast_strlen_zero(context))
- ast_copy_string(d->context, context, sizeof(d->context));
-
- d->mode = mode;
-
- AST_LIST_LOCK(&domain_list);
- AST_LIST_INSERT_TAIL(&domain_list, d, list);
- AST_LIST_UNLOCK(&domain_list);
-
- if (sipdebug)
- ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
-
- return 1;
-}
-
-/*! \brief check_sip_domain: Check if domain part of uri is local to our server */
-static int check_sip_domain(const char *domain, char *context, size_t len)
-{
- struct domain *d;
- int result = 0;
-
- AST_LIST_LOCK(&domain_list);
- AST_LIST_TRAVERSE(&domain_list, d, list) {
- if (strcasecmp(d->domain, domain))
- continue;
-
- if (len && !ast_strlen_zero(d->context))
- ast_copy_string(context, d->context, len);
-
- result = 1;
- break;
- }
- AST_LIST_UNLOCK(&domain_list);
-
- return result;
-}
-
-/*! \brief Clear our domain list (at reload) */
-static void clear_sip_domains(void)
-{
- struct domain *d;
-
- AST_LIST_LOCK(&domain_list);
- while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
- free(d);
- AST_LIST_UNLOCK(&domain_list);
-}
-
/*! \brief Add realm authentication in list */
static struct sip_auth *add_realm_authentication(struct sip_auth *authlist, char *configuration, int lineno)
@@ -14766,7 +14456,7 @@
}
}
- if (!global.allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
+ if (!global.allow_external_domains && domains_configured()) {
ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
global.allow_external_domains = 1;
}
@@ -14832,38 +14522,12 @@
sipnet.bindaddr.sin_port = ntohs(DEFAULT_LISTEN_SIP_PORT);
sipnet.bindaddr.sin_family = AF_INET;
sipnet_lock();
- if ((sipnet.sipsock > -1) && (memcmp(&old_bindaddr, &sipnet.bindaddr, sizeof(struct sockaddr_in)))) {
+ if (sipsocket_initialized() && (memcmp(&old_bindaddr, &sipnet.bindaddr, sizeof(struct sockaddr_in)))) {
close(sipnet.sipsock);
sipnet.sipsock = -1;
}
- if (sipnet.sipsock < 0) {
- sipnet.sipsock = socket(AF_INET, SOCK_DGRAM, 0);
- if (sipnet.sipsock < 0) {
- ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
- } else {
- /* Allow SIP clients on the same host to access us: */
- const int reuseFlag = 1;
- setsockopt(sipnet.sipsock, SOL_SOCKET, SO_REUSEADDR,
- (const char*)&reuseFlag,
- sizeof reuseFlag);
-
- if (bind(sipnet.sipsock, (struct sockaddr *)&sipnet.bindaddr, sizeof(sipnet.bindaddr)) < 0) {
- ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
- ast_inet_ntoa(sipnet.bindaddr.sin_addr), ntohs(sipnet.bindaddr.sin_port),
- strerror(errno));
- close(sipnet.sipsock);
- sipnet.sipsock = -1;
- } else {
- if (option_verbose > 1) {
- ast_verbose(VERBOSE_PREFIX_2 "SIP Listening on %s:%d\n",
- ast_inet_ntoa(sipnet.bindaddr.sin_addr), ntohs(sipnet.bindaddr.sin_port));
- ast_verbose(VERBOSE_PREFIX_2 "Using SIP TOS: %s\n", ast_tos2str(global.tos_sip));
- }
- if (setsockopt(sipnet.sipsock, IPPROTO_IP, IP_TOS, &global.tos_sip, sizeof(global.tos_sip)))
- ast_log(LOG_WARNING, "Unable to set SIP TOS to %s\n", ast_tos2str(global.tos_sip));
- }
- }
- }
+ if (!sipsocket_initialized())
+ sipsocket_open(); /* Open socket, bind to address and set TOS option */
sipnet_unlock();
/* Add default domains - host name, IP address and IP:port */
Modified: team/oej/codename-pineapple/channels/sip3/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/Makefile?rev=44899&r1=44898&r2=44899&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/Makefile (original)
+++ team/oej/codename-pineapple/channels/sip3/Makefile Wed Oct 11 14:41:08 2006
@@ -1,7 +1,7 @@
#
# Makefile for chan_sip3 support
#
-all: sip3_refer.o sip3_subscribe.o sip3_network.o
+all: sip3_refer.o sip3_subscribe.o sip3_network.o sip3_domain.o sip3_callerid.o sip3_auth.c
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
Modified: team/oej/codename-pineapple/channels/sip3/sip3.h
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3.h?rev=44899&r1=44898&r2=44899&view=diff
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3.h (original)
+++ team/oej/codename-pineapple/channels/sip3/sip3.h Wed Oct 11 14:41:08 2006
@@ -895,4 +895,9 @@
int registry_objects;
};
+/* Ugly solution, please don't tell kpfleming */
+#ifndef CHAN_SIP3_MAIN
+extern struct sip_globals global; /* Defined in chan_sip3.c */
#endif
+
+#endif
Added: team/oej/codename-pineapple/channels/sip3/sip3_auth.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_auth.c?rev=44899&view=auto
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_auth.c (added)
+++ team/oej/codename-pineapple/channels/sip3/sip3_auth.c Wed Oct 11 14:41:08 2006
@@ -1,0 +1,252 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Various SIP authentication functions
+ * Version 3 of chan_sip
+ *
+ * \author Mark Spencer <markster at digium.com>
+ * \author Olle E. Johansson <oej at edvina.net> (all the chan_sip3 changes)
+ *
+ * See Also:
+ * \arg \ref AstCREDITS
+ *
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <signal.h>
+#include <sys/signal.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <arpa/inet.h>
+#include <netinet/ip.h>
+#include <regex.h>
+
+#include "asterisk/lock.h"
+#include "asterisk/channel.h"
+#include "asterisk/config.h"
+#include "asterisk/logger.h"
+#include "asterisk/module.h"
+#include "asterisk/pbx.h"
+#include "asterisk/options.h"
+#include "asterisk/lock.h"
+#include "asterisk/sched.h"
+#include "asterisk/io.h"
+#include "asterisk/rtp.h"
+#include "asterisk/udptl.h"
+#include "asterisk/acl.h"
+#include "asterisk/manager.h"
+#include "asterisk/callerid.h"
+#include "asterisk/cli.h"
+#include "asterisk/app.h"
+#include "asterisk/musiconhold.h"
+#include "asterisk/dsp.h"
+#include "asterisk/features.h"
+#include "asterisk/acl.h"
+#include "asterisk/srv.h"
+#include "asterisk/astdb.h"
+#include "asterisk/causes.h"
+#include "asterisk/utils.h"
+#include "asterisk/file.h"
+#include "asterisk/astobj.h"
+#include "asterisk/dnsmgr.h"
+#include "asterisk/devicestate.h"
+#include "asterisk/linkedlists.h"
+#include "asterisk/stringfields.h"
+#include "asterisk/monitor.h"
+#include "asterisk/localtime.h"
+#include "asterisk/abstract_jb.h"
+#include "asterisk/compiler.h"
+#include "sip3.h"
+
+/*! \brief Check user authorization from peer definition
+ Some actions, like REGISTER and INVITEs from peers require
+ authentication (if peer have secret set)
+ \return 0 on success, non-zero on error
+*/
+static enum check_auth_result check_auth(struct sip_pvt *p, struct sip_request *req, const char *username,
+ const char *secret, const char *md5secret, int sipmethod,
+ char *uri, enum xmittype reliable, int ignore)
+{
+ const char *response = "407 Proxy Authentication Required";
+ const char *reqheader = "Proxy-Authorization";
+ const char *respheader = "Proxy-Authenticate";
+ const char *authtoken;
+ char a1_hash[256];
+ char resp_hash[256]="";
+ char tmp[BUFSIZ * 2]; /* Make a large enough buffer */
+ char *c;
+ int wrongnonce = FALSE;
+ int good_response;
+ const char *usednonce = p->randdata;
+
+ /* table of recognised keywords, and their value in the digest */
+ enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
+ struct x {
+ const char *key;
+ const char *s;
+ } *i, keys[] = {
+ [K_RESP] = { "response=", "" },
+ [K_URI] = { "uri=", "" },
+ [K_USER] = { "username=", "" },
+ [K_NONCE] = { "nonce=", "" },
+ [K_LAST] = { NULL, NULL}
+ };
+
+ /* Always OK if no secret */
+ if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret))
+ return AUTH_SUCCESSFUL;
+ if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
+ /* On a REGISTER, we have to use 401 and its family of headers instead of 407 and its family
+ of headers -- GO SIP! Whoo hoo! Two things that do the same thing but are used in
+ different circumstances! What a surprise. */
+ response = "401 Unauthorized";
+ reqheader = "Authorization";
+ respheader = "WWW-Authenticate";
+ }
+ authtoken = get_header(req, reqheader);
+ if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
+ /* This is a retransmitted invite/register/etc, don't reconstruct authentication
+ information */
+ if (!reliable) {
+ /* Resend message if this was NOT a reliable delivery. Otherwise the
+ retransmission should get it */
+ transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
+ /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
+ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+ }
+ return AUTH_CHALLENGE_SENT;
+ } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
+ /* We have no auth, so issue challenge and request authentication */
+ ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
+ transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
+ /* Schedule auto destroy in 32 seconds */
+ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+ return AUTH_CHALLENGE_SENT;
+ }
+
+ /* --- We have auth, so check it */
+
+ /* 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. */
+
+
+ /* Make a copy of the response and parse it */
+ ast_copy_string(tmp, authtoken, sizeof(tmp));
+ c = tmp;
+
+ while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
+ for (i = keys; i->key != NULL; i++) {
+ const char *separator = ","; /* default */
+
+ if (strncasecmp(c, i->key, strlen(i->key)) != 0)
+ continue;
+ /* Found. Skip keyword, take text in quotes or up to the separator. */
+ c += strlen(i->key);
+ if (*c == '"') { /* in quotes. Skip first and look for last */
+ c++;
+ separator = "\"";
+ }
+ i->s = c;
+ strsep(&c, separator);
+ break;
+ }
+ if (i->key == NULL) /* not found, jump after space or comma */
+ strsep(&c, " ,");
+ }
+
+ /* Verify that digest username matches the username we auth as */
+ if (strcmp(username, keys[K_USER].s)) {
+ ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
+ username, keys[K_USER].s);
+ /* Oops, we're trying something here */
+ return AUTH_USERNAME_MISMATCH;
+ }
+
+ /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */
+ if (strcasecmp(p->randdata, keys[K_NONCE].s)) { /* XXX it was 'n'casecmp ? */
+ wrongnonce = TRUE;
+ usednonce = keys[K_NONCE].s;
+ }
+
+ if (!ast_strlen_zero(md5secret))
+ ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
+ else {
+ char a1[256];
+ snprintf(a1, sizeof(a1), "%s:%s:%s", username, global.realm, secret);
+ ast_md5_hash(a1_hash, a1);
+ }
+
+ /* compute the expected response to compare with what we received */
+ {
+ char a2[256];
+ char a2_hash[256];
+ char resp[256];
+
+ snprintf(a2, sizeof(a2), "%s:%s", sip_method2txt(sipmethod), S_OR(keys[K_URI].s, uri));
+ ast_md5_hash(a2_hash, a2);
+ snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
+ ast_md5_hash(resp_hash, resp);
+ }
+
+ good_response = keys[K_RESP].s &&
+ !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
+ if (wrongnonce) {
+ ast_string_field_build(p, randdata, "%08lx", ast_random());
+ if (good_response) {
+ if (sipdebug)
+ ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To"));
+ /* We got working auth token, based on stale nonce . */
+ transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 1);
+ } else {
+ /* Everything was wrong, so give the device one more try with a new challenge */
+ if (sipdebug)
+ ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
+ transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
+ }
+
+ /* Schedule auto destroy in 32 seconds */
+ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+ return AUTH_CHALLENGE_SENT;
+ }
+ if (good_response)
+ return AUTH_SUCCESSFUL;
+
+ /* Ok, we have a bad username/secret pair */
+ /* Challenge again, and again, and again */
+ transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
+ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+
+ return AUTH_CHALLENGE_SENT;
+}
+
Propchange: team/oej/codename-pineapple/channels/sip3/sip3_auth.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/oej/codename-pineapple/channels/sip3/sip3_auth.c
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/oej/codename-pineapple/channels/sip3/sip3_auth.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/oej/codename-pineapple/channels/sip3/sip3_callerid.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_callerid.c?rev=44899&view=auto
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_callerid.c (added)
+++ team/oej/codename-pineapple/channels/sip3/sip3_callerid.c Wed Oct 11 14:41:08 2006
@@ -1,0 +1,82 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Various SIP callerid functions
+ * Version 3 of chan_sip
+ *
+ * \author Mark Spencer <markster at digium.com>
+ * \author Olle E. Johansson <oej at edvina.net> (all the chan_sip3 changes)
+ *
+ * See Also:
+ * \arg \ref AstCREDITS
+ *
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <signal.h>
+#include <sys/signal.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <arpa/inet.h>
+#include <netinet/ip.h>
+#include <regex.h>
+
+#include "asterisk/lock.h"
+#include "asterisk/channel.h"
+#include "asterisk/config.h"
+#include "asterisk/logger.h"
+#include "asterisk/module.h"
+#include "asterisk/pbx.h"
+#include "asterisk/options.h"
+#include "asterisk/lock.h"
+#include "asterisk/sched.h"
+#include "asterisk/io.h"
+#include "asterisk/rtp.h"
+#include "asterisk/udptl.h"
+#include "asterisk/acl.h"
+#include "asterisk/callerid.h"
+#include "asterisk/app.h"
+#include "asterisk/astdb.h"
+#include "asterisk/causes.h"
+#include "asterisk/utils.h"
+#include "asterisk/file.h"
+#include "asterisk/astobj.h"
+#include "asterisk/dnsmgr.h"
+#include "asterisk/linkedlists.h"
+#include "asterisk/monitor.h"
+#include "asterisk/localtime.h"
+#include "asterisk/compiler.h"
+#include "sip3.h"
+
+
Propchange: team/oej/codename-pineapple/channels/sip3/sip3_callerid.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/oej/codename-pineapple/channels/sip3/sip3_callerid.c
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/oej/codename-pineapple/channels/sip3/sip3_callerid.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/oej/codename-pineapple/channels/sip3/sip3_domain.c
URL: http://svn.digium.com/view/asterisk/team/oej/codename-pineapple/channels/sip3/sip3_domain.c?rev=44899&view=auto
==============================================================================
--- team/oej/codename-pineapple/channels/sip3/sip3_domain.c (added)
+++ team/oej/codename-pineapple/channels/sip3/sip3_domain.c Wed Oct 11 14:41:08 2006
@@ -1,0 +1,223 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2006, Digium, Inc.
+ *
+ * Mark Spencer <markster at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Various SIP domains function
+ * Version 3 of chan_sip
+ *
+ * \author Mark Spencer <markster at digium.com>
+ * \author Olle E. Johansson <oej at edvina.net> (all the chan_sip3 changes)
+ *
+ * See Also:
+ * \arg \ref AstCREDITS
+ *
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <signal.h>
+#include <sys/signal.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <arpa/inet.h>
+#include <netinet/ip.h>
+#include <regex.h>
+
+#include "asterisk/lock.h"
+#include "asterisk/channel.h"
+#include "asterisk/config.h"
+#include "asterisk/logger.h"
+#include "asterisk/module.h"
+#include "asterisk/pbx.h"
+#include "asterisk/options.h"
+#include "asterisk/lock.h"
+#include "asterisk/sched.h"
+#include "asterisk/io.h"
+#include "asterisk/rtp.h"
+#include "asterisk/udptl.h"
+#include "asterisk/acl.h"
+#include "asterisk/manager.h"
+#include "asterisk/callerid.h"
+#include "asterisk/cli.h"
+#include "asterisk/app.h"
+#include "asterisk/musiconhold.h"
+#include "asterisk/dsp.h"
+#include "asterisk/features.h"
+#include "asterisk/acl.h"
+#include "asterisk/srv.h"
+#include "asterisk/astdb.h"
+#include "asterisk/causes.h"
+#include "asterisk/utils.h"
+#include "asterisk/file.h"
+#include "asterisk/astobj.h"
+#include "asterisk/dnsmgr.h"
+#include "asterisk/devicestate.h"
+#include "asterisk/linkedlists.h"
+#include "asterisk/stringfields.h"
+#include "asterisk/monitor.h"
+#include "asterisk/localtime.h"
+#include "asterisk/abstract_jb.h"
+#include "asterisk/compiler.h"
+#include "sip3.h"
+
+static AST_LIST_HEAD_STATIC(domain_list, domain); /*!< The SIP domain list */
+
+/*! \brief Add SIP domain to list of domains we are responsible for */
+static int add_sip_domain(const char *domain, const enum domain_mode mode, const char *context)
+{
+ struct domain *d;
+
+ if (ast_strlen_zero(domain)) {
+ ast_log(LOG_WARNING, "Zero length domain.\n");
+ return 1;
+ }
+
+ if (!(d = ast_calloc(1, sizeof(*d))))
+ return 0;
+
+ ast_copy_string(d->domain, domain, sizeof(d->domain));
+
+ if (!ast_strlen_zero(context))
+ ast_copy_string(d->context, context, sizeof(d->context));
+
+ d->mode = mode;
+
+ AST_LIST_LOCK(&domain_list);
+ AST_LIST_INSERT_TAIL(&domain_list, d, list);
+ AST_LIST_UNLOCK(&domain_list);
+
+ if (option_debug > 2)
+ ast_log(LOG_DEBUG, "Added local SIP domain '%s'\n", domain);
+
+ return 1;
+}
+
+/*! \brief return TRUE if any domains are configured for this server */
+static int domains_configured()
+{
+ return (!AST_LIST_EMPTY(&domain_list));
+}
+
+
+/*! \brief check_sip_domain: Check if domain part of uri is local to our server */
+static int check_sip_domain(const char *domain, char *context, size_t len)
+{
+ struct domain *d;
+ int result = 0;
+
+ AST_LIST_LOCK(&domain_list);
+ AST_LIST_TRAVERSE(&domain_list, d, list) {
+ if (strcasecmp(d->domain, domain))
+ continue;
+
+ if (len && !ast_strlen_zero(d->context))
+ ast_copy_string(context, d->context, len);
+
+ result = 1;
+ break;
+ }
+ AST_LIST_UNLOCK(&domain_list);
+
+ return result;
+}
+
+/*! \brief Clear our domain list (at reload) */
+static void clear_sip_domains(void)
+{
+ struct domain *d;
+
+ AST_LIST_LOCK(&domain_list);
+ while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
+ free(d);
+ AST_LIST_UNLOCK(&domain_list);
+}
+
+
+/*! \brief Dial plan function to check if domain is local */
+static int func_check_sipdomain(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
+{
+ if (ast_strlen_zero(data)) {
[... 893 lines stripped ...]
More information about the asterisk-commits
mailing list