aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfile <file@f38db490-d61c-443f-a65b-d21fe96a405b>2006-07-11 19:03:56 +0000
committerfile <file@f38db490-d61c-443f-a65b-d21fe96a405b>2006-07-11 19:03:56 +0000
commite3ad207f586cd641e5c6a83c27c860daa69f8b71 (patch)
tree9fb7368df572f58e20771ab3596ec3b37c076dae
parent3a438083caa79a4c9231cfae0c5254c0dd8380a4 (diff)
And now the trunk version! Add an option for IAX2 users that allows you to set how many outstanding AUTHREQs chan_iax2 will wait for replies on.
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@37380 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--channels/chan_iax2.c84
-rw-r--r--configs/iax.conf.sample2
2 files changed, 79 insertions, 7 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 97f87d51b..7dfbd444f 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -248,7 +248,7 @@ enum {
IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */
IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */
IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */
- /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
+ /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */
IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */
IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */
@@ -263,7 +263,8 @@ enum {
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_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */
- IAX_TRANSFERMEDIA = (1 << 23) /*!< When doing IAX2 transfers, transfer media only */
+ IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */
+ IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */
} iax2_flags;
static int global_rtautoclear = 120;
@@ -284,6 +285,8 @@ struct iax2_user {
int amaflags;
unsigned int flags;
int capability;
+ int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
+ int curauthreq; /*!< Current number of outstanding AUTHREQs */
char cid_num[AST_MAX_EXTENSION];
char cid_name[AST_MAX_EXTENSION];
struct ast_codec_pref prefs;
@@ -1616,6 +1619,20 @@ static int send_packet(struct iax_frame *f)
static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
{
+ struct iax2_user *user = NULL;
+
+ /* Decrement AUTHREQ count if needed */
+ if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
+ AST_LIST_LOCK(&users);
+ AST_LIST_TRAVERSE(&users, user, entry) {
+ if (!strcmp(user->name, pvt->username)) {
+ user->curauthreq--;
+ break;
+ }
+ }
+ AST_LIST_UNLOCK(&users);
+ ast_clear_flag(pvt, IAX_MAXAUTHREQ);
+ }
/* No more pings or lagrq's */
if (pvt->pingid > -1)
ast_sched_del(sched, pvt->pingid);
@@ -4524,7 +4541,7 @@ static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies
int version = 2;
struct iax2_user *user = NULL, *best = NULL;
int bestscore = 0;
- int gotcapability=0;
+ int gotcapability = 0;
char iabuf[INET_ADDRSTRLEN];
struct ast_variable *v = NULL, *tmpvar = NULL;
@@ -4643,6 +4660,9 @@ static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies
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;
ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
@@ -4745,9 +4765,35 @@ static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
static int authenticate_request(struct chan_iax2_pvt *p)
{
+ struct iax2_user *user = NULL;
struct iax_ie_data ied;
- int res;
+ int res = -1, authreq_restrict = 0;
+
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_LIST_LOCK(&users);
+ AST_LIST_TRAVERSE(&users, user, entry) {
+ if (!strcmp(user->name, p->username)) {
+ if (user->curauthreq == user->maxauthreq)
+ authreq_restrict = 1;
+ else
+ user->curauthreq++;
+ break;
+ }
+ }
+ AST_LIST_UNLOCK(&users);
+ }
+
+ /* 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);
if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random());
@@ -4755,10 +4801,14 @@ static int authenticate_request(struct chan_iax2_pvt *p)
}
if (p->encmethods)
iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
+
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);
+
if (p->encmethods)
ast_set_flag(p, IAX_ENCRYPTED);
+
return res;
}
@@ -4770,7 +4820,20 @@ static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
char rsasecret[256] = "";
int res = -1;
int x;
-
+ struct iax2_user *user = NULL;
+
+ if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
+ AST_LIST_LOCK(&users);
+ AST_LIST_TRAVERSE(&users, user, entry) {
+ if (!strcmp(user->name, p->username)) {
+ user->curauthreq--;
+ break;
+ }
+ }
+ AST_LIST_UNLOCK(&users);
+ ast_clear_flag(p, IAX_MAXAUTHREQ);
+ }
+
if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
return res;
if (ies->password)
@@ -6808,8 +6871,8 @@ retryowner:
merge_encryption(iaxs[fr->callno],ies.encmethods);
else
iaxs[fr->callno]->encmethods = 0;
- authenticate_request(iaxs[fr->callno]);
- ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
+ if (!authenticate_request(iaxs[fr->callno]))
+ ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
break;
case IAX_COMMAND_DPREQ:
/* Request status in the dialplan */
@@ -8320,6 +8383,7 @@ static struct iax2_user *build_user(const char *name, struct ast_variable *v, in
struct ast_ha *oldha = NULL;
struct iax2_context *oldcon = NULL;
int format;
+ int oldcurauthreq = 0;
char *varname = NULL, *varval = NULL;
struct ast_variable *tmpvar = NULL;
@@ -8334,6 +8398,7 @@ static struct iax2_user *build_user(const char *name, struct ast_variable *v, in
user = NULL;
if (user) {
+ oldcurauthreq = user->curauthreq;
oldha = user->ha;
oldcon = user->contexts;
user->ha = NULL;
@@ -8349,6 +8414,7 @@ static struct iax2_user *build_user(const char *name, struct ast_variable *v, in
if (user) {
memset(user, 0, sizeof(struct iax2_user));
+ user->curauthreq = oldcurauthreq;
user->prefs = prefs;
user->capability = iax2_capability;
user->encmethods = iax2_encryption;
@@ -8440,6 +8506,10 @@ static struct iax2_user *build_user(const char *name, struct ast_variable *v, in
}
} else if (!strcasecmp(v->name, "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")) */
/* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
v = v->next;
diff --git a/configs/iax.conf.sample b/configs/iax.conf.sample
index 0d2f27093..96c604b64 100644
--- a/configs/iax.conf.sample
+++ b/configs/iax.conf.sample
@@ -314,6 +314,8 @@ inkeys=freeworlddialup
; only media stream
;jitterbuffer=yes ; Override global setting an enable jitter buffer
; ; 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>
;deny=0.0.0.0/0.0.0.0
;accountcode=markster0101