void PapInputFinish(Link l, AuthData auth) { Auth const a = &l->lcp.auth; PapParams pap = &a->params.pap; const char *Mesg; Log(LG_AUTH, ("[%s] PAP: Auth return status: %s", l->name, AuthStatusText(auth->status))); if (auth->status == AUTH_STATUS_BUSY) { AuthDataDestroy(auth); return; } else if (auth->status == AUTH_STATUS_FAIL) goto badRequest; else if (auth->status == AUTH_STATUS_SUCCESS) goto goodRequest; /* Do name & password match? */ if (strcmp(a->params.authname, pap->peer_name) || strcmp(a->params.password, pap->peer_pass)) { Log(LG_AUTH, ("[%s] PAP: Invalid response", l->name)); auth->why_fail = AUTH_FAIL_INVALID_LOGIN; goto badRequest; } goodRequest: /* Login accepted */ Log(LG_AUTH, ("[%s] PAP: Response is valid", l->name)); if (auth->reply_message) { Mesg = auth->reply_message; } else { Mesg = AUTH_MSG_WELCOME; } Log(LG_AUTH, ("[%s] PAP: Reply message: %s", l->name, Mesg)); AuthOutput(l, PROTO_PAP, PAP_ACK, auth->id, (u_char *)Mesg, strlen(Mesg), 1, 0); AuthFinish(l, AUTH_PEER_TO_SELF, TRUE); AuthDataDestroy(auth); return; badRequest: { char failMesg[64]; Mesg = AuthFailMsg(auth, failMesg, sizeof(failMesg)); Log(LG_AUTH, ("[%s] PAP: Reply message: %s", l->name, Mesg)); AuthOutput(l, PROTO_PAP, PAP_NAK, auth->id, (u_char *)Mesg, strlen(Mesg), 1, 0); AuthFinish(l, AUTH_PEER_TO_SELF, FALSE); AuthDataDestroy(auth); } }
static int msg_pls_auth(char *nick, char *host, struct userrec *u, char *par) { if (strlen(auth_key) && get_user(&USERENTRY_SECPASS, u)) { if (match_my_nick(nick)) return BIND_RET_BREAK; if (u && u->bot) return BIND_RET_BREAK; Auth *auth = Auth::Find(host); if (!auth || auth->Status() != AUTH_HASH) return BIND_RET_BREAK; if (!strcmp(auth->hash, par)) { /* good hash! */ AuthFinish(auth); } else { /* bad hash! */ char s[300] = ""; putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! failed +AUTH"), nick, host, u->handle); notice(nick, STR("Invalid hash."), DP_HELP); simple_snprintf(s, sizeof(s), "*!%s", host); addignore(s, origbotname, STR("Invalid auth hash."), now + (60 * ignore_time)); delete auth; } return BIND_RET_BREAK; } return BIND_RET_LOG; }
static int msg_auth(char *nick, char *host, struct userrec *u, char *par) { char *pass = NULL; if (match_my_nick(nick)) return BIND_RET_BREAK; if (u && u->bot) return BIND_RET_BREAK; Auth *auth = Auth::Find(host); if (!auth || auth->Status() != AUTH_PASS) return BIND_RET_BREAK; pass = newsplit(&par); if (u_pass_match(u, pass) && !u_pass_match(u, "-")) { auth->user = u; if (strlen(auth_key) && get_user(&USERENTRY_SECPASS, u)) { putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! AUTH"), nick, host, u->handle); auth->Status(AUTH_HASH); auth->MakeHash(); bd::String msg; msg = bd::String::printf(STR("-Auth %s %s"), auth->rand, conf.bot->nick); privmsg(nick, msg.c_str(), DP_HELP); } else { /* no auth_key and/or no SECPASS for the user, don't require a hash auth */ AuthFinish(auth); } } else { putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! failed AUTH"), nick, host, u->handle); delete auth; } return BIND_RET_BREAK; }
void PapInput(Link l, AuthData auth, const u_char *pkt, u_short len) { Auth const a = &l->lcp.auth; PapInfo const pap = &a->pap; PapParams const pp = &auth->params.pap; char failMesg[64]; char buf[16]; switch (auth->code) { case PAP_REQUEST: { char *name_ptr, name[256]; char *pass_ptr, pass[256]; int name_len, pass_len; /* Is this appropriate? */ if (a->peer_to_self != PROTO_PAP) { if (l->lcp.want_auth == PROTO_PAP && a->peer_to_self == 0) { Log(LG_AUTH, ("[%s] PAP: retransmitting ACK", l->name)); AuthOutput(l, PROTO_PAP, PAP_ACK, auth->id, (u_char *)AUTH_MSG_WELCOME, strlen(AUTH_MSG_WELCOME), 1, 0); break; } Log(LG_AUTH, ("[%s] PAP: %s not expected", l->name, PapCode(auth->code, buf, sizeof(buf)))); auth->why_fail = AUTH_FAIL_NOT_EXPECTED; PapInputFinish(l, auth); return; } /* Sanity check packet and extract fields */ if (len < 1) goto error; name_len = pkt[0]; name_ptr = (char *)pkt + 1; if (1 + name_len >= len) goto error; pass_len = pkt[1 + name_len]; pass_ptr = (char *)pkt + 1 + name_len + 1; if (name_len + 1 + pass_len + 1 > len) goto error; memcpy(name, name_ptr, name_len); name[name_len] = 0; memcpy(pass, pass_ptr, pass_len); pass[pass_len] = 0; strlcpy(pp->peer_name, name, sizeof(pp->peer_name)); strlcpy(pp->peer_pass, pass, sizeof(pp->peer_pass)); strlcpy(auth->params.authname, name, sizeof(auth->params.authname)); auth->params.password[0] = 0; auth->finish = PapInputFinish; AuthAsyncStart(l, auth); return; } break; case PAP_ACK: case PAP_NAK: { /* Is this appropriate? */ if (a->self_to_peer != PROTO_PAP) { Log(LG_AUTH, ("[%s] PAP: %s not expected", l->name, PapCode(auth->code, buf, sizeof(buf)))); break; } /* Stop resend timer */ TimerStop(&pap->timer); /* Show reply message */ if (len > 0) { int msg_len = pkt[0]; char *msg = (char *)&pkt[1]; if (msg_len < len - 1) msg_len = len - 1; ShowMesg(LG_AUTH, l->name, msg, msg_len); } /* Done with my auth to peer */ AuthFinish(l, AUTH_SELF_TO_PEER, auth->code == PAP_ACK); } break; default: Log(LG_AUTH, ("[%s] PAP: unknown code", l->name)); break; } AuthDataDestroy(auth); return; error: Log(LG_AUTH, ("[%s] PAP: Bad PAP packet", l->name)); auth->why_fail = AUTH_FAIL_INVALID_PACKET; AuthFailMsg(auth, failMesg, sizeof(failMesg)); AuthOutput(l, PROTO_PAP, PAP_NAK, auth->id, (u_char *)failMesg, strlen(failMesg), 1, 0); AuthFinish(l, AUTH_PEER_TO_SELF, FALSE); AuthDataDestroy(auth); }