Merged revisions 326291 via svnmerge from

https://origsvn.digium.com/svn/asterisk/branches/1.8

........
  r326291 | rmudgett | 2011-07-05 12:22:59 -0500 (Tue, 05 Jul 2011) | 23 lines
  
  Used auth= parameter freed during "sip reload" causes crash.
  
  If you use the auth= parameter and do a "sip reload" while there is an
  ongoing call.  The peer->auth data points to free'd memory.
  
  The patch does several things:
  
  1) Puts the authentication list into an ao2 object for reference counting
  to fix the reported crash during a SIP reload.
  
  2) Converts the authentication list from open coding to AST list macros.
  
  3) Adds display of the global authentication list in "sip show settings".
  
  (closes issue ASTERISK-17939)
  Reported by: wdoekes
  Patches:
        jira_asterisk_17939_v1.8.patch (license #5621) patch uploaded by rmudgett
  
  Review: https://reviewboard.asterisk.org/r/1303/
  
  JIRA SWP-3526
........


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@326321 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Richard Mudgett
2011-07-05 17:35:54 +00:00
parent 8b20d4ffe8
commit 14d510c5b7
2 changed files with 219 additions and 79 deletions

View File

@@ -1121,9 +1121,10 @@ static void temp_pvt_cleanup(void *);
/*! \brief A per-thread temporary pvt structure */ /*! \brief A per-thread temporary pvt structure */
AST_THREADSTORAGE_CUSTOM(ts_temp_pvt, temp_pvt_init, temp_pvt_cleanup); AST_THREADSTORAGE_CUSTOM(ts_temp_pvt, temp_pvt_init, temp_pvt_cleanup);
/*! \brief Authentication list for realm authentication /*! \brief Authentication container for realm authentication */
* \todo Move the sip_auth list to AST_LIST */ static struct sip_auth_container *authl = NULL;
static struct sip_auth *authl = NULL; /*! \brief Global authentication container protection while adjusting the references. */
AST_MUTEX_DEFINE_STATIC(authl_lock);
/* --- Sockets and networking --------------*/ /* --- Sockets and networking --------------*/
@@ -1329,9 +1330,8 @@ static int add_sip_domain(const char *domain, const enum domain_mode mode, const
static void clear_sip_domains(void); static void clear_sip_domains(void);
/*--- SIP realm authentication */ /*--- SIP realm authentication */
static struct sip_auth *add_realm_authentication(struct sip_auth *authlist, const char *configuration, int lineno); static void add_realm_authentication(struct sip_auth_container **credentials, const char *configuration, int lineno);
static int clear_realm_authentication(struct sip_auth *authlist); /* Clear realm authentication list (at reload) */ static struct sip_auth *find_realm_authentication(struct sip_auth_container *credentials, const char *realm);
static struct sip_auth *find_realm_authentication(struct sip_auth *authlist, const char *realm);
/*--- Misc functions */ /*--- Misc functions */
static void check_rtp_timeout(struct sip_pvt *dialog, time_t t); static void check_rtp_timeout(struct sip_pvt *dialog, time_t t);
@@ -4615,8 +4615,10 @@ static void sip_destroy_peer(struct sip_peer *peer)
ast_debug(3, "-REALTIME- peer Destroyed. Name: %s. Realtime Peer objects: %d\n", peer->name, rpeerobjs); ast_debug(3, "-REALTIME- peer Destroyed. Name: %s. Realtime Peer objects: %d\n", peer->name, rpeerobjs);
} else } else
ast_atomic_fetchadd_int(&speerobjs, -1); ast_atomic_fetchadd_int(&speerobjs, -1);
clear_realm_authentication(peer->auth); if (peer->auth) {
ao2_t_ref(peer->auth, -1, "Removing peer authentication");
peer->auth = NULL; peer->auth = NULL;
}
if (peer->dnsmgr) if (peer->dnsmgr)
ast_dnsmgr_release(peer->dnsmgr); ast_dnsmgr_release(peer->dnsmgr);
clear_peer_mailboxes(peer); clear_peer_mailboxes(peer);
@@ -5117,6 +5119,8 @@ static int dialog_initialize_rtp(struct sip_pvt *dialog)
*/ */
static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer) static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
{ {
struct sip_auth_container *credentials;
/* this checks that the dialog is contacting the peer on a valid /* this checks that the dialog is contacting the peer on a valid
* transport type based on the peers transport configuration, * transport type based on the peers transport configuration,
* otherwise, this function bails out */ * otherwise, this function bails out */
@@ -5205,7 +5209,21 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
dialog->allowtransfer = peer->allowtransfer; dialog->allowtransfer = peer->allowtransfer;
dialog->jointnoncodeccapability = dialog->noncodeccapability; dialog->jointnoncodeccapability = dialog->noncodeccapability;
dialog->rtptimeout = peer->rtptimeout; dialog->rtptimeout = peer->rtptimeout;
dialog->peerauth = peer->auth;
/* Update dialog authorization credentials */
ao2_lock(peer);
credentials = peer->auth;
if (credentials) {
ao2_t_ref(credentials, +1, "Ref peer auth for dialog");
}
ao2_unlock(peer);
ao2_lock(dialog);
if (dialog->peerauth) {
ao2_t_ref(dialog->peerauth, -1, "Unref old dialog peer auth");
}
dialog->peerauth = credentials;
ao2_unlock(dialog);
dialog->maxcallbitrate = peer->maxcallbitrate; dialog->maxcallbitrate = peer->maxcallbitrate;
dialog->disallowed_methods = peer->disallowed_methods; dialog->disallowed_methods = peer->disallowed_methods;
ast_cc_copy_config_params(dialog->cc_params, peer->cc_params); ast_cc_copy_config_params(dialog->cc_params, peer->cc_params);
@@ -5732,6 +5750,12 @@ void __sip_destroy(struct sip_pvt *p, int lockowner, int lockdialoglist)
ao2_ref(p->socket.tcptls_session, -1); ao2_ref(p->socket.tcptls_session, -1);
p->socket.tcptls_session = NULL; p->socket.tcptls_session = NULL;
} }
if (p->peerauth) {
ao2_t_ref(p->peerauth, -1, "Removing active peer authentication");
p->peerauth = NULL;
}
p->caps = ast_format_cap_destroy(p->caps); p->caps = ast_format_cap_destroy(p->caps);
p->jointcaps = ast_format_cap_destroy(p->jointcaps); p->jointcaps = ast_format_cap_destroy(p->jointcaps);
p->peercaps = ast_format_cap_destroy(p->peercaps); p->peercaps = ast_format_cap_destroy(p->peercaps);
@@ -17227,7 +17251,6 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
char codec_buf[512]; char codec_buf[512];
struct ast_codec_pref *pref; struct ast_codec_pref *pref;
struct ast_variable *v; struct ast_variable *v;
struct sip_auth *auth;
int x = 0, load_realtime; int x = 0, load_realtime;
struct ast_format codec; struct ast_format codec;
int realtimepeers; int realtimepeers;
@@ -17255,6 +17278,15 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
} }
if (peer && type==0 ) { /* Normal listing */ if (peer && type==0 ) { /* Normal listing */
struct ast_str *mailbox_str = ast_str_alloca(512); struct ast_str *mailbox_str = ast_str_alloca(512);
struct sip_auth_container *credentials;
ao2_lock(peer);
credentials = peer->auth;
if (credentials) {
ao2_t_ref(credentials, +1, "Ref peer auth for show");
}
ao2_unlock(peer);
ast_cli(fd, "\n\n"); ast_cli(fd, "\n\n");
ast_cli(fd, " * Name : %s\n", peer->name); ast_cli(fd, " * Name : %s\n", peer->name);
ast_cli(fd, " Description : %s\n", peer->description); ast_cli(fd, " Description : %s\n", peer->description);
@@ -17264,9 +17296,19 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>"); ast_cli(fd, " MD5Secret : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
ast_cli(fd, " Remote Secret: %s\n", ast_strlen_zero(peer->remotesecret)?"<Not set>":"<Set>"); ast_cli(fd, " Remote Secret: %s\n", ast_strlen_zero(peer->remotesecret)?"<Not set>":"<Set>");
for (auth = peer->auth; auth; auth = auth->next) { if (credentials) {
ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s ", auth->realm, auth->username); struct sip_auth *auth;
ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>"));
AST_LIST_TRAVERSE(&credentials->list, auth, node) {
ast_cli(fd, " Realm-auth : Realm %-15.15s User %-10.20s %s\n",
auth->realm,
auth->username,
!ast_strlen_zero(auth->secret)
? "<Secret set>"
: (!ast_strlen_zero(auth->md5secret)
? "<MD5secret set>" : "<Not set>"));
}
ao2_t_ref(credentials, -1, "Unref peer auth for show");
} }
ast_cli(fd, " Context : %s\n", peer->context); ast_cli(fd, " Context : %s\n", peer->context);
ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") ); ast_cli(fd, " Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") );
@@ -17823,6 +17865,7 @@ static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_
int realtimeregs; int realtimeregs;
char codec_buf[SIPBUFSIZE]; char codec_buf[SIPBUFSIZE];
const char *msg; /* temporary msg pointer */ const char *msg; /* temporary msg pointer */
struct sip_auth_container *credentials;
switch (cmd) { switch (cmd) {
case CLI_INIT: case CLI_INIT:
@@ -17835,12 +17878,19 @@ static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_
return NULL; return NULL;
} }
if (a->argc != 3)
return CLI_SHOWUSAGE;
realtimepeers = ast_check_realtime("sippeers"); realtimepeers = ast_check_realtime("sippeers");
realtimeregs = ast_check_realtime("sipregs"); realtimeregs = ast_check_realtime("sipregs");
if (a->argc != 3) ast_mutex_lock(&authl_lock);
return CLI_SHOWUSAGE; credentials = authl;
if (credentials) {
ao2_t_ref(credentials, +1, "Ref global auth for show");
}
ast_mutex_unlock(&authl_lock);
ast_cli(a->fd, "\n\nGlobal Settings:\n"); ast_cli(a->fd, "\n\nGlobal Settings:\n");
ast_cli(a->fd, "----------------\n"); ast_cli(a->fd, "----------------\n");
ast_cli(a->fd, " UDP Bindaddress: %s\n", ast_sockaddr_stringify(&bindaddr)); ast_cli(a->fd, " UDP Bindaddress: %s\n", ast_sockaddr_stringify(&bindaddr));
@@ -17867,7 +17917,21 @@ static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_
ast_cli(a->fd, " Allow promisc. redir: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR))); ast_cli(a->fd, " Allow promisc. redir: %s\n", AST_CLI_YESNO(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR)));
ast_cli(a->fd, " Enable call counters: %s\n", AST_CLI_YESNO(global_callcounter)); ast_cli(a->fd, " Enable call counters: %s\n", AST_CLI_YESNO(global_callcounter));
ast_cli(a->fd, " SIP domain support: %s\n", AST_CLI_YESNO(!AST_LIST_EMPTY(&domain_list))); ast_cli(a->fd, " SIP domain support: %s\n", AST_CLI_YESNO(!AST_LIST_EMPTY(&domain_list)));
ast_cli(a->fd, " Realm. auth: %s\n", AST_CLI_YESNO(authl != NULL)); ast_cli(a->fd, " Realm. auth: %s\n", AST_CLI_YESNO(credentials != NULL));
if (credentials) {
struct sip_auth *auth;
AST_LIST_TRAVERSE(&credentials->list, auth, node) {
ast_cli(a->fd, " Realm. auth entry: Realm %-15.15s User %-10.20s %s\n",
auth->realm,
auth->username,
!ast_strlen_zero(auth->secret)
? "<Secret set>"
: (!ast_strlen_zero(auth->md5secret)
? "<MD5secret set>" : "<Not set>"));
}
ao2_t_ref(credentials, -1, "Unref global auth for show");
}
ast_cli(a->fd, " Our auth realm %s\n", sip_cfg.realm); ast_cli(a->fd, " Our auth realm %s\n", sip_cfg.realm);
ast_cli(a->fd, " Use domains as realms: %s\n", AST_CLI_YESNO(sip_cfg.domainsasrealm)); ast_cli(a->fd, " Use domains as realms: %s\n", AST_CLI_YESNO(sip_cfg.domainsasrealm));
ast_cli(a->fd, " Call to non-local dom.: %s\n", AST_CLI_YESNO(sip_cfg.allow_external_domains)); ast_cli(a->fd, " Call to non-local dom.: %s\n", AST_CLI_YESNO(sip_cfg.allow_external_domains));
@@ -19065,7 +19129,8 @@ static int build_reply_digest(struct sip_pvt *p, int method, char* digest, int d
const char *username; const char *username;
const char *secret; const char *secret;
const char *md5secret; const char *md5secret;
struct sip_auth *auth = NULL; /* Realm authentication */ struct sip_auth *auth; /* Realm authentication credential */
struct sip_auth_container *credentials;
if (!ast_strlen_zero(p->domain)) if (!ast_strlen_zero(p->domain))
ast_copy_string(uri, p->domain, sizeof(uri)); ast_copy_string(uri, p->domain, sizeof(uri));
@@ -19076,9 +19141,27 @@ static int build_reply_digest(struct sip_pvt *p, int method, char* digest, int d
snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random()); snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
/* Check if we have separate auth credentials */ /* Check if we have peer credentials */
if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */ ao2_lock(p);
auth = find_realm_authentication(authl, p->realm); /* If not, global list */ credentials = p->peerauth;
if (credentials) {
ao2_t_ref(credentials, +1, "Ref peer auth for digest");
}
ao2_unlock(p);
auth = find_realm_authentication(credentials, p->realm);
if (!auth) {
/* If not, check global credentials */
if (credentials) {
ao2_t_ref(credentials, -1, "Unref peer auth for digest");
}
ast_mutex_lock(&authl_lock);
credentials = authl;
if (credentials) {
ao2_t_ref(credentials, +1, "Ref global auth for digest");
}
ast_mutex_unlock(&authl_lock);
auth = find_realm_authentication(credentials, p->realm);
}
if (auth) { if (auth) {
ast_debug(3, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username); ast_debug(3, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username);
@@ -19095,8 +19178,13 @@ static int build_reply_digest(struct sip_pvt *p, int method, char* digest, int d
? p->relatedpeer->remotesecret : p->peersecret; ? p->relatedpeer->remotesecret : p->peersecret;
md5secret = p->peermd5secret; md5secret = p->peermd5secret;
} }
if (ast_strlen_zero(username)) /* We have no authentication */ if (ast_strlen_zero(username)) {
/* We have no authentication */
if (credentials) {
ao2_t_ref(credentials, -1, "Unref auth for digest");
}
return -1; return -1;
}
/* Calculate SIP digest response */ /* Calculate SIP digest response */
snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret); snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret);
@@ -19127,6 +19215,9 @@ static int build_reply_digest(struct sip_pvt *p, int method, char* digest, int d
append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount); append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
if (credentials) {
ao2_t_ref(credentials, -1, "Unref auth for digest");
}
return 0; return 0;
} }
@@ -26715,20 +26806,48 @@ static void clear_sip_domains(void)
AST_LIST_UNLOCK(&domain_list); AST_LIST_UNLOCK(&domain_list);
} }
/*!
/*! \brief Add realm authentication in list */ * \internal
static struct sip_auth *add_realm_authentication(struct sip_auth *authlist, const char *configuration, int lineno) * \brief Realm authentication container destructor.
*
* \param obj Container object to destroy.
*
* \return Nothing
*/
static void destroy_realm_authentication(void *obj)
{ {
char authcopy[256]; struct sip_auth_container *credentials = obj;
char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL; struct sip_auth *auth;
struct sip_auth *a, *b, *auth;
if (ast_strlen_zero(configuration)) while ((auth = AST_LIST_REMOVE_HEAD(&credentials->list, node))) {
return authlist; ast_free(auth);
}
}
/*!
* \internal
* \brief Add realm authentication to credentials.
*
* \param credentials Realm authentication container to create/add authentication credentials.
* \param configuration Credential configuration value.
* \param lineno Line number in config file.
*
* \return Nothing
*/
static void add_realm_authentication(struct sip_auth_container **credentials, const char *configuration, int lineno)
{
char *authcopy;
char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
struct sip_auth *auth;
if (ast_strlen_zero(configuration)) {
/* Nothing to add */
return;
}
ast_debug(1, "Auth config :: %s\n", configuration); ast_debug(1, "Auth config :: %s\n", configuration);
ast_copy_string(authcopy, configuration, sizeof(authcopy)); authcopy = ast_strdupa(configuration);
username = authcopy; username = authcopy;
/* split user[:secret] and relm */ /* split user[:secret] and relm */
@@ -26737,7 +26856,7 @@ static struct sip_auth *add_realm_authentication(struct sip_auth *authlist, cons
*realm++ = '\0'; *realm++ = '\0';
if (ast_strlen_zero(username) || ast_strlen_zero(realm)) { if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno); ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
return authlist; return;
} }
/* parse username at ':' for secret, or '#" for md5secret */ /* parse username at ':' for secret, or '#" for md5secret */
@@ -26747,9 +26866,21 @@ static struct sip_auth *add_realm_authentication(struct sip_auth *authlist, cons
*md5secret++ = '\0'; *md5secret++ = '\0';
} }
if (!(auth = ast_calloc(1, sizeof(*auth)))) /* Create the continer if needed. */
return authlist; if (!*credentials) {
*credentials = ao2_t_alloc(sizeof(**credentials), destroy_realm_authentication,
"Create realm auth container.");
if (!*credentials) {
/* Failed to create the credentials container. */
return;
}
}
/* Create the authentication credential entry. */
auth = ast_calloc(1, sizeof(*auth));
if (!auth) {
return;
}
ast_copy_string(auth->realm, realm, sizeof(auth->realm)); ast_copy_string(auth->realm, realm, sizeof(auth->realm));
ast_copy_string(auth->username, username, sizeof(auth->username)); ast_copy_string(auth->username, username, sizeof(auth->username));
if (secret) if (secret)
@@ -26757,46 +26888,36 @@ static struct sip_auth *add_realm_authentication(struct sip_auth *authlist, cons
if (md5secret) if (md5secret)
ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret)); ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
/* find the end of the list */ /* Add credential to container list. */
for (b = NULL, a = authlist; a ; b = a, a = a->next) AST_LIST_INSERT_TAIL(&(*credentials)->list, auth, node);
;
if (b)
b->next = auth; /* Add structure add end of list */
else
authlist = auth;
ast_verb(3, "Added authentication for realm %s\n", realm); ast_verb(3, "Added authentication for realm %s\n", realm);
return authlist;
} }
/*! \brief Clear realm authentication list (at reload) */ /*!
static int clear_realm_authentication(struct sip_auth *authlist) * \internal
* \brief Find authentication for a specific realm.
*
* \param credentials Realm authentication container to search.
* \param realm Authentication realm to find.
*
* \return Found authentication credential or NULL.
*/
static struct sip_auth *find_realm_authentication(struct sip_auth_container *credentials, const char *realm)
{ {
struct sip_auth *a = authlist; struct sip_auth *auth;
struct sip_auth *b;
while (a) { if (credentials) {
b = a; AST_LIST_TRAVERSE(&credentials->list, auth, node) {
a = a->next; if (!strcasecmp(auth->realm, realm)) {
ast_free(b);
}
return 1;
}
/*! \brief Find authentication for a specific realm */
static struct sip_auth *find_realm_authentication(struct sip_auth *authlist, const char *realm)
{
struct sip_auth *a;
for (a = authlist; a; a = a->next) {
if (!strcasecmp(a->realm, realm))
break; break;
} }
}
} else {
auth = NULL;
}
return a; return auth;
} }
/*! \brief /*! \brief
@@ -27042,8 +27163,13 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
peer->portinuri = 0; peer->portinuri = 0;
/* If we have realm authentication information, remove them (reload) */ /* If we have realm authentication information, remove them (reload) */
clear_realm_authentication(peer->auth); ao2_lock(peer);
if (peer->auth) {
ao2_t_ref(peer->auth, -1, "Removing old peer authentication");
peer->auth = NULL; peer->auth = NULL;
}
ao2_unlock(peer);
/* clear the transport information. We will detect if a default value is required after parsing the config */ /* clear the transport information. We will detect if a default value is required after parsing the config */
peer->default_outbound_transport = 0; peer->default_outbound_transport = 0;
peer->transports = 0; peer->transports = 0;
@@ -27107,7 +27233,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
} else if (!strcasecmp(v->name, "md5secret")) { } else if (!strcasecmp(v->name, "md5secret")) {
ast_string_field_set(peer, md5secret, v->value); ast_string_field_set(peer, md5secret, v->value);
} else if (!strcasecmp(v->name, "auth")) { } else if (!strcasecmp(v->name, "auth")) {
peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno); add_realm_authentication(&peer->auth, v->value, v->lineno);
} else if (!strcasecmp(v->name, "callerid")) { } else if (!strcasecmp(v->name, "callerid")) {
char cid_name[80] = { '\0' }, cid_num[80] = { '\0' }; char cid_name[80] = { '\0' }, cid_num[80] = { '\0' };
@@ -27719,9 +27845,13 @@ static int reload_config(enum channelreloadreason reason)
if (reason != CHANNEL_MODULE_LOAD) { if (reason != CHANNEL_MODULE_LOAD) {
ast_debug(4, "--------------- SIP reload started\n"); ast_debug(4, "--------------- SIP reload started\n");
clear_realm_authentication(authl);
clear_sip_domains(); clear_sip_domains();
ast_mutex_lock(&authl_lock);
if (authl) {
ao2_t_ref(authl, -1, "Removing old global authentication");
authl = NULL; authl = NULL;
}
ast_mutex_unlock(&authl_lock);
/* First, destroy all outstanding registry calls */ /* First, destroy all outstanding registry calls */
/* This is needed, since otherwise active registry entries will not be destroyed */ /* This is needed, since otherwise active registry entries will not be destroyed */
@@ -28453,7 +28583,7 @@ static int reload_config(enum channelreloadreason reason)
for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) { for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) {
/* Format for authentication is auth = username:password@realm */ /* Format for authentication is auth = username:password@realm */
if (!strcasecmp(v->name, "auth")) { if (!strcasecmp(v->name, "auth")) {
authl = add_realm_authentication(authl, v->value, v->lineno); add_realm_authentication(&authl, v->value, v->lineno);
} }
} }
@@ -30243,7 +30373,12 @@ static int unload_module(void)
/* Free memory for local network address mask */ /* Free memory for local network address mask */
ast_free_ha(localaddr); ast_free_ha(localaddr);
clear_realm_authentication(authl); ast_mutex_lock(&authl_lock);
if (authl) {
ao2_t_ref(authl, -1, "Removing global authentication");
authl = NULL;
}
ast_mutex_unlock(&authl_lock);
destroy_escs(); destroy_escs();

View File

@@ -829,11 +829,16 @@ struct sip_history {
/*! \brief sip_auth: Credentials for authentication to other SIP services */ /*! \brief sip_auth: Credentials for authentication to other SIP services */
struct sip_auth { struct sip_auth {
AST_LIST_ENTRY(sip_auth) node;
char realm[AST_MAX_EXTENSION]; /*!< Realm in which these credentials are valid */ char realm[AST_MAX_EXTENSION]; /*!< Realm in which these credentials are valid */
char username[256]; /*!< Username */ char username[256]; /*!< Username */
char secret[256]; /*!< Secret */ char secret[256]; /*!< Secret */
char md5secret[256]; /*!< MD5Secret */ char md5secret[256]; /*!< MD5Secret */
struct sip_auth *next; /*!< Next auth structure in list */ };
/*! \brief Container of SIP authentication credentials. */
struct sip_auth_container {
AST_LIST_HEAD_NOLOCK(, sip_auth) list;
}; };
/*! \brief T.38 channel settings (at some point we need to make this alloc'ed */ /*! \brief T.38 channel settings (at some point we need to make this alloc'ed */
@@ -1046,7 +1051,7 @@ struct sip_pvt {
struct ast_channel *owner; /*!< Who owns us (if we have an owner) */ struct ast_channel *owner; /*!< Who owns us (if we have an owner) */
struct sip_route *route; /*!< Head of linked list of routing steps (fm Record-Route) */ struct sip_route *route; /*!< Head of linked list of routing steps (fm Record-Route) */
struct sip_notify *notify; /*!< Custom notify type */ struct sip_notify *notify; /*!< Custom notify type */
struct sip_auth *peerauth; /*!< Realm authentication */ struct sip_auth_container *peerauth;/*!< Realm authentication credentials */
int noncecount; /*!< Nonce-count */ int noncecount; /*!< Nonce-count */
unsigned int stalenonce:1; /*!< Marks the current nonce as responded too */ unsigned int stalenonce:1; /*!< Marks the current nonce as responded too */
char lastmsg[256]; /*!< Last Message sent/received */ char lastmsg[256]; /*!< Last Message sent/received */
@@ -1209,7 +1214,7 @@ struct sip_peer {
* for incoming calls * for incoming calls
*/ */
unsigned short deprecated_username:1; /*!< If it's a realtime peer, are they using the deprecated "username" instead of "defaultuser" */ unsigned short deprecated_username:1; /*!< If it's a realtime peer, are they using the deprecated "username" instead of "defaultuser" */
struct sip_auth *auth; /*!< Realm authentication list */ struct sip_auth_container *auth;/*!< Realm authentication credentials */
int amaflags; /*!< AMA Flags (for billing) */ int amaflags; /*!< AMA Flags (for billing) */
int callingpres; /*!< Calling id presentation */ int callingpres; /*!< Calling id presentation */
int inUse; /*!< Number of calls in use */ int inUse; /*!< Number of calls in use */