X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/blobdiff_plain/bea3f9341a973c59100a209a86bf56a1768e35c5..a3da4b66b05fa77dec803e29b525c464cbd5d37c:/src/nickserv.c?ds=sidebyside diff --git a/src/nickserv.c b/src/nickserv.c index 485d1fd..b85d5ad 100644 --- a/src/nickserv.c +++ b/src/nickserv.c @@ -254,6 +254,7 @@ static const struct message_entry msgtab[] = { { "NSMSG_HANDLEINFO_COOKIE_EMAIL_DATA", "Cookie: New email address: %s" }, { "NSMSG_HANDLEINFO_INFOLINE", "Infoline: %s" }, { "NSMSG_HANDLEINFO_FLAGS", "Flags: %s" }, + { "NSMSG_HANDLEINFO_OPSERV_LEVEL", "Opserv level: %d " }, { "NSMSG_HANDLEINFO_EPITHET", "Epithet: %s" }, { "NSMSG_HANDLEINFO_NOTE", "Note (by %s on %s): %s " }, { "NSMSG_HANDLEINFO_FAKEHOST", "Fake host: %s" }, @@ -263,7 +264,7 @@ static const struct message_entry msgtab[] = { { "NSMSG_HANDLEINFO_LAST_HOST_UNKNOWN", "Last quit hostmask: Unknown" }, { "NSMSG_HANDLEINFO_NICKS", "Nickname(s): %s" }, { "NSMSG_HANDLEINFO_MASKS", "Hostmask(s): %s" }, - { "NSMSG_HANDLEINFO_SSLFPS", "SSL Fingerprints(s): %s" }, + { "NSMSG_HANDLEINFO_SSLFPS", "Client Certificate Fingerprints(s): %s" }, { "NSMSG_HANDLEINFO_IGNORES", "Ignore(s): %s" }, { "NSMSG_HANDLEINFO_CHANNELS", "Channel(s): %s" }, { "NSMSG_HANDLEINFO_CURRENT", "Current nickname(s): %s" }, @@ -298,13 +299,13 @@ static const struct message_entry msgtab[] = { { "NSMSG_ADDMASK_SUCCESS", "Hostmask %s added." }, { "NSMSG_ADDIGNORE_ALREADY", "$b%s$b is already an ignored hostmask in your account." }, { "NSMSG_ADDIGNORE_SUCCESS", "Hostmask %s added." }, - { "NSMSG_ADDSSLFP_ALREADY", "$b%s$b is already an SSL fingerprint in your account." }, - { "NSMSG_ADDSSLFP_SUCCESS", "SSL fingerprint %s added." }, + { "NSMSG_ADDSSLFP_ALREADY", "$b%s$b is already a client certificate fingerprint in your account." }, + { "NSMSG_ADDSSLFP_SUCCESS", "Client certificate fingerprint %s added." }, { "NSMSG_DELMASK_NOTLAST", "You may not delete your last hostmask." }, { "NSMSG_DELMASK_SUCCESS", "Hostmask %s deleted." }, { "NSMSG_DELMASK_NOT_FOUND", "Unable to find mask to be deleted." }, - { "NSMSG_DELSSLFP_SUCCESS", "SSL fingerprint %s deleted." }, - { "NSMSG_DELSSLFP_NOT_FOUND", "Unable to find SSL fingerprint to be deleted." }, + { "NSMSG_DELSSLFP_SUCCESS", "Client certificate fingerprint %s deleted." }, + { "NSMSG_DELSSLFP_NOT_FOUND", "Unable to find client certificate fingerprint to be deleted." }, { "NSMSG_OPSERV_LEVEL_BAD", "You may not promote another oper above your level." }, { "NSMSG_USE_CMD_PASS", "Please use the PASS command to change your password." }, { "NSMSG_UNKNOWN_NICK", "I know nothing about nick $b%s$b." }, @@ -1548,7 +1549,7 @@ static NICKSERV_FUNC(cmd_oregister) char* mask = NULL; char* nick = NULL; - NICKSERV_MIN_PARMS(2); + NICKSERV_MIN_PARMS(3); account = argv[1]; pass = argv[2]; @@ -1795,6 +1796,10 @@ static NICKSERV_FUNC(cmd_handleinfo) reply("NSMSG_HANDLEINFO_FLAGS", nsmsg_none); } + if (hi->opserv_level > 0) { + reply("NSMSG_HANDLEINFO_OPSERV_LEVEL", hi->opserv_level); + } + if (HANDLE_FLAGGED(hi, SUPPORT_HELPER) || HANDLE_FLAGGED(hi, NETWORK_HELPER) || (hi->opserv_level > 0)) { @@ -2122,6 +2127,10 @@ struct handle_info *loc_auth(char *sslfp, char *handle, char *password, char *us handle = hi->handle; } + /* Ensure handle is valid if not found in internal DB */ + if (!hi && (!handle || !is_valid_handle(handle))) + return 0; + #ifdef WITH_LDAP if (nickserv_conf.ldap_enable && (password != NULL)) { ldap_result = ldap_check_auth(handle, password); @@ -2285,9 +2294,75 @@ struct handle_info *loc_auth(char *sslfp, char *handle, char *password, char *us return hi; } +void nickserv_do_autoauth(struct userNode *user) +{ + struct handle_info *hi; + struct userNode *other; + int used, maxlogins; + + /* Already authed, nothing to do */ + if (user->handle_info) + return; + + /* No client certificate fingerprint, cant auto auth */ + if (!user->sslfp) + return; + + hi = find_handleinfo_by_sslfp(user->sslfp); + if (!hi) + return; + + /* User doesn't match host masks */ + if (!valid_user_for(user, hi)) { + if (hi->email_addr && nickserv_conf.email_enabled) + send_message_type(4, user, nickserv, + handle_find_message(hi, "NSMSG_USE_AUTHCOOKIE"), + hi->handle); + else + send_message_type(4, user, nickserv, + handle_find_message(hi, "NSMSG_HOSTMASK_INVALID"), + hi->handle); + return; + } + + /* Account suspended? */ + if (HANDLE_FLAGGED(hi, SUSPENDED)) { + send_message_type(4, user, nickserv, + handle_find_message(hi, "NSMSG_HANDLE_SUSPENDED")); + return; + } + + maxlogins = hi->maxlogins ? hi->maxlogins : nickserv_conf.default_maxlogins; + for (used = 0, other = hi->users; other; other = other->next_authed) { + if (++used >= maxlogins) { + send_message_type(4, user, nickserv, + handle_find_message(hi, "NSMSG_MAX_LOGINS"), + maxlogins); + return; + } + } + + set_user_handle_info(user, hi, 1); + if (nickserv_conf.email_required && !hi->email_addr) + send_message_type(4, user, nickserv, + handle_find_message(hi, "NSMSG_PLEASE_SET_EMAIL")); + + /* If a channel was waiting for this user to auth, + * finish adding them */ + process_adduser_pending(user); + + send_message_type(4, user, nickserv, + handle_find_message(hi, "NSMSG_AUTH_SUCCESS")); + + /* Set +x if autohide is on */ + if(HANDLE_FLAGGED(hi, AUTOHIDE)) + irc_umode(user, "+x"); +} + static NICKSERV_FUNC(cmd_auth) { int pw_arg, used, maxlogins; + int sslfpauth = 0; struct handle_info *hi; const char *passwd; const char *handle; @@ -2341,7 +2416,7 @@ static NICKSERV_FUNC(cmd_auth) } #ifdef WITH_LDAP - if(strchr(argv[1], '<') || strchr(handle, '>')) { + if(strchr(handle, '<') || strchr(handle, '>')) { reply("NSMSG_NO_ANGLEBRACKETS"); return 0; } @@ -2377,7 +2452,7 @@ static NICKSERV_FUNC(cmd_auth) * create the account. */ char *mask; - if(!(hi = nickserv_register(user, user, argv[1], argv[2], 0))) { + if(!(hi = nickserv_register(user, user, handle, passwd, 0))) { reply("NSMSG_UNABLE_TO_ADD"); return 0; /* couldn't add the user for some reason */ } @@ -2419,11 +2494,15 @@ static NICKSERV_FUNC(cmd_auth) argv[pw_arg] = "BADMASK"; return 1; } + + if (valid_user_sslfp(user, hi)) + sslfpauth = 1; + #ifdef WITH_LDAP if(( ( nickserv_conf.ldap_enable && ldap_result == LDAP_INVALID_CREDENTIALS ) || - ( (!nickserv_conf.ldap_enable) && (!checkpass(passwd, hi->passwd)) ) ) && !valid_user_sslfp(user, hi)) { + ( (!nickserv_conf.ldap_enable) && (!checkpass(passwd, hi->passwd)) ) ) && !sslfpauth) { #else - if (!checkpass(passwd, hi->passwd) && !valid_user_sslfp(user, hi)) { + if (!checkpass(passwd, hi->passwd) && !sslfpauth) { #endif unsigned int n; send_message_type(4, user, cmd->parent->bot, @@ -2467,9 +2546,9 @@ static NICKSERV_FUNC(cmd_auth) set_user_handle_info(user, hi, 1); if (nickserv_conf.email_required && !hi->email_addr) reply("NSMSG_PLEASE_SET_EMAIL"); - if (!is_secure_password(hi->handle, passwd, NULL)) + if (!sslfpauth && !is_secure_password(hi->handle, passwd, NULL)) reply("NSMSG_WEAK_PASSWORD"); - if (hi->passwd[0] != '$') + if (!sslfpauth && (hi->passwd[0] != '$')) cryptpass(passwd, hi->passwd); /* If a channel was waiting for this user to auth, @@ -3880,12 +3959,10 @@ static OPTION_FUNC(opt_note) static NICKSERV_FUNC(cmd_reclaim) { - struct handle_info *hi; struct nick_info *ni; struct userNode *victim; NICKSERV_MIN_PARMS(2); - hi = user->handle_info; ni = dict_find(nickserv_nick_dict, argv[1], 0); if (!ni) { reply("NSMSG_UNKNOWN_NICK", argv[1]); @@ -5317,8 +5394,9 @@ nickserv_conf_read(void) if(nickserv_conf.ldap_enable > 0) { /* ldap is enabled but not compiled in - error out */ log_module(MAIN_LOG, LOG_ERROR, "ldap is enabled in config, but not compiled in!"); - nickserv_conf.ldap_enable = 0; - sleep(5); + exit(2); + /* nickserv_conf.ldap_enable = 0; */ + /* sleep(5); */ } #endif @@ -5426,6 +5504,7 @@ static int check_user_nick(struct userNode *user, UNUSED_ARG(void *extra)) { struct nick_info *ni; user->modes &= ~FLAGS_REGNICK; + if (!(ni = get_nick_info(user->nick))) return 0; if (user->handle_info == ni->owner) { @@ -5433,9 +5512,10 @@ check_user_nick(struct userNode *user, UNUSED_ARG(void *extra)) { irc_regnick(user); return 0; } - if (nickserv_conf.warn_nick_owned) + if (nickserv_conf.warn_nick_owned) { send_message(user, nickserv, "NSMSG_RECLAIM_WARN", ni->nick, ni->owner->handle); send_message(user, nickserv, "NSMSG_RECLAIM_HOWTO", ni->owner->handle, nickserv->nick, self->name, ni->owner->handle); + } if (nickserv_conf.auto_reclaim_action == RECLAIM_NONE) return 0; if (nickserv_conf.auto_reclaim_delay) @@ -5446,6 +5526,21 @@ check_user_nick(struct userNode *user, UNUSED_ARG(void *extra)) { return 0; } +static int +new_user_event(struct userNode *user, void *extra) { + /* If the user's server is not bursting, + * the user is authed, the account has autohide set + * and the user doesn't have user mode +x then apply + * the autohide setting. + */ + if (!user->uplink->burst && user->handle_info && + HANDLE_FLAGGED(user->handle_info, AUTOHIDE) && + !IsHiddenHost(user)) + irc_umode(user, "+x"); + + return check_user_nick(user, extra); +} + void handle_account(struct userNode *user, const char *stamp) { @@ -5747,7 +5842,7 @@ sasl_packet(struct SASLSession *session) base64_decode_alloc(session->buf, session->buflen, &raw, &rawlen); raw = (char *)realloc(raw, rawlen+1); - raw[rawlen] = '\0'; + raw[rawlen] = '\0'; authzid = raw; r = raw; @@ -5764,7 +5859,7 @@ sasl_packet(struct SASLSession *session) log_module(NS_LOG, LOG_DEBUG, "SASL: Checking supplied credentials"); - if (c != 2) + if ((c != 2) || !(*authcid)) { log_module(NS_LOG, LOG_DEBUG, "SASL: Incomplete credentials supplied"); irc_sasl(session->source, session->uid, "D", "F"); @@ -5778,10 +5873,18 @@ sasl_packet(struct SASLSession *session) } else { - if (*authzid && irccasecmp(authzid, authcid) && HANDLE_FLAGGED(hi, IMPERSONATE)) + if (*authzid && irccasecmp(authzid, authcid)) { - hii = hi; - hi = get_handle_info(authzid); + if (HANDLE_FLAGGED(hi, IMPERSONATE)) + { + hii = hi; + hi = get_handle_info(authzid); + } + else + { + log_module(NS_LOG, LOG_DEBUG, "SASL: Impersonation unauthorized"); + hi = NULL; + } } if (hi) { @@ -5951,7 +6054,7 @@ init_nickserv(const char *nick) struct chanNode *chan; unsigned int i; NS_LOG = log_register_type("NickServ", "file:nickserv.log"); - reg_new_user_func(check_user_nick, NULL); + reg_new_user_func(new_user_event, NULL); reg_nick_change_func(handle_nick_change, NULL); reg_del_user_func(nickserv_remove_user, NULL); reg_account_func(handle_account); @@ -5990,10 +6093,10 @@ init_nickserv(const char *nick) nickserv_define_func("OADDMASK", cmd_oaddmask, 0, 1, 0); nickserv_define_func("DELMASK", cmd_delmask, -1, 1, 0); nickserv_define_func("ODELMASK", cmd_odelmask, 0, 1, 0); - nickserv_define_func("ADDSSLFP", cmd_addsslfp, -1, 1, 0); - nickserv_define_func("OADDSSLFP", cmd_oaddsslfp, 0, 1, 0); - nickserv_define_func("DELSSLFP", cmd_delsslfp, -1, 1, 0); - nickserv_define_func("ODELSSLFP", cmd_odelsslfp, 0, 1, 0); + nickserv_define_func("ADDCERTFP", cmd_addsslfp, -1, 1, 0); + nickserv_define_func("OADDCERTFP", cmd_oaddsslfp, 0, 1, 0); + nickserv_define_func("DELCERTFP", cmd_delsslfp, -1, 1, 0); + nickserv_define_func("ODELCERTFP", cmd_odelsslfp, 0, 1, 0); nickserv_define_func("PASS", cmd_pass, -1, 1, 0); nickserv_define_func("SET", cmd_set, -1, 1, 0); nickserv_define_func("OSET", cmd_oset, 0, 1, 0);