X-Git-Url: https://jfr.im/git/solanum.git/blobdiff_plain/105a4985b402b3ab294e3bec1fa75bac75430482..f8838806ef332738fd17e725c9e7d5b1418a9756:/modules/m_challenge.c diff --git a/modules/m_challenge.c b/modules/m_challenge.c index b3410b88..74fa7708 100644 --- a/modules/m_challenge.c +++ b/modules/m_challenge.c @@ -53,24 +53,26 @@ #define CHALLENGE_SECRET_LENGTH 128 /* how long our challenge secret should be */ #ifndef HAVE_LIBCRYPTO + +static const char challenge_desc[] = "Does nothing as OpenSSL was not enabled."; + /* Maybe this should be an error or something?-davidt */ /* now it is -larne */ -static int challenge_load(void) +static int challenge_load(void) { -#ifndef STATIC_MODULES - sendto_realops_snomask(SNO_GENERAL, L_ALL, + sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Challenge module not loaded because OpenSSL is not available."); ilog(L_MAIN, "Challenge module not loaded because OpenSSL is not available."); return -1; -#else - return 0; -#endif } -DECLARE_MODULE_AV2(challenge, challenge_load, NULL, NULL, NULL, NULL, NULL, NULL, NULL); +DECLARE_MODULE_AV2(challenge, challenge_load, NULL, NULL, NULL, NULL, NULL, NULL, challenge_desc); #else -static int m_challenge(struct MsgBuf *, struct Client *, struct Client *, int, const char **); +static const char challenge_desc[] = + "Provides the challenge-response facility used for becoming an IRC operator"; + +static void m_challenge(struct MsgBuf *, struct Client *, struct Client *, int, const char **); /* We have openssl support, so include /CHALLENGE */ struct Message challenge_msgtab = { @@ -79,9 +81,10 @@ struct Message challenge_msgtab = { }; mapi_clist_av1 challenge_clist[] = { &challenge_msgtab, NULL }; -DECLARE_MODULE_AV2(challenge, NULL, NULL, challenge_clist, NULL, NULL, NULL, NULL, NULL); -static int generate_challenge(char **r_challenge, char **r_response, RSA * key); +DECLARE_MODULE_AV2(challenge, NULL, NULL, challenge_clist, NULL, NULL, NULL, NULL, challenge_desc); + +static bool generate_challenge(char **r_challenge, char **r_response, RSA * key); static void cleanup_challenge(struct Client *target_p) @@ -90,9 +93,9 @@ cleanup_challenge(struct Client *target_p) return; rb_free(target_p->localClient->challenge); - rb_free(target_p->localClient->opername); + rb_free(target_p->user->opername); target_p->localClient->challenge = NULL; - target_p->localClient->opername = NULL; + target_p->user->opername = NULL; target_p->localClient->chal_time = 0; } @@ -100,7 +103,7 @@ cleanup_challenge(struct Client *target_p) * m_challenge - generate RSA challenge for wouldbe oper * parv[1] = operator to challenge for, or +response */ -static int +static void m_challenge(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct oper_conf *oper_p; @@ -110,25 +113,37 @@ m_challenge(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou size_t cnt; int len = 0; + if (ConfigFileEntry.oper_secure_only && !IsSecureClient(source_p)) + { + sendto_one_notice(source_p, ":You must be using a secure connection to /CHALLENGE on this server"); + if (ConfigFileEntry.failed_oper_notice) + { + sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, + "Failed CHALLENGE attempt - missing secure connection by %s (%s@%s)", + source_p->name, source_p->username, source_p->host); + } + return; + } + /* if theyre an oper, reprint oper motd and ignore */ if(IsOper(source_p)) { sendto_one(source_p, form_str(RPL_YOUREOPER), me.name, source_p->name); send_oper_motd(source_p); - return 0; + return; } if(*parv[1] == '+') { /* Ignore it if we aren't expecting this... -A1kmm */ if(!source_p->localClient->challenge) - return 0; + return; if((rb_current_time() - source_p->localClient->chal_time) > CHALLENGE_EXPIRES) { sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, source_p->name); ilog(L_FOPER, "EXPIRED CHALLENGE (%s) by (%s!%s@%s) (%s)", - source_p->localClient->opername, source_p->name, + source_p->user->opername, source_p->name, source_p->username, source_p->host, source_p->sockhost); if(ConfigFileEntry.failed_oper_notice) @@ -137,7 +152,7 @@ m_challenge(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou source_p->name, source_p->username, source_p->host); cleanup_challenge(source_p); - return 0; + return; } parv[1]++; @@ -148,7 +163,7 @@ m_challenge(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou { sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, source_p->name); ilog(L_FOPER, "FAILED CHALLENGE (%s) by (%s!%s@%s) (%s)", - source_p->localClient->opername, source_p->name, + source_p->user->opername, source_p->name, source_p->username, source_p->host, source_p->sockhost); if(ConfigFileEntry.failed_oper_notice) @@ -159,20 +174,20 @@ m_challenge(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou rb_free(b_response); cleanup_challenge(source_p); - return 0; + return; } rb_free(b_response); oper_p = find_oper_conf(source_p->username, source_p->orighost, source_p->sockhost, - source_p->localClient->opername); + source_p->user->opername); if(oper_p == NULL) { sendto_one_numeric(source_p, ERR_NOOPERHOST, form_str(ERR_NOOPERHOST)); ilog(L_FOPER, "FAILED OPER (%s) by (%s!%s@%s) (%s)", - source_p->localClient->opername, source_p->name, + source_p->user->opername, source_p->name, source_p->username, source_p->host, source_p->sockhost); @@ -181,7 +196,8 @@ m_challenge(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou "Failed CHALLENGE attempt - host mismatch by %s (%s@%s)", source_p->name, source_p->username, source_p->host); - return 0; + cleanup_challenge(source_p); + return; } cleanup_challenge(source_p); @@ -189,9 +205,9 @@ m_challenge(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou oper_up(source_p, oper_p); ilog(L_OPERED, "OPER %s by %s!%s@%s (%s)", - source_p->localClient->opername, source_p->name, + source_p->user->opername, source_p->name, source_p->username, source_p->host, source_p->sockhost); - return 0; + return; } cleanup_challenge(source_p); @@ -210,16 +226,16 @@ m_challenge(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Failed CHALLENGE attempt - host mismatch by %s (%s@%s)", source_p->name, source_p->username, source_p->host); - return 0; + return; } if(!oper_p->rsa_pubkey) { sendto_one_notice(source_p, ":I'm sorry, PK authentication is not enabled for your oper{} block."); - return 0; + return; } - if(IsOperConfNeedSSL(oper_p) && !IsSSLClient(source_p)) + if(IsOperConfNeedSSL(oper_p) && !IsSecureClient(source_p)) { sendto_one_numeric(source_p, ERR_NOOPERHOST, form_str(ERR_NOOPERHOST)); ilog(L_FOPER, "FAILED CHALLENGE (%s) by (%s!%s@%s) (%s) -- requires SSL/TLS", @@ -228,16 +244,16 @@ m_challenge(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou if(ConfigFileEntry.failed_oper_notice) { - sendto_realops_snomask(SNO_GENERAL, L_ALL, + sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Failed CHALLENGE attempt - missing SSL/TLS by %s (%s@%s)", source_p->name, source_p->username, source_p->host); } - return 0; + return; } if (oper_p->certfp != NULL) { - if (source_p->certfp == NULL || strcasecmp(source_p->certfp, oper_p->certfp)) + if (source_p->certfp == NULL || rb_strcasecmp(source_p->certfp, oper_p->certfp)) { sendto_one_numeric(source_p, ERR_NOOPERHOST, form_str(ERR_NOOPERHOST)); ilog(L_FOPER, "FAILED OPER (%s) by (%s!%s@%s) (%s) -- client certificate fingerprint mismatch", @@ -246,15 +262,15 @@ m_challenge(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou if(ConfigFileEntry.failed_oper_notice) { - sendto_realops_snomask(SNO_GENERAL, L_ALL, + sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Failed OPER attempt - client certificate fingerprint mismatch by %s (%s@%s)", source_p->name, source_p->username, source_p->host); } - return 0; + return; } } - if(!generate_challenge(&challenge, &(source_p->localClient->challenge), oper_p->rsa_pubkey)) + if(generate_challenge(&challenge, &(source_p->localClient->challenge), oper_p->rsa_pubkey)) { char *chal = challenge; source_p->localClient->chal_time = rb_current_time(); @@ -262,7 +278,7 @@ m_challenge(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou { cnt = rb_strlcpy(chal_line, chal, CHALLENGE_WIDTH); sendto_one(source_p, form_str(RPL_RSACHALLENGE2), me.name, source_p->name, chal_line); - if(cnt > CHALLENGE_WIDTH) + if(cnt >= CHALLENGE_WIDTH) chal += CHALLENGE_WIDTH - 1; else break; @@ -271,15 +287,13 @@ m_challenge(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou sendto_one(source_p, form_str(RPL_ENDOFRSACHALLENGE2), me.name, source_p->name); rb_free(challenge); - source_p->localClient->opername = rb_strdup(oper_p->name); + source_p->user->opername = rb_strdup(oper_p->name); } else sendto_one_notice(source_p, ":Failed to generate challenge."); - - return 0; } -static int +static bool generate_challenge(char **r_challenge, char **r_response, RSA * rsa) { SHA_CTX ctx; @@ -290,12 +304,12 @@ generate_challenge(char **r_challenge, char **r_response, RSA * rsa) int ret; if(!rsa) - return -1; + return false; if(rb_get_random(secret, CHALLENGE_SECRET_LENGTH)) { SHA1_Init(&ctx); SHA1_Update(&ctx, (uint8_t *)secret, CHALLENGE_SECRET_LENGTH); - *r_response = malloc(SHA_DIGEST_LENGTH); + *r_response = rb_malloc(SHA_DIGEST_LENGTH); SHA1_Final((uint8_t *)*r_response, &ctx); length = RSA_size(rsa); @@ -306,7 +320,7 @@ generate_challenge(char **r_challenge, char **r_response, RSA * rsa) { *r_challenge = (char *)rb_base64_encode(tmp, ret); rb_free(tmp); - return 0; + return true; } rb_free(tmp); @@ -321,7 +335,7 @@ generate_challenge(char **r_challenge, char **r_response, RSA * rsa) cnt++; } - return (-1); + return false; } #endif /* HAVE_LIBCRYPTO */