mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-09 11:28:25 +00:00
Add configuration option for IAX2 users that will limit the amount of outstanding AUTHREQs we are waiting for replies on.
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.2@37378 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -264,7 +264,8 @@ enum {
|
|||||||
IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */
|
IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */
|
||||||
IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */
|
IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */
|
||||||
IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */
|
IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */
|
||||||
IAX_TRUNKTIMESTAMPS = (1 << 22) /*!< Send trunk timestamps */
|
IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */
|
||||||
|
IAX_MAXAUTHREQ = (1 << 23) /*!< Maximum outstanding AUTHREQ restriction is in place */
|
||||||
} iax2_flags;
|
} iax2_flags;
|
||||||
|
|
||||||
static int global_rtautoclear = 120;
|
static int global_rtautoclear = 120;
|
||||||
@@ -285,6 +286,8 @@ struct iax2_user {
|
|||||||
int amaflags;
|
int amaflags;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
int capability;
|
int capability;
|
||||||
|
int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
|
||||||
|
int curauthreq; /*!< Current number of outstanding AUTHREQs */
|
||||||
char cid_num[AST_MAX_EXTENSION];
|
char cid_num[AST_MAX_EXTENSION];
|
||||||
char cid_name[AST_MAX_EXTENSION];
|
char cid_name[AST_MAX_EXTENSION];
|
||||||
struct ast_codec_pref prefs;
|
struct ast_codec_pref prefs;
|
||||||
@@ -1525,6 +1528,7 @@ static int iax2_predestroy(int callno)
|
|||||||
{
|
{
|
||||||
struct ast_channel *c;
|
struct ast_channel *c;
|
||||||
struct chan_iax2_pvt *pvt;
|
struct chan_iax2_pvt *pvt;
|
||||||
|
struct iax2_user *user;
|
||||||
ast_mutex_lock(&iaxsl[callno]);
|
ast_mutex_lock(&iaxsl[callno]);
|
||||||
pvt = iaxs[callno];
|
pvt = iaxs[callno];
|
||||||
if (!pvt) {
|
if (!pvt) {
|
||||||
@@ -1532,6 +1536,18 @@ static int iax2_predestroy(int callno)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
|
if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
|
||||||
|
if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
|
||||||
|
ast_mutex_lock(&userl.lock);
|
||||||
|
user = userl.users;
|
||||||
|
while (user) {
|
||||||
|
if (!strcmp(user->name, pvt->username)) {
|
||||||
|
user->curauthreq--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
user = user->next;
|
||||||
|
}
|
||||||
|
ast_mutex_unlock(&userl.lock);
|
||||||
|
}
|
||||||
/* No more pings or lagrq's */
|
/* No more pings or lagrq's */
|
||||||
if (pvt->pingid > -1)
|
if (pvt->pingid > -1)
|
||||||
ast_sched_del(sched, pvt->pingid);
|
ast_sched_del(sched, pvt->pingid);
|
||||||
@@ -1586,6 +1602,7 @@ static void iax2_destroy(int callno)
|
|||||||
struct chan_iax2_pvt *pvt;
|
struct chan_iax2_pvt *pvt;
|
||||||
struct iax_frame *cur;
|
struct iax_frame *cur;
|
||||||
struct ast_channel *owner;
|
struct ast_channel *owner;
|
||||||
|
struct iax2_user *user;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
ast_mutex_lock(&iaxsl[callno]);
|
ast_mutex_lock(&iaxsl[callno]);
|
||||||
@@ -1609,6 +1626,18 @@ retry:
|
|||||||
if (pvt) {
|
if (pvt) {
|
||||||
if (!owner)
|
if (!owner)
|
||||||
pvt->owner = NULL;
|
pvt->owner = NULL;
|
||||||
|
if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
|
||||||
|
ast_mutex_lock(&userl.lock);
|
||||||
|
user = userl.users;
|
||||||
|
while (user) {
|
||||||
|
if (!strcmp(user->name, pvt->username)) {
|
||||||
|
user->curauthreq--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
user = user->next;
|
||||||
|
}
|
||||||
|
ast_mutex_unlock(&userl.lock);
|
||||||
|
}
|
||||||
/* No more pings or lagrq's */
|
/* No more pings or lagrq's */
|
||||||
if (pvt->pingid > -1)
|
if (pvt->pingid > -1)
|
||||||
ast_sched_del(sched, pvt->pingid);
|
ast_sched_del(sched, pvt->pingid);
|
||||||
@@ -4832,6 +4861,9 @@ static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies
|
|||||||
iaxs[callno]->vars = tmpvar;
|
iaxs[callno]->vars = tmpvar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* If a max AUTHREQ restriction is in place, activate it */
|
||||||
|
if (user->maxauthreq > 0)
|
||||||
|
ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
|
||||||
iaxs[callno]->prefs = user->prefs;
|
iaxs[callno]->prefs = user->prefs;
|
||||||
ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
|
ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
|
||||||
ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
|
ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
|
||||||
@@ -4936,9 +4968,37 @@ static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
|
|||||||
|
|
||||||
static int authenticate_request(struct chan_iax2_pvt *p)
|
static int authenticate_request(struct chan_iax2_pvt *p)
|
||||||
{
|
{
|
||||||
|
struct iax2_user *user = NULL;
|
||||||
struct iax_ie_data ied;
|
struct iax_ie_data ied;
|
||||||
int res;
|
int res = -1, authreq_restrict = 0;
|
||||||
|
|
||||||
memset(&ied, 0, sizeof(ied));
|
memset(&ied, 0, sizeof(ied));
|
||||||
|
|
||||||
|
/* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
|
||||||
|
if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
|
||||||
|
ast_mutex_lock(&userl.lock);
|
||||||
|
user = userl.users;
|
||||||
|
while (user) {
|
||||||
|
if (!strcmp(user->name, p->username)) {
|
||||||
|
if (user->curauthreq == user->maxauthreq)
|
||||||
|
authreq_restrict = 1;
|
||||||
|
else
|
||||||
|
user->curauthreq++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
user = user->next;
|
||||||
|
}
|
||||||
|
ast_mutex_unlock(&userl.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the AUTHREQ limit test failed, send back an error */
|
||||||
|
if (authreq_restrict) {
|
||||||
|
iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
|
||||||
|
iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
|
||||||
|
send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
|
iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
|
||||||
if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
|
if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
|
||||||
snprintf(p->challenge, sizeof(p->challenge), "%d", rand());
|
snprintf(p->challenge, sizeof(p->challenge), "%d", rand());
|
||||||
@@ -4946,10 +5006,14 @@ static int authenticate_request(struct chan_iax2_pvt *p)
|
|||||||
}
|
}
|
||||||
if (p->encmethods)
|
if (p->encmethods)
|
||||||
iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
|
iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
|
||||||
|
|
||||||
iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
|
iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
|
||||||
|
|
||||||
res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
|
res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
|
||||||
|
|
||||||
if (p->encmethods)
|
if (p->encmethods)
|
||||||
ast_set_flag(p, IAX_ENCRYPTED);
|
ast_set_flag(p, IAX_ENCRYPTED);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4961,6 +5025,21 @@ static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
|
|||||||
char rsasecret[256] = "";
|
char rsasecret[256] = "";
|
||||||
int res = -1;
|
int res = -1;
|
||||||
int x;
|
int x;
|
||||||
|
struct iax2_user *user = NULL;
|
||||||
|
|
||||||
|
if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
|
||||||
|
ast_mutex_lock(&userl.lock);
|
||||||
|
user = userl.users;
|
||||||
|
while (user) {
|
||||||
|
if (!strcmp(user->name, p->username)) {
|
||||||
|
user->curauthreq--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
user = user->next;
|
||||||
|
}
|
||||||
|
ast_mutex_unlock(&userl.lock);
|
||||||
|
ast_clear_flag(p, IAX_MAXAUTHREQ);
|
||||||
|
}
|
||||||
|
|
||||||
if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
|
if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
|
||||||
return res;
|
return res;
|
||||||
@@ -6960,7 +7039,7 @@ retryowner:
|
|||||||
merge_encryption(iaxs[fr->callno],ies.encmethods);
|
merge_encryption(iaxs[fr->callno],ies.encmethods);
|
||||||
else
|
else
|
||||||
iaxs[fr->callno]->encmethods = 0;
|
iaxs[fr->callno]->encmethods = 0;
|
||||||
authenticate_request(iaxs[fr->callno]);
|
if (!authenticate_request(iaxs[fr->callno]))
|
||||||
ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
|
ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
|
||||||
break;
|
break;
|
||||||
case IAX_COMMAND_DPREQ:
|
case IAX_COMMAND_DPREQ:
|
||||||
@@ -8325,6 +8404,7 @@ static struct iax2_user *build_user(const char *name, struct ast_variable *v, in
|
|||||||
struct ast_ha *oldha = NULL;
|
struct ast_ha *oldha = NULL;
|
||||||
struct iax2_context *oldcon = NULL;
|
struct iax2_context *oldcon = NULL;
|
||||||
int format;
|
int format;
|
||||||
|
int oldcurauthreq = 0;
|
||||||
char *varname = NULL, *varval = NULL;
|
char *varname = NULL, *varval = NULL;
|
||||||
struct ast_variable *tmpvar = NULL;
|
struct ast_variable *tmpvar = NULL;
|
||||||
|
|
||||||
@@ -8343,6 +8423,7 @@ static struct iax2_user *build_user(const char *name, struct ast_variable *v, in
|
|||||||
user = NULL;
|
user = NULL;
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
|
oldcurauthreq = user->curauthreq;
|
||||||
oldha = user->ha;
|
oldha = user->ha;
|
||||||
oldcon = user->contexts;
|
oldcon = user->contexts;
|
||||||
user->ha = NULL;
|
user->ha = NULL;
|
||||||
@@ -8363,6 +8444,7 @@ static struct iax2_user *build_user(const char *name, struct ast_variable *v, in
|
|||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
memset(user, 0, sizeof(struct iax2_user));
|
memset(user, 0, sizeof(struct iax2_user));
|
||||||
|
user->curauthreq = oldcurauthreq;
|
||||||
user->prefs = prefs;
|
user->prefs = prefs;
|
||||||
user->capability = iax2_capability;
|
user->capability = iax2_capability;
|
||||||
user->encmethods = iax2_encryption;
|
user->encmethods = iax2_encryption;
|
||||||
@@ -8445,6 +8527,10 @@ static struct iax2_user *build_user(const char *name, struct ast_variable *v, in
|
|||||||
}
|
}
|
||||||
} else if (!strcasecmp(v->name, "inkeys")) {
|
} else if (!strcasecmp(v->name, "inkeys")) {
|
||||||
ast_copy_string(user->inkeys, v->value, sizeof(user->inkeys));
|
ast_copy_string(user->inkeys, v->value, sizeof(user->inkeys));
|
||||||
|
} else if (!strcasecmp(v->name, "maxauthreq")) {
|
||||||
|
user->maxauthreq = atoi(v->value);
|
||||||
|
if (user->maxauthreq < 0)
|
||||||
|
user->maxauthreq = 0;
|
||||||
}/* else if (strcasecmp(v->name,"type")) */
|
}/* else if (strcasecmp(v->name,"type")) */
|
||||||
/* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
|
/* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
|
||||||
v = v->next;
|
v = v->next;
|
||||||
|
|||||||
@@ -349,6 +349,8 @@ inkeys=freeworlddialup
|
|||||||
;notransfer=yes ; Disable IAX native transfer
|
;notransfer=yes ; Disable IAX native transfer
|
||||||
;jitterbuffer=yes ; Override global setting an enable jitter buffer
|
;jitterbuffer=yes ; Override global setting an enable jitter buffer
|
||||||
; ; for this user
|
; ; for this user
|
||||||
|
;maxauthreq=10 ; Set maximum number of outstanding AUTHREQs waiting for replies. Any further authentication attempts will be blocked
|
||||||
|
; ; if this limit is reached until they expire or a reply is received.
|
||||||
;callerid="Mark Spencer" <(256) 428-6275>
|
;callerid="Mark Spencer" <(256) 428-6275>
|
||||||
;deny=0.0.0.0/0.0.0.0
|
;deny=0.0.0.0/0.0.0.0
|
||||||
;accountcode=markster0101
|
;accountcode=markster0101
|
||||||
|
|||||||
Reference in New Issue
Block a user