X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/blobdiff_plain/99c332f89e36cc335bc2ae1bebf4611c2a6a2609..c73514ea1e6c286b2418e7b845c99a4d36601570:/src/nickserv.c diff --git a/src/nickserv.c b/src/nickserv.c index 6bac45c..01c6325 100644 --- a/src/nickserv.c +++ b/src/nickserv.c @@ -88,6 +88,7 @@ #define KEY_PASSWD "passwd" #define KEY_NICKS "nicks" #define KEY_MASKS "masks" +#define KEY_SSLFPS "sslfps" #define KEY_IGNORES "ignores" #define KEY_OPSERV_LEVEL "opserv_level" #define KEY_FLAGS "flags" @@ -238,7 +239,7 @@ static const struct message_entry msgtab[] = { { "NSMSG_HANDLEINFO_REGGED", "Registered on: %s" }, { "NSMSG_HANDLEINFO_LASTSEEN", "Last seen: %s" }, { "NSMSG_HANDLEINFO_LASTSEEN_NOW", "Last seen: Right now!" }, - { "NSMSG_HANDLEINFO_KARMA", " Karma: %d" }, + { "NSMSG_HANDLEINFO_KARMA", "Karma: %d" }, { "NSMSG_HANDLEINFO_VACATION", "On vacation." }, { "NSMSG_HANDLEINFO_EMAIL_ADDR", "Email address: %s" }, { "NSMSG_HANDLEINFO_COOKIE_ACTIVATION", "Cookie: There is currently an activation cookie issued for this account" }, @@ -257,6 +258,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_IGNORES", "Ignore(s): %s" }, { "NSMSG_HANDLEINFO_CHANNELS", "Channel(s): %s" }, { "NSMSG_HANDLEINFO_CURRENT", "Current nickname(s): %s" }, @@ -286,9 +288,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_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_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." }, @@ -504,21 +510,25 @@ delete_nick(struct nick_info *ni) } static unreg_func_t *unreg_func_list; +static void **unreg_func_list_extra; static unsigned int unreg_func_size = 0, unreg_func_used = 0; void -reg_unreg_func(unreg_func_t func) +reg_unreg_func(unreg_func_t func, void *extra) { if (unreg_func_used == unreg_func_size) { if (unreg_func_size) { unreg_func_size <<= 1; unreg_func_list = realloc(unreg_func_list, unreg_func_size*sizeof(unreg_func_t)); + unreg_func_list_extra = realloc(unreg_func_list_extra, unreg_func_size*sizeof(void*)); } else { unreg_func_size = 8; unreg_func_list = malloc(unreg_func_size*sizeof(unreg_func_t)); + unreg_func_list_extra = malloc(unreg_func_size*sizeof(void*)); } } - unreg_func_list[unreg_func_used++] = func; + unreg_func_list[unreg_func_used] = func; + unreg_func_list_extra[unreg_func_used++] = extra; } static void @@ -536,6 +546,7 @@ free_handle_info(void *vhi) struct handle_info *hi = vhi; free_string_list(hi->masks); + free_string_list(hi->sslfps); free_string_list(hi->ignores); assert(!hi->users); @@ -581,7 +592,7 @@ nickserv_unregister_handle(struct handle_info *hi, struct userNode *notify, stru } #endif for (n=0; nusers) { if (nickserv_conf.sync_log) { uNode = GetUserH(hi->users->nick); @@ -827,6 +838,25 @@ valid_user_for(struct userNode *user, struct handle_info *hi) return 0; } +static int +valid_user_sslfp(struct userNode *user, struct handle_info *hi) +{ + unsigned int ii; + + if (!hi->sslfps->used) + return 0; + if (!(user->sslfp)) + return 0; + + /* If any SSL fingerprint matches, allow it. */ + for (ii=0; iisslfps->used; ii++) + if (!irccasecmp(user->sslfp, hi->sslfps->list[ii])) + return 1; + + /* No valid SSL fingerprint found. */ + return 0; +} + static int is_secure_password(const char *handle, const char *pass, struct userNode *user) { @@ -870,21 +900,25 @@ is_secure_password(const char *handle, const char *pass, struct userNode *user) } static auth_func_t *auth_func_list; +static void **auth_func_list_extra; static unsigned int auth_func_size = 0, auth_func_used = 0; void -reg_auth_func(auth_func_t func) +reg_auth_func(auth_func_t func, void *extra) { if (auth_func_used == auth_func_size) { if (auth_func_size) { auth_func_size <<= 1; auth_func_list = realloc(auth_func_list, auth_func_size*sizeof(auth_func_t)); + auth_func_list_extra = realloc(auth_func_list_extra, auth_func_size*sizeof(void*)); } else { auth_func_size = 8; auth_func_list = malloc(auth_func_size*sizeof(auth_func_t)); + auth_func_list_extra = malloc(auth_func_size*sizeof(void*)); } } - auth_func_list[auth_func_used++] = func; + auth_func_list[auth_func_used] = func; + auth_func_list_extra[auth_func_used++] = extra; } static handle_rename_func_t *rf_list; @@ -964,7 +998,7 @@ void send_func_list(struct userNode *user) old_info = user->handle_info; for (n=0; nnick)) { for (n=0; ndead) return; } @@ -1104,7 +1138,7 @@ nickserv_register(struct userNode *user, struct userNode *settee, const char *ha #ifdef WITH_LDAP if(nickserv_conf.ldap_enable && nickserv_conf.ldap_admin_dn) { int rc; - rc = ldap_do_add(handle, crypted, NULL); + rc = ldap_do_add(handle, (no_auth ? NULL : crypted), NULL); if(LDAP_SUCCESS != rc && LDAP_ALREADY_EXISTS != rc ) { if(user) send_message(user, nickserv, "NSMSG_LDAP_FAIL", ldap_err2string(rc)); @@ -1114,6 +1148,7 @@ nickserv_register(struct userNode *user, struct userNode *settee, const char *ha #endif hi = register_handle(handle, crypted, 0); hi->masks = alloc_string_list(1); + hi->sslfps = alloc_string_list(1); hi->ignores = alloc_string_list(1); hi->users = NULL; hi->language = lang_C; @@ -1491,14 +1526,15 @@ static NICKSERV_FUNC(cmd_oregister) pass = argv[2]; if(nickserv_conf.force_handles_lowercase) irc_strtolower(account); + if (!is_valid_handle(argv[1])) { + reply("NSMSG_BAD_HANDLE", argv[1]); + return 0; + } if (nickserv_conf.email_required) { NICKSERV_MIN_PARMS(3); email = argv[3]; - if (argc >= 4) {/* take: "acct pass email mask nick" or "acct pass email mask" or "acct pass email nick" */ - if (argc < 4) { - mask = NULL; - settee = NULL; - } else if (strchr(argv[4], '@')) + if (argc > 4) {/* take: "acct pass email mask nick" or "acct pass email mask" or "acct pass email nick" */ + if (strchr(argv[4], '@')) mask = argv[4]; else nick = argv[4]; @@ -1508,11 +1544,8 @@ static NICKSERV_FUNC(cmd_oregister) } } else { - if (argc >= 4) {/* take: "account pass mask nick" or "account pass mask" or "account pass nick" */ - if (argc < 4) { - mask = NULL; - settee = NULL; - } else if (strchr(argv[3], '@')) + if (argc > 3) {/* take: "account pass mask nick" or "account pass mask" or "account pass nick" */ + if (strchr(argv[3], '@')) mask = argv[3]; else nick = argv[3]; @@ -1799,6 +1832,26 @@ static NICKSERV_FUNC(cmd_handleinfo) reply("NSMSG_HANDLEINFO_MASKS", nsmsg_none); } + if (hi->sslfps->used) { + for (i=0; i < hi->sslfps->used; i++) { + herelen = strlen(hi->sslfps->list[i]); + if (pos + herelen + 1 > ArrayLength(buff)) { + i--; + goto print_sslfp_buff; + } + memcpy(buff+pos, hi->sslfps->list[i], herelen); + pos += herelen; buff[pos++] = ' '; + if (i+1 == hi->sslfps->used) { + print_sslfp_buff: + buff[pos-1] = 0; + reply("NSMSG_HANDLEINFO_SSLFPS", buff); + pos = 0; + } + } + } else { + reply("NSMSG_HANDLEINFO_SSLFPS", nsmsg_none); + } + if (hi->ignores->used) { for (i=0; i < hi->ignores->used; i++) { herelen = strlen(hi->ignores->list[i]); @@ -1980,88 +2033,94 @@ reg_failpw_func(failpw_func_t func, void *extra) * called by nefariouses enhanced AC login-on-connect code * */ -struct handle_info *loc_auth(char *handle, char *password, char *userhost) +struct handle_info *loc_auth(char *sslfp, char *handle, char *password, char *userhost) { - int pw_arg, used, maxlogins; + int wildmask = 0, auth = 0; + int used, maxlogins; unsigned int ii; - int wildmask = 0; struct handle_info *hi; struct userNode *other; #ifdef WITH_LDAP int ldap_result = LDAP_SUCCESS; char *email = NULL; #endif - + hi = dict_find(nickserv_handle_dict, handle, NULL); - pw_arg = 2; - + #ifdef WITH_LDAP - if(nickserv_conf.ldap_enable) { + if (nickserv_conf.ldap_enable) { ldap_result = ldap_check_auth(handle, password); - if(ldap_result != LDAP_SUCCESS) { - return NULL; + if (!hi && (ldap_result != LDAP_SUCCESS)) + return NULL; + if (ldap_result == LDAP_SUCCESS) { + /* Mark auth as successful */ + auth++; + } + + if (!hi && (ldap_result == LDAP_SUCCESS) && nickserv_conf.ldap_autocreate) { + /* user not found, but authed to ldap successfully.. + * create the account. + */ + char *mask; + int rc; + + /* Add a *@* mask */ + /* TODO if userhost is not null, build mask based on that. */ + if(nickserv_conf.default_hostmask) + mask = "*@*"; + else + return NULL; /* They dont have a *@* mask so they can't loc */ + + if(!(hi = nickserv_register(NULL, NULL, handle, password, 0))) { + return 0; /* couldn't add the user for some reason */ + } + + if((rc = ldap_get_user_info(handle, &email) != LDAP_SUCCESS)) + { + if(nickserv_conf.email_required) { + return 0; + } + } + if(email) { + nickserv_set_email_addr(hi, email); + free(email); + } + if(mask) { + char* mask_canonicalized = canonicalize_hostmask(strdup(mask)); + string_list_append(hi->masks, mask_canonicalized); + } + if(nickserv_conf.sync_log) + SyncLog("REGISTER %s %s %s %s", hi->handle, hi->passwd, "@", handle); } } -#else - if (!hi) { - return NULL; - } +#endif - if (!checkpass(password, hi->passwd)) { + /* hi should now be a valid handle, if not return NULL */ + if (!hi) return NULL; - } -#endif + #ifdef WITH_LDAP - /* ldap libs are present but we are not using them... */ - if( !nickserv_conf.ldap_enable ) { - if (!hi) { - return NULL; - } - if (!checkpass(password, hi->passwd)) { - return NULL; - } + if (password && *password && !nickserv_conf.ldap_enable) { +#else + if (password && *password) { +#endif + if (checkpass(password, hi->passwd)) + auth++; } - else if( (!hi) && ldap_result == LDAP_SUCCESS && nickserv_conf.ldap_autocreate) { - /* user not found, but authed to ldap successfully.. - * create the account. - */ - char *mask; - int rc; - - /* Add a *@* mask */ - /* TODO if userhost is not null, build mask based on that. */ - if(nickserv_conf.default_hostmask) - mask = "*@*"; - else - return NULL; /* They dont have a *@* mask so they can't loc */ - - if(!(hi = nickserv_register(NULL, NULL, handle, password, 0))) { - return 0; /* couldn't add the user for some reason */ - } - - if((rc = ldap_get_user_info(handle, &email) != LDAP_SUCCESS)) - { - if(nickserv_conf.email_required) { - return 0; + + if (!auth && sslfp && *sslfp && hi->sslfps->used) { + /* If any SSL fingerprint matches, allow it. */ + for (ii=0; iisslfps->used; ii++) { + if (!irccasecmp(sslfp, hi->sslfps->list[ii])) { + auth++; + break; } - } - if(email) { - nickserv_set_email_addr(hi, email); - free(email); - } - if(mask) { - char* mask_canonicalized = canonicalize_hostmask(strdup(mask)); - string_list_append(hi->masks, mask_canonicalized); - } - if(nickserv_conf.sync_log) - SyncLog("REGISTER %s %s %s %s", hi->handle, hi->passwd, "@", handle); + } } -#endif - - /* Still no account, so just fail out */ - if (!hi) { + + /* Auth should have succeeded by this point */ + if (!auth) return NULL; - } /* We don't know the users hostname, or anything because they * havn't registered yet. So we can only allow LOC if your @@ -2089,7 +2148,7 @@ struct handle_info *loc_auth(char *handle, char *password, char *userhost) ui = malloc(strlen(userhost)); sprintf(uh, "%s@%s", ident, realhost); sprintf(ui, "%s@%s", ident, ip); - for (ii=0; iimasks->used; ii++) + for (ii=0; iimasks->used; ii++) { if(match_ircglob(uh, hi->masks->list[ii]) || match_ircglob(ui, hi->masks->list[ii])) @@ -2267,10 +2326,10 @@ static NICKSERV_FUNC(cmd_auth) return 1; } #ifdef WITH_LDAP - if( ( nickserv_conf.ldap_enable && ldap_result == LDAP_INVALID_CREDENTIALS ) || - ( (!nickserv_conf.ldap_enable) && (!checkpass(passwd, hi->passwd)) ) ) { + if(( ( nickserv_conf.ldap_enable && ldap_result == LDAP_INVALID_CREDENTIALS ) || + ( (!nickserv_conf.ldap_enable) && (!checkpass(passwd, hi->passwd)) ) ) && !valid_user_sslfp(user, hi)) { #else - if (!checkpass(passwd, hi->passwd)) { + if (!checkpass(passwd, hi->passwd) && !valid_user_sslfp(user, hi)) { #endif unsigned int n; send_message_type(4, user, cmd->parent->bot, @@ -2516,39 +2575,26 @@ static NICKSERV_FUNC(cmd_odelcookie) switch (hi->cookie->type) { case ACTIVATION: safestrncpy(hi->passwd, hi->cookie->data, sizeof(hi->passwd)); - if (nickserv_conf.sync_log) - SyncLog("ACCOUNTACC %s", hi->handle); - break; - case PASSWORD_CHANGE: - safestrncpy(hi->passwd, hi->cookie->data, sizeof(hi->passwd)); - if (nickserv_conf.sync_log) - SyncLog("PASSCHANGE %s %s", hi->handle, hi->passwd); - break; - case EMAIL_CHANGE: - if (!hi->email_addr && nickserv_conf.sync_log) { - if (nickserv_conf.sync_log) - SyncLog("REGISTER %s %s %s %s", hi->handle, hi->passwd, hi->cookie->data, user->info); - } #ifdef WITH_LDAP if(nickserv_conf.ldap_enable && nickserv_conf.ldap_admin_dn) { int rc; - if((rc = ldap_do_modify(hi->handle, NULL, hi->cookie->data)) != LDAP_SUCCESS) { - /* Falied to update email in ldap, but still + if((rc = ldap_do_modify(hi->handle, hi->cookie->data, NULL)) != LDAP_SUCCESS) { + /* Falied to update password in ldap, but still * updated it here.. what should we do? */ - reply("NSMSG_LDAP_FAIL_SEND_EMAIL", ldap_err2string(rc)); - } else { - nickserv_set_email_addr(hi, hi->cookie->data); + reply("NSMSG_LDAP_FAIL", ldap_err2string(rc)); + return 0; } } - else { - nickserv_set_email_addr(hi, hi->cookie->data); - } -#else - nickserv_set_email_addr(hi, hi->cookie->data); #endif if (nickserv_conf.sync_log) - SyncLog("EMAILCHANGE %s %s", hi->handle, hi->cookie->data); + SyncLog("ACCOUNTACC %s", hi->handle); break; + case PASSWORD_CHANGE: + break; + case EMAIL_CHANGE: + break; + case ALLOWAUTH: + break; default: reply("NSMSG_BAD_COOKIE_TYPE", hi->cookie->type); log_module(NS_LOG, LOG_ERROR, "Bad cookie type %d for account %s.", hi->cookie->type, hi->handle); @@ -2899,6 +2945,80 @@ static NICKSERV_FUNC(cmd_odelmask) return nickserv_delmask(cmd, user, hi, argv[2], 1); } +static int +nickserv_addsslfp(struct userNode *user, struct handle_info *hi, const char *sslfp) +{ + unsigned int i; + char *new_sslfp = strdup(sslfp); + for (i=0; isslfps->used; i++) { + if (!irccasecmp(new_sslfp, hi->sslfps->list[i])) { + send_message(user, nickserv, "NSMSG_ADDSSLFP_ALREADY", new_sslfp); + free(new_sslfp); + return 0; + } + } + string_list_append(hi->sslfps, new_sslfp); + send_message(user, nickserv, "NSMSG_ADDSSLFP_SUCCESS", new_sslfp); + return 1; +} + +static NICKSERV_FUNC(cmd_addsslfp) +{ + NICKSERV_MIN_PARMS((user->sslfp ? 1 : 2)); + if ((argc < 2) && (user->sslfp)) { + int res = nickserv_addsslfp(user, user->handle_info, user->sslfp); + return res; + } else { + return nickserv_addsslfp(user, user->handle_info, argv[1]); + } +} + +static NICKSERV_FUNC(cmd_oaddsslfp) +{ + struct handle_info *hi; + + NICKSERV_MIN_PARMS(3); + if (!(hi = get_victim_oper(user, argv[1]))) + return 0; + return nickserv_addsslfp(user, hi, argv[2]); +} + +static int +nickserv_delsslfp(struct svccmd *cmd, struct userNode *user, struct handle_info *hi, const char *del_sslfp) +{ + unsigned int i; + for (i=0; isslfps->used; i++) { + if (!irccasecmp(del_sslfp, hi->sslfps->list[i])) { + char *old_sslfp = hi->sslfps->list[i]; + hi->sslfps->list[i] = hi->sslfps->list[--hi->sslfps->used]; + reply("NSMSG_DELSSLFP_SUCCESS", old_sslfp); + free(old_sslfp); + return 1; + } + } + reply("NSMSG_DELSSLFP_NOT_FOUND"); + return 0; +} + +static NICKSERV_FUNC(cmd_delsslfp) +{ + NICKSERV_MIN_PARMS((user->sslfp ? 1 : 2)); + if ((argc < 2) && (user->sslfp)) { + return nickserv_delsslfp(cmd, user, user->handle_info, user->sslfp); + } else { + return nickserv_delsslfp(cmd, user, user->handle_info, argv[1]); + } +} + +static NICKSERV_FUNC(cmd_odelsslfp) +{ + struct handle_info *hi; + NICKSERV_MIN_PARMS(3); + if (!(hi = get_victim_oper(user, argv[1]))) + return 0; + return nickserv_delsslfp(cmd, user, hi, argv[2]); +} + int nickserv_modify_handle_flags(struct userNode *user, struct userNode *bot, const char *str, unsigned long *padded, unsigned long *premoved) { unsigned int nn, add = 1, pos; @@ -3378,7 +3498,7 @@ oper_try_set_access(struct userNode *user, struct userNode *bot, struct handle_i } if(nickserv_conf.ldap_enable && *(nickserv_conf.ldap_field_oslevel) && *(nickserv_conf.ldap_admin_dn)) { int rc; - if((rc = ldap_do_oslevel(target->handle, new_level)) != LDAP_SUCCESS) { + if((rc = ldap_do_oslevel(target->handle, new_level, target->opserv_level)) != LDAP_SUCCESS) { send_message(user, bot, "NSMSG_LDAP_FAIL", ldap_err2string(rc)); return 0; } @@ -3889,6 +4009,8 @@ nickserv_saxdb_write(struct saxdb_context *ctx) { saxdb_write_sint(ctx, KEY_KARMA, hi->karma); if (hi->masks->used) saxdb_write_string_list(ctx, KEY_MASKS, hi->masks); + if (hi->sslfps->used) + saxdb_write_string_list(ctx, KEY_SSLFPS, hi->sslfps); if (hi->ignores->used) saxdb_write_string_list(ctx, KEY_IGNORES, hi->ignores); if (hi->maxlogins) @@ -3923,21 +4045,25 @@ nickserv_saxdb_write(struct saxdb_context *ctx) { } static handle_merge_func_t *handle_merge_func_list; +static void **handle_merge_func_list_extra; static unsigned int handle_merge_func_size = 0, handle_merge_func_used = 0; void -reg_handle_merge_func(handle_merge_func_t func) +reg_handle_merge_func(handle_merge_func_t func, void *extra) { if (handle_merge_func_used == handle_merge_func_size) { if (handle_merge_func_size) { handle_merge_func_size <<= 1; handle_merge_func_list = realloc(handle_merge_func_list, handle_merge_func_size*sizeof(handle_merge_func_t)); + handle_merge_func_list_extra = realloc(handle_merge_func_list_extra, handle_merge_func_size*sizeof(void*)); } else { handle_merge_func_size = 8; handle_merge_func_list = malloc(handle_merge_func_size*sizeof(handle_merge_func_t)); + handle_merge_func_list_extra = malloc(handle_merge_func_size*sizeof(void*)); } } - handle_merge_func_list[handle_merge_func_used++] = func; + handle_merge_func_list[handle_merge_func_used] = func; + handle_merge_func_list_extra[handle_merge_func_used++] = extra; } static NICKSERV_FUNC(cmd_merge) @@ -3959,7 +4085,7 @@ static NICKSERV_FUNC(cmd_merge) } for (n=0; nnicks) { @@ -3982,6 +4108,16 @@ static NICKSERV_FUNC(cmd_merge) string_list_append(hi_to->masks, strdup(mask)); } + /* Merge the SSL fingerprints. */ + for (ii=0; iisslfps->used; ii++) { + char *sslfp = hi_from->sslfps->list[ii]; + for (jj=0; jjsslfps->used; jj++) + if (!irccasecmp(hi_to->sslfps->list[jj], sslfp)) + break; + if (jj==hi_to->sslfps->used) /* Nothing from the "to" handle covered this sslfp, so add it. */ + string_list_append(hi_to->sslfps, strdup(sslfp)); + } + /* Merge the ignores. */ for (ii=0; iiignores->used; ii++) { char *ignore = hi_from->ignores->list[ii]; @@ -4497,7 +4633,7 @@ static void nickserv_db_read_handle(char *handle, dict_t obj) { const char *str; - struct string_list *masks, *slist, *ignores; + struct string_list *masks, *sslfps, *slist, *ignores; struct handle_info *hi; struct userNode *authed_users; struct userData *channel_list; @@ -4537,6 +4673,8 @@ nickserv_db_read_handle(char *handle, dict_t obj) hi->channels = channel_list; masks = database_get_data(obj, KEY_MASKS, RECDB_STRING_LIST); hi->masks = masks ? string_list_copy(masks) : alloc_string_list(1); + sslfps = database_get_data(obj, KEY_SSLFPS, RECDB_STRING_LIST); + hi->sslfps = sslfps ? string_list_copy(sslfps) : alloc_string_list(1); ignores = database_get_data(obj, KEY_IGNORES, RECDB_STRING_LIST); hi->ignores = ignores ? string_list_copy(ignores) : alloc_string_list(1); str = database_get_data(obj, KEY_MAXLOGINS, RECDB_QSTRING); @@ -5161,7 +5299,7 @@ nickserv_define_func(const char *name, modcmd_func_t func, int min_level, int mu } static void -nickserv_db_cleanup(void) +nickserv_db_cleanup(UNUSED_ARG(void* extra)) { unreg_del_user_func(nickserv_remove_user, NULL); userList_clean(&curr_helpers); @@ -5174,12 +5312,15 @@ nickserv_db_cleanup(void) dict_delete(nickserv_id_dict); dict_delete(nickserv_conf.weak_password_dict); free(auth_func_list); + free(auth_func_list_extra); free(unreg_func_list); + free(unreg_func_list_extra); free(rf_list); free(rf_list_extra); free(allowauth_func_list); free(allowauth_func_list_extra); free(handle_merge_func_list); + free(handle_merge_func_list_extra); free(failpw_func_list); free(failpw_func_list_extra); if (nickserv_conf.valid_handle_regex_set) @@ -5188,7 +5329,7 @@ nickserv_db_cleanup(void) regfree(&nickserv_conf.valid_nick_regex); } -void handle_loc_auth_oper(struct userNode *user, UNUSED_ARG(struct handle_info *old_handle)) { +void handle_loc_auth_oper(struct userNode *user, UNUSED_ARG(struct handle_info *old_handle), UNUSED_ARG(void *extra)) { if (!*nickserv_conf.auto_oper || !user->handle_info) return; @@ -5215,7 +5356,7 @@ init_nickserv(const char *nick) reg_nick_change_func(handle_nick_change, NULL); reg_del_user_func(nickserv_remove_user, NULL); reg_account_func(handle_account); - reg_auth_func(handle_loc_auth_oper); + reg_auth_func(handle_loc_auth_oper, NULL); /* set up handle_inverse_flags */ memset(handle_inverse_flags, 0, sizeof(handle_inverse_flags)); @@ -5246,6 +5387,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("PASS", cmd_pass, -1, 1, 0); nickserv_define_func("SET", cmd_set, -1, 1, 0); nickserv_define_func("OSET", cmd_oset, 0, 1, 0); @@ -5329,7 +5474,7 @@ init_nickserv(const char *nick) nickserv_service = service_register(nickserv); } saxdb_register("NickServ", nickserv_saxdb_read, nickserv_saxdb_write); - reg_exit_func(nickserv_db_cleanup); + reg_exit_func(nickserv_db_cleanup, NULL); if(nickserv_conf.handle_expire_frequency) timeq_add(now + nickserv_conf.handle_expire_frequency, expire_handles, NULL);