|
version 1.1.1.3, 2016/11/01 09:56:12
|
version 1.1.1.4.2.1, 2023/09/27 11:08:00
|
|
Line 43
|
Line 43
|
| |
|
| static void AuthTimeout(void *arg); |
static void AuthTimeout(void *arg); |
| static int |
static int |
| AuthGetExternalPassword(char *extcmd, char *authname, | AuthGetExternalPassword(const char *extcmd, char *authname, |
| char *password, size_t passlen); |
char *password, size_t passlen); |
| static void AuthAsync(void *arg); |
static void AuthAsync(void *arg); |
| static void AuthAsyncFinish(void *arg, int was_canceled); |
static void AuthAsyncFinish(void *arg, int was_canceled); |
|
Line 72 static void AuthOpie(AuthData auth);
|
Line 72 static void AuthOpie(AuthData auth);
|
| |
|
| #endif |
#endif |
| static const char *AuthCode(int proto, u_char code, char *buf, size_t len); |
static const char *AuthCode(int proto, u_char code, char *buf, size_t len); |
| static int AuthSetCommand(Context ctx, int ac, char *av[], void *arg); | static int AuthSetCommand(Context ctx, int ac, const char *const av[], const void *arg); |
| |
|
| /* Set menu options */ |
/* Set menu options */ |
| enum { |
enum { |
|
Line 128 const struct cmdtab AuthSetCmds[] = {
|
Line 128 const struct cmdtab AuthSetCmds[] = {
|
| AuthSetCommand, NULL, 2, (void *)SET_YES}, |
AuthSetCommand, NULL, 2, (void *)SET_YES}, |
| {"no [opt ...]", "Disable and deny option", |
{"no [opt ...]", "Disable and deny option", |
| AuthSetCommand, NULL, 2, (void *)SET_NO}, |
AuthSetCommand, NULL, 2, (void *)SET_NO}, |
| {NULL}, | {NULL, NULL, NULL, NULL, 0, NULL}, |
| }; |
}; |
| |
|
| const u_char gMsoftZeros[32]; |
const u_char gMsoftZeros[32]; |
| int gMaxLogins = 0; /* max number of concurrent logins per | static unsigned gMaxLogins = 0; /* max number of concurrent logins per |
| * user */ |
* user */ |
| int gMaxLoginsCI = 0; | static unsigned gMaxLoginsCI = 0; |
| |
|
| /* |
/* |
| * INTERNAL VARIABLES |
* INTERNAL VARIABLES |
| */ |
*/ |
| |
|
| static struct confinfo gConfList[] = { | static const struct confinfo gConfList[] = { |
| {0, AUTH_CONF_RADIUS_AUTH, "radius-auth"}, |
{0, AUTH_CONF_RADIUS_AUTH, "radius-auth"}, |
| {0, AUTH_CONF_RADIUS_ACCT, "radius-acct"}, |
{0, AUTH_CONF_RADIUS_ACCT, "radius-acct"}, |
| {0, AUTH_CONF_INTERNAL, "internal"}, |
{0, AUTH_CONF_INTERNAL, "internal"}, |
|
Line 188 void
|
Line 188 void
|
| authparamsInit(struct authparams *ap) |
authparamsInit(struct authparams *ap) |
| { |
{ |
| memset(ap, 0, sizeof(struct authparams)); |
memset(ap, 0, sizeof(struct authparams)); |
| |
#ifdef USE_RADIUS |
| ap->eapmsg = NULL; |
ap->eapmsg = NULL; |
| ap->state = NULL; |
ap->state = NULL; |
| ap->class = NULL; |
ap->class = NULL; |
| ap->filter_id = NULL; |
ap->filter_id = NULL; |
| |
#endif |
| ap->msdomain = NULL; |
ap->msdomain = NULL; |
| #ifdef SIOCSIFDESCR |
#ifdef SIOCSIFDESCR |
| ap->ifdescr = NULL; |
ap->ifdescr = NULL; |
|
Line 208 authparamsDestroy(struct authparams *ap)
|
Line 210 authparamsDestroy(struct authparams *ap)
|
| int i; |
int i; |
| #endif |
#endif |
| |
|
| |
#ifdef USE_RADIUS |
| Freee(ap->eapmsg); |
Freee(ap->eapmsg); |
| Freee(ap->state); |
Freee(ap->state); |
| Freee(ap->class); |
Freee(ap->class); |
| Freee(ap->filter_id); |
Freee(ap->filter_id); |
| |
#endif |
| |
|
| #ifdef USE_IPFW |
#ifdef USE_IPFW |
| ACLDestroy(ap->acl_rule); |
ACLDestroy(ap->acl_rule); |
|
Line 252 authparamsCopy(struct authparams *src, struct authpara
|
Line 256 authparamsCopy(struct authparams *src, struct authpara
|
| |
|
| memcpy(dst, src, sizeof(struct authparams)); |
memcpy(dst, src, sizeof(struct authparams)); |
| |
|
| |
#ifdef USE_RADIUS |
| if (src->eapmsg) |
if (src->eapmsg) |
| dst->eapmsg = Mdup(MB_AUTH, src->eapmsg, src->eapmsg_len); |
dst->eapmsg = Mdup(MB_AUTH, src->eapmsg, src->eapmsg_len); |
| if (src->state) |
if (src->state) |
|
Line 260 authparamsCopy(struct authparams *src, struct authpara
|
Line 265 authparamsCopy(struct authparams *src, struct authpara
|
| dst->class = Mdup(MB_AUTH, src->class, src->class_len); |
dst->class = Mdup(MB_AUTH, src->class, src->class_len); |
| if (src->filter_id) |
if (src->filter_id) |
| dst->filter_id = Mstrdup(MB_AUTH, src->filter_id); |
dst->filter_id = Mstrdup(MB_AUTH, src->filter_id); |
| |
#endif |
| |
|
| #ifdef USE_IPFW |
#ifdef USE_IPFW |
| ACLCopy(src->acl_rule, &dst->acl_rule); |
ACLCopy(src->acl_rule, &dst->acl_rule); |
|
Line 308 AuthInit(Link l)
|
Line 314 AuthInit(Link l)
|
| Enable(&ac->options, AUTH_CONF_INTERNAL); |
Enable(&ac->options, AUTH_CONF_INTERNAL); |
| Enable(&ac->options, AUTH_CONF_ACCT_MANDATORY); |
Enable(&ac->options, AUTH_CONF_ACCT_MANDATORY); |
| |
|
| |
#ifdef USE_RADIUS |
| EapInit(l); |
EapInit(l); |
| RadiusInit(l); |
RadiusInit(l); |
| |
#endif |
| } |
} |
| |
|
| /* |
/* |
|
Line 420 AuthStart(Link l)
|
Line 428 AuthStart(Link l)
|
| case PROTO_CHAP: |
case PROTO_CHAP: |
| ChapStart(l, AUTH_SELF_TO_PEER); |
ChapStart(l, AUTH_SELF_TO_PEER); |
| break; |
break; |
| |
#ifdef USE_RADIUS |
| case PROTO_EAP: |
case PROTO_EAP: |
| EapStart(l, AUTH_SELF_TO_PEER); |
EapStart(l, AUTH_SELF_TO_PEER); |
| break; |
break; |
| |
#endif |
| default: |
default: |
| assert(0); |
assert(0); |
| } |
} |
|
Line 437 AuthStart(Link l)
|
Line 447 AuthStart(Link l)
|
| case PROTO_CHAP: |
case PROTO_CHAP: |
| ChapStart(l, AUTH_PEER_TO_SELF); |
ChapStart(l, AUTH_PEER_TO_SELF); |
| break; |
break; |
| |
#ifdef USE_RADIUS |
| case PROTO_EAP: |
case PROTO_EAP: |
| EapStart(l, AUTH_PEER_TO_SELF); |
EapStart(l, AUTH_PEER_TO_SELF); |
| break; |
break; |
| |
#endif |
| default: |
default: |
| assert(0); |
assert(0); |
| } |
} |
|
Line 449 AuthStart(Link l)
|
Line 461 AuthStart(Link l)
|
| * AuthInput() |
* AuthInput() |
| * |
* |
| * Deal with PAP/CHAP/EAP packet |
* Deal with PAP/CHAP/EAP packet |
| |
* But cannot be called for EAP packet if RADIUS support is not compiled in. |
| */ |
*/ |
| |
|
| void |
void |
| AuthInput(Link l, int proto, Mbuf bp) |
AuthInput(Link l, int proto, Mbuf bp) |
| { |
{ |
| AuthData auth; |
AuthData auth; |
| int len; |
|
| struct fsmheader fsmh; |
struct fsmheader fsmh; |
| u_char *pkt; |
u_char *pkt; |
| char buf[16]; |
char buf[16]; |
| |
u_short len; |
| |
uint16_t fsmh_len; |
| |
|
| /* Sanity check */ |
/* Sanity check */ |
| if (l->lcp.phase != PHASE_AUTHENTICATE && l->lcp.phase != PHASE_NETWORK) { |
if (l->lcp.phase != PHASE_AUTHENTICATE && l->lcp.phase != PHASE_NETWORK) { |
|
Line 470 AuthInput(Link l, int proto, Mbuf bp)
|
Line 484 AuthInput(Link l, int proto, Mbuf bp)
|
| |
|
| /* Sanity check length */ |
/* Sanity check length */ |
| if (len < sizeof(fsmh)) { |
if (len < sizeof(fsmh)) { |
| Log(LG_ERR | LG_AUTH, ("[%s] AUTH: rec'd runt packet: %d bytes", | Log(LG_ERR | LG_AUTH, ("[%s] AUTH: rec'd runt packet: %hu bytes", |
| l->name, len)); |
l->name, len)); |
| mbfree(bp); |
mbfree(bp); |
| return; |
return; |
| } |
} |
| auth = AuthDataNew(l); |
|
| auth->proto = proto; |
|
| |
|
| bp = mbread(bp, &fsmh, sizeof(fsmh)); |
bp = mbread(bp, &fsmh, sizeof(fsmh)); |
| if (len > ntohs(fsmh.length)) |
|
| len = ntohs(fsmh.length); |
|
| len -= sizeof(fsmh); |
|
| |
|
| |
fsmh_len = ntohs(fsmh.length); |
| |
if (len > fsmh_len) { |
| |
/* Sanity check length */ |
| |
if (fsmh_len < sizeof(fsmh)) { |
| |
Log(LG_ERR | LG_AUTH, ("[%s] AUTH: bad length: says %hu, rec'd %hu", |
| |
l->name, fsmh_len, len)); |
| |
mbfree(bp); |
| |
return; |
| |
} |
| |
len = fsmh_len; |
| |
} |
| |
|
| |
len -= sizeof(fsmh); |
| pkt = MBDATA(bp); |
pkt = MBDATA(bp); |
| |
|
| |
#ifdef USE_RADIUS |
| if (proto == PROTO_EAP && bp) { |
if (proto == PROTO_EAP && bp) { |
| Log(LG_AUTH, ("[%s] %s: rec'd %s #%d len: %d, type: %s", l->name, | Log(LG_AUTH, ("[%s] %s: rec'd %s #%d len: %hu, type: %s", l->name, |
| ProtoName(proto), AuthCode(proto, fsmh.code, buf, sizeof(buf)), fsmh.id, |
ProtoName(proto), AuthCode(proto, fsmh.code, buf, sizeof(buf)), fsmh.id, |
| ntohs(fsmh.length), EapType(pkt[0]))); | fsmh_len, EapType(pkt[0]))); |
| } else { | } else |
| Log(LG_AUTH, ("[%s] %s: rec'd %s #%d len: %d", l->name, | #endif |
| | Log(LG_AUTH, ("[%s] %s: rec'd %s #%d len: %hu", l->name, |
| ProtoName(proto), AuthCode(proto, fsmh.code, buf, sizeof(buf)), fsmh.id, |
ProtoName(proto), AuthCode(proto, fsmh.code, buf, sizeof(buf)), fsmh.id, |
| ntohs(fsmh.length))); | fsmh_len)); |
| } | |
| |
|
| |
auth = AuthDataNew(l); |
| |
auth->proto = proto; |
| auth->id = fsmh.id; |
auth->id = fsmh.id; |
| auth->code = fsmh.code; |
auth->code = fsmh.code; |
| /* Status defaults to undefined */ |
/* Status defaults to undefined */ |
|
Line 507 AuthInput(Link l, int proto, Mbuf bp)
|
Line 532 AuthInput(Link l, int proto, Mbuf bp)
|
| case PROTO_CHAP: |
case PROTO_CHAP: |
| ChapInput(l, auth, pkt, len); |
ChapInput(l, auth, pkt, len); |
| break; |
break; |
| |
#ifdef USE_RADIUS |
| case PROTO_EAP: |
case PROTO_EAP: |
| EapInput(l, auth, pkt, len); |
EapInput(l, auth, pkt, len); |
| break; |
break; |
| |
#endif |
| default: |
default: |
| assert(0); |
assert(0); |
| } |
} |
|
Line 552 AuthOutput(Link l, int proto, u_int code, u_int id, co
|
Line 579 AuthOutput(Link l, int proto, u_int code, u_int id, co
|
| } |
} |
| bp = mbcopyback(bp, MBLEN(bp), ptr, len); |
bp = mbcopyback(bp, MBLEN(bp), ptr, len); |
| |
|
| |
#ifdef USE_RADIUS |
| if (proto == PROTO_EAP) { |
if (proto == PROTO_EAP) { |
| Log(LG_AUTH, ("[%s] %s: sending %s #%d len: %d, type: %s", l->name, |
Log(LG_AUTH, ("[%s] %s: sending %s #%d len: %d, type: %s", l->name, |
| ProtoName(proto), AuthCode(proto, code, buf, sizeof(buf)), id, plen, EapType(eap_type))); |
ProtoName(proto), AuthCode(proto, code, buf, sizeof(buf)), id, plen, EapType(eap_type))); |
| } else { | } else |
| | #endif |
| Log(LG_AUTH, ("[%s] %s: sending %s #%d len: %d", l->name, |
Log(LG_AUTH, ("[%s] %s: sending %s #%d len: %d", l->name, |
| ProtoName(proto), AuthCode(proto, code, buf, sizeof(buf)), id, plen)); |
ProtoName(proto), AuthCode(proto, code, buf, sizeof(buf)), id, plen)); |
| } |
|
| |
|
| /* Send it out */ |
/* Send it out */ |
| NgFuncWritePppFrameLink(l, proto, bp); |
NgFuncWritePppFrameLink(l, proto, bp); |
|
Line 707 AuthStop(Link l)
|
Line 735 AuthStop(Link l)
|
| TimerStop(&a->timer); |
TimerStop(&a->timer); |
| PapStop(&a->pap); |
PapStop(&a->pap); |
| ChapStop(&a->chap); |
ChapStop(&a->chap); |
| |
#ifdef USE_RADIUS |
| EapStop(&a->eap); |
EapStop(&a->eap); |
| |
#endif |
| paction_cancel(&a->thread); |
paction_cancel(&a->thread); |
| } |
} |
| |
|
|
Line 718 AuthStop(Link l)
|
Line 748 AuthStop(Link l)
|
| */ |
*/ |
| |
|
| int |
int |
| AuthStat(Context ctx, int ac, char *av[], void *arg) | AuthStat(Context ctx, int ac, const char *const av[], const void *arg) |
| { |
{ |
| Auth const au = &ctx->lnk->lcp.auth; |
Auth const au = &ctx->lnk->lcp.auth; |
| AuthConf const conf = &au->conf; |
AuthConf const conf = &au->conf; |
|
Line 735 AuthStat(Context ctx, int ac, char *av[], void *arg)
|
Line 765 AuthStat(Context ctx, int ac, char *av[], void *arg)
|
| |
|
| #endif |
#endif |
| |
|
| |
(void)ac; |
| |
(void)av; |
| |
(void)arg; |
| |
|
| Printf("Configuration:\r\n"); |
Printf("Configuration:\r\n"); |
| Printf("\tMy authname : %s\r\n", conf->authname); |
Printf("\tMy authname : %s\r\n", conf->authname); |
| Printf("\tMax-Logins : %d%s\r\n", gMaxLogins, (gMaxLoginsCI ? " CI" : "")); | Printf("\tMax-Logins : %u%s\r\n", gMaxLogins, (gMaxLoginsCI ? " CI" : "")); |
| Printf("\tAcct Update : %d\r\n", conf->acct_update); |
Printf("\tAcct Update : %d\r\n", conf->acct_update); |
| Printf("\t Limit In : %d\r\n", conf->acct_update_lim_recv); |
Printf("\t Limit In : %d\r\n", conf->acct_update_lim_recv); |
| Printf("\t Limit Out : %d\r\n", conf->acct_update_lim_xmit); |
Printf("\t Limit Out : %d\r\n", conf->acct_update_lim_xmit); |
|
Line 964 AuthAccount(void *arg)
|
Line 998 AuthAccount(void *arg)
|
| |
|
| Log(LG_AUTH2, ("[%s] ACCT: Thread started", auth->info.lnkname)); |
Log(LG_AUTH2, ("[%s] ACCT: Thread started", auth->info.lnkname)); |
| |
|
| |
#ifdef USE_RADIUS |
| if (Enabled(&auth->conf.options, AUTH_CONF_RADIUS_ACCT)) |
if (Enabled(&auth->conf.options, AUTH_CONF_RADIUS_ACCT)) |
| err |= RadiusAccount(auth); |
err |= RadiusAccount(auth); |
| |
#endif |
| #ifdef USE_PAM |
#ifdef USE_PAM |
| if (Enabled(&auth->conf.options, AUTH_CONF_PAM_ACCT)) |
if (Enabled(&auth->conf.options, AUTH_CONF_PAM_ACCT)) |
| err |= AuthPAMAcct(auth); |
err |= AuthPAMAcct(auth); |
|
Line 1005 AuthAccountFinish(void *arg, int was_canceled)
|
Line 1041 AuthAccountFinish(void *arg, int was_canceled)
|
| auth->info.lnkname)); |
auth->info.lnkname)); |
| } |
} |
| |
|
| |
#ifdef USE_RADIUS |
| /* Cleanup */ |
/* Cleanup */ |
| RadiusClose(auth); |
RadiusClose(auth); |
| |
#endif |
| |
|
| if (was_canceled) { |
if (was_canceled) { |
| AuthDataDestroy(auth); |
AuthDataDestroy(auth); |
|
Line 1173 AuthAsync(void *arg)
|
Line 1211 AuthAsync(void *arg)
|
| return; |
return; |
| } |
} |
| } |
} |
| |
#ifdef USE_RADIUS |
| if (auth->proto == PROTO_EAP && auth->eap_radius) { |
if (auth->proto == PROTO_EAP && auth->eap_radius) { |
| auth->params.authentic = AUTH_CONF_RADIUS_AUTH; |
auth->params.authentic = AUTH_CONF_RADIUS_AUTH; |
| RadiusEapProxy(auth); |
RadiusEapProxy(auth); |
|
Line 1190 AuthAsync(void *arg)
|
Line 1229 AuthAsync(void *arg)
|
| return; |
return; |
| } |
} |
| } |
} |
| |
#endif |
| #ifdef USE_PAM |
#ifdef USE_PAM |
| if (Enabled(&auth->conf.options, AUTH_CONF_PAM_AUTH)) { |
if (Enabled(&auth->conf.options, AUTH_CONF_PAM_AUTH)) { |
| auth->params.authentic = AUTH_CONF_PAM_AUTH; |
auth->params.authentic = AUTH_CONF_PAM_AUTH; |
|
Line 1259 AuthAsyncFinish(void *arg, int was_canceled)
|
Line 1299 AuthAsyncFinish(void *arg, int was_canceled)
|
| if (was_canceled) |
if (was_canceled) |
| Log(LG_AUTH2, ("[%s] AUTH: Thread was canceled", auth->info.lnkname)); |
Log(LG_AUTH2, ("[%s] AUTH: Thread was canceled", auth->info.lnkname)); |
| |
|
| |
#ifdef USE_RADIUS |
| /* cleanup */ |
/* cleanup */ |
| RadiusClose(auth); |
RadiusClose(auth); |
| |
#endif |
| |
|
| if (was_canceled) { |
if (was_canceled) { |
| AuthDataDestroy(auth); |
AuthDataDestroy(auth); |
|
Line 1868 const char *
|
Line 1910 const char *
|
| AuthMPPETypesname(int types, char *buf, size_t len) |
AuthMPPETypesname(int types, char *buf, size_t len) |
| { |
{ |
| if (types == 0) { |
if (types == 0) { |
| sprintf(buf, "no encryption required"); | strlcpy(buf, "no encryption required", len); |
| return (buf); |
return (buf); |
| } |
} |
| buf[0] = 0; |
buf[0] = 0; |
| if (types & MPPE_TYPE_40BIT) |
if (types & MPPE_TYPE_40BIT) |
| sprintf(buf, "40 "); | strlcpy(buf, "40 ", len); |
| if (types & MPPE_TYPE_56BIT) |
if (types & MPPE_TYPE_56BIT) |
| sprintf(&buf[strlen(buf)], "56 "); | strlcat(buf, "56 ", len); |
| if (types & MPPE_TYPE_128BIT) |
if (types & MPPE_TYPE_128BIT) |
| sprintf(&buf[strlen(buf)], "128 "); | strlcat(buf, "128 ", len); |
| |
|
| if (strlen(buf) == 0) { |
if (strlen(buf) == 0) { |
| sprintf(buf, "unknown types"); | strlcpy(buf, "unknown types", len); |
| } else { |
} else { |
| sprintf(&buf[strlen(buf)], "bit"); | strlcat(buf, "bit", len); |
| } |
} |
| |
|
| return (buf); |
return (buf); |
|
Line 1896 AuthMPPETypesname(int types, char *buf, size_t len)
|
Line 1938 AuthMPPETypesname(int types, char *buf, size_t len)
|
| * -1 on error (can't fork, no data read, whatever) |
* -1 on error (can't fork, no data read, whatever) |
| */ |
*/ |
| static int |
static int |
| AuthGetExternalPassword(char *extcmd, char *authname, char *password, size_t passlen) | AuthGetExternalPassword(const char *extcmd, char *authname, char *password, size_t passlen) |
| { |
{ |
| char cmd[AUTH_MAX_PASSWORD + 5 + AUTH_MAX_AUTHNAME]; |
char cmd[AUTH_MAX_PASSWORD + 5 + AUTH_MAX_AUTHNAME]; |
| int ok = 0; |
int ok = 0; |
|
Line 1933 static const char *
|
Line 1975 static const char *
|
| AuthCode(int proto, u_char code, char *buf, size_t len) |
AuthCode(int proto, u_char code, char *buf, size_t len) |
| { |
{ |
| switch (proto) { |
switch (proto) { |
| |
#ifdef USE_RADIUS |
| case PROTO_EAP: |
case PROTO_EAP: |
| return EapCode(code, buf, len); |
return EapCode(code, buf, len); |
| |
|
| |
#endif |
| case PROTO_CHAP: |
case PROTO_CHAP: |
| return ChapCode(code, buf, len); |
return ChapCode(code, buf, len); |
| |
|
|
Line 1954 AuthCode(int proto, u_char code, char *buf, size_t len
|
Line 1998 AuthCode(int proto, u_char code, char *buf, size_t len
|
| */ |
*/ |
| |
|
| static int |
static int |
| AuthSetCommand(Context ctx, int ac, char *av[], void *arg) | AuthSetCommand(Context ctx, int ac, const char *const av[], const void *arg) |
| { |
{ |
| AuthConf const autc = &ctx->lnk->lcp.auth.conf; |
AuthConf const autc = &ctx->lnk->lcp.auth.conf; |
| int val; |
int val; |
|
Line 1983 AuthSetCommand(Context ctx, int ac, char *av[], void *
|
Line 2027 AuthSetCommand(Context ctx, int ac, char *av[], void *
|
| break; |
break; |
| |
|
| case SET_MAX_LOGINS: |
case SET_MAX_LOGINS: |
| gMaxLogins = atoi(av[0]); | gMaxLogins = (unsigned)atoi(av[0]); |
| if (ac >= 2 && strcasecmp(av[1], "ci") == 0) { |
if (ac >= 2 && strcasecmp(av[1], "ci") == 0) { |
| gMaxLoginsCI = 1; |
gMaxLoginsCI = 1; |
| } else { |
} else { |