diff options
author | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-06-26 14:19:38 +0000 |
---|---|---|
committer | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2004-06-26 14:19:38 +0000 |
commit | a4b291c15f3a27d60396d2c225db88c850a31cd6 (patch) | |
tree | f6781c770c15ad0c291ff2b32e4cc4eed30e7967 | |
parent | 1e7a60f1b8fde718309b43f8aadfeeca74302dd3 (diff) |
Minor alsa fixes, add "delayreject" option to IAX to implement request of bug #1846)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@3313 f38db490-d61c-443f-a65b-d21fe96a405b
-rwxr-xr-x | channels/chan_alsa.c | 1 | ||||
-rwxr-xr-x | channels/chan_iax2.c | 80 | ||||
-rwxr-xr-x | configs/iax.conf.sample | 6 |
3 files changed, 76 insertions, 11 deletions
diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c index 3a3054e2d..b8ae8b94c 100755 --- a/channels/chan_alsa.c +++ b/channels/chan_alsa.c @@ -634,7 +634,6 @@ static struct ast_frame *alsa_read(struct ast_channel *chan) snd_pcm_prepare(alsa.icard); } else if (r < 0) { ast_log(LOG_ERROR, "Read error: %s\n", snd_strerror(r)); - return NULL; } else if (r >= 0) { off -= r; } diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index cb48f0144..54ae3ff67 100755 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -177,6 +177,7 @@ static int iaxtrunkdebug = 0; static char accountcode[20]; static int amaflags = 0; static int globalnotransfer = 0; +static int delayreject = 0; static pthread_t netthreadid = AST_PTHREADT_NULL; @@ -447,6 +448,8 @@ struct chan_iax2_pvt { int pingid; /* Transmit PING request */ int lagid; /* Retransmit lag request */ int autoid; /* Auto hangup for Dialplan requestor */ + int authid; /* Authentication rejection ID */ + int authfail; /* Reason to report failure */ int initid; /* Initial peer auto-congest ID (based on qualified peers) */ char dproot[AST_MAX_EXTENSION]; char accountcode[20]; @@ -631,6 +634,7 @@ static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, int lockpeer) tmp->pingid = -1; tmp->lagid = -1; tmp->autoid = -1; + tmp->authid = -1; tmp->initid = -1; /* strncpy(tmp->context, context, sizeof(tmp->context)-1); */ strncpy(tmp->exten, "s", sizeof(tmp->exten)-1); @@ -1236,12 +1240,15 @@ static int iax2_predestroy(int callno) ast_sched_del(sched, pvt->lagid); if (pvt->autoid > -1) ast_sched_del(sched, pvt->autoid); + if (pvt->authid > -1) + ast_sched_del(sched, pvt->authid); if (pvt->initid > -1) ast_sched_del(sched, pvt->initid); pvt->pingid = -1; pvt->lagid = -1; pvt->autoid = -1; pvt->initid = -1; + pvt->authid = -1; pvt->alreadygone = 1; } c = pvt->owner; @@ -1305,11 +1312,14 @@ retry: ast_sched_del(sched, pvt->lagid); if (pvt->autoid > -1) ast_sched_del(sched, pvt->autoid); + if (pvt->authid > -1) + ast_sched_del(sched, pvt->authid); if (pvt->initid > -1) ast_sched_del(sched, pvt->initid); pvt->pingid = -1; pvt->lagid = -1; pvt->autoid = -1; + pvt->authid = -1; pvt->initid = -1; if (pvt->bridgetrans) ast_translator_free_path(pvt->bridgetrans); @@ -4268,9 +4278,50 @@ static int stop_stuff(int callno) if (iaxs[callno]->initid > -1) ast_sched_del(sched, iaxs[callno]->initid); iaxs[callno]->initid = -1; + if (iaxs[callno]->authid > -1) + ast_sched_del(sched, iaxs[callno]->authid); + iaxs[callno]->authid = -1; return 0; } +static int auth_reject(void *nothing) +{ + /* Called from IAX thread only, without iaxs lock */ + int callno = (int)(long)(nothing); + struct iax_ie_data ied; + ast_mutex_lock(&iaxsl[callno]); + if (iaxs[callno]) { + iaxs[callno]->authid = -1; + memset(&ied, 0, sizeof(ied)); + if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { + iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); + } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { + iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); + } + send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); + } + ast_mutex_unlock(&iaxsl[callno]); + return 0; +} + +static int auth_fail(int callno, int failcode) +{ + /* Schedule sending the authentication failure in one second, to prevent + guessing */ + ast_mutex_lock(&iaxsl[callno]); + iaxs[callno]->authfail = failcode; + if (delayreject) { + ast_mutex_lock(&iaxsl[callno]); + if (iaxs[callno]->authid > -1) + ast_sched_del(sched, iaxs[callno]->authid); + iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno); + ast_mutex_unlock(&iaxsl[callno]); + } else + auth_reject((void *)(long)callno); + ast_mutex_unlock(&iaxsl[callno]); + return 0; +} + static int auto_hangup(void *nothing) { /* Called from IAX thread only, without iaxs lock */ @@ -5008,12 +5059,14 @@ retryowner: /* Ignore if it's already up */ if (iaxs[fr.callno]->state & (IAX_STATE_STARTED | IAX_STATE_TBD)) break; + /* For security, always ack immediately */ + if (delayreject) + send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); if (check_access(fr.callno, &sin, &ies)) { /* They're not allowed on */ - memset(&ied0, 0, sizeof(ied0)); - iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); - send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); - ast_log(LOG_NOTICE, "Rejected connect attempt from %s\n", inet_ntoa(sin.sin_addr)); + auth_fail(fr.callno, IAX_COMMAND_REJECT); + if (authdebug) + ast_log(LOG_NOTICE, "Rejected connect attempt from %s\n", inet_ntoa(sin.sin_addr)); break; } /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ @@ -5110,10 +5163,10 @@ retryowner: if (authdebug) ast_log(LOG_WARNING, "Call rejected by %s: %s\n", inet_ntoa(iaxs[fr.callno]->addr.sin_addr), ies.cause ? ies.cause : "<Unknown>"); } - iaxs[fr.callno]->error = EPERM; ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", fr.callno); /* Send ack immediately, before we destroy */ send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); + iaxs[fr.callno]->error = EPERM; iax2_destroy_nolock(fr.callno); break; case IAX_COMMAND_TRANSFER: @@ -5284,6 +5337,9 @@ retryowner2: } break; case IAX_COMMAND_AUTHREP: + /* For security, always ack immediately */ + if (delayreject) + send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); /* Ignore once we've started */ if (iaxs[fr.callno]->state & (IAX_STATE_STARTED | IAX_STATE_TBD)) { ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr.callno]->owner ? iaxs[fr.callno]->owner->name : "<Unknown>"); @@ -5293,8 +5349,7 @@ retryowner2: if (authdebug) ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", inet_ntoa(iaxs[fr.callno]->addr.sin_addr), iaxs[fr.callno]->username); memset(&ied0, 0, sizeof(ied0)); - iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); - send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); + auth_fail(fr.callno, IAX_COMMAND_REJECT); break; } if (strcasecmp(iaxs[fr.callno]->exten, "TBD")) { @@ -5390,10 +5445,12 @@ retryowner2: break; case IAX_COMMAND_REGREQ: case IAX_COMMAND_REGREL: + /* For security, always ack immediately */ + if (delayreject) + send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.iseqno); if (register_verify(fr.callno, &sin, &ies)) { - memset(&ied0, 0, sizeof(ied0)); - iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Registration Refused"); - send_command_final(iaxs[fr.callno], AST_FRAME_IAX, IAX_COMMAND_REGREJ, 0, ied0.buf, ied0.pos, -1); + /* Send delayed failure */ + auth_fail(fr.callno, IAX_COMMAND_REGREJ); break; } if ((ast_strlen_zero(iaxs[fr.callno]->secret) && ast_strlen_zero(iaxs[fr.callno]->inkeys)) || (iaxs[fr.callno]->state & IAX_STATE_AUTHENTICATED)) { @@ -6294,6 +6351,8 @@ static int set_config(char *config_file, struct sockaddr_in* sin){ authdebug = ast_true(v->value); else if (!strcasecmp(v->name, "notransfer")) globalnotransfer = ast_true(v->value); + else if (!strcasecmp(v->name, "delayreject")) + delayreject = ast_true(v->value); else if (!strcasecmp(v->name, "trunkfreq")) { trunkfreq = atoi(v->value); if (trunkfreq < 10) @@ -6423,6 +6482,7 @@ static int reload_config(void) strncpy(accountcode, "", sizeof(accountcode)-1); strncpy(language, "", sizeof(language)-1); amaflags = 0; + delayreject = 0; globalnotransfer = 0; srand(time(NULL)); delete_users(); diff --git a/configs/iax.conf.sample b/configs/iax.conf.sample index b0bfc9080..8cd590f2a 100755 --- a/configs/iax.conf.sample +++ b/configs/iax.conf.sample @@ -15,6 +15,12 @@ ; ;iaxcompat=yes ; +; For increased security against brute force password attacks +; enable "delayreject" which will delay the sending of authentication +; reject for REGREQ or AUTHREP if there is a password. +; +;delayreject=yes +; ; You may specify a global default AMA flag for iaxtel calls. It must be ; one of 'default', 'omit', 'billing', or 'documentation'. These flags ; are used in the generation of call detail records. |