]> jfr.im git - irc/evilnet/x3.git/blobdiff - src/nickserv.c
Heres an initial version of centralied silence list management, I want to make the...
[irc/evilnet/x3.git] / src / nickserv.c
index ade655da7eb09d114f4831de024d212911a50c1c..12e1a30d9e3f7da2e1b929d394f37ae2983b9f23 100644 (file)
@@ -3,7 +3,7 @@
  *
  * This file is part of x3.
  *
- * srvx is free software; you can redistribute it and/or modify
+ * x3 is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
 #define KEY_COOKIE_TIMEOUT "cookie_timeout"
 #define KEY_ACCOUNTS_PER_EMAIL "accounts_per_email"
 #define KEY_EMAIL_SEARCH_LEVEL "email_search_level"
+#define KEY_DEFAULT_STYLE "default_style"
 
 #define KEY_ID "id"
 #define KEY_PASSWD "passwd"
 #define KEY_NICKS "nicks"
 #define KEY_MASKS "masks"
+#define KEY_IGNORES "ignores"
 #define KEY_OPSERV_LEVEL "opserv_level"
 #define KEY_FLAGS "flags"
 #define KEY_REGISTER_ON "register"
@@ -213,6 +215,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_IGNORES", "Ignore(s): %s" },
     { "NSMSG_HANDLEINFO_CHANNELS", "Channel(s): %s" },
     { "NSMSG_HANDLEINFO_CURRENT", "Current nickname(s): %s" },
     { "NSMSG_HANDLEINFO_DNR", "Do-not-register (by %s): %s" },
@@ -239,6 +242,8 @@ static const struct message_entry msgtab[] = {
     { "NSMSG_MASK_INVALID", "$b%s$b is an invalid hostmask." },
     { "NSMSG_ADDMASK_ALREADY", "$b%s$b is already a hostmask in your account." },
     { "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_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." },
@@ -407,6 +412,7 @@ static struct {
     unsigned char hard_maxlogins;
     const char *auto_oper;
     const char *auto_admin;
+    char default_style;
 } nickserv_conf;
 
 /* We have 2^32 unique account IDs to use. */
@@ -559,6 +565,7 @@ free_handle_info(void *vhi)
 #endif
 
     free_string_list(hi->masks);
+    free_string_list(hi->ignores);
     assert(!hi->users);
 
     while (hi->nicks)
@@ -718,6 +725,7 @@ is_registerable_nick(const char *nick)
     }
     return 1;
 }
+/*  this has been replaced with one in tools.c
 
 static int
 is_valid_email_addr(const char *email)
@@ -725,6 +733,8 @@ is_valid_email_addr(const char *email)
     return strchr(email, '@') != NULL;
 }
 
+*/ 
+
 static const char *
 visible_email_addr(struct userNode *user, struct handle_info *hi)
 {
@@ -1062,6 +1072,7 @@ nickserv_register(struct userNode *user, struct userNode *settee, const char *ha
     cryptpass(passwd, crypted);
     hi = register_handle(handle, crypted, 0);
     hi->masks = alloc_string_list(1);
+    hi->ignores = alloc_string_list(1);
     hi->users = NULL;
     hi->language = lang_C;
     hi->registered = now;
@@ -1250,6 +1261,7 @@ nickserv_set_email_addr(struct handle_info *hi, const char *new_email_addr)
 
 static NICKSERV_FUNC(cmd_register)
 {
+    irc_in_addr_t ip;
     struct handle_info *hi;
     const char *email_addr, *password;
     char syncpass[MD5_CRYPT_LENGTH];
@@ -1295,7 +1307,7 @@ static NICKSERV_FUNC(cmd_register)
         email_addr = argv[3];
 
         /* Check that the email address looks valid.. */
-        if (!is_valid_email_addr(email_addr)) {
+        if (!valid_email(email_addr)) {
             reply("NSMSG_BAD_EMAIL_ADDR");
             return 0;
         }
@@ -1343,7 +1355,7 @@ static NICKSERV_FUNC(cmd_register)
         string_list_append(hi->masks, strdup("*@*"));
     } else {
         string_list_append(hi->masks, generate_hostmask(user, GENMASK_OMITNICK|GENMASK_NO_HIDING|GENMASK_ANY_IDENT));
-        if (user->ip.s_addr && user->hostname[strspn(user->hostname, "0123456789.")])
+        if (irc_in_addr_is_valid(user->ip) && !irc_pton(&ip, NULL, user->hostname))
             string_list_append(hi->masks, generate_hostmask(user, GENMASK_OMITNICK|GENMASK_BYIP|GENMASK_NO_HIDING|GENMASK_ANY_IDENT));
     }
 
@@ -1386,7 +1398,7 @@ static NICKSERV_FUNC(cmd_oregister)
     struct userNode *settee;
     struct handle_info *hi;
 
-    NICKSERV_MIN_PARMS(nickserv_conf.email_required ? 5 : 4);
+    NICKSERV_MIN_PARMS(nickserv_conf.email_required ? 4 : 3);
 
     if (!is_valid_handle(argv[1])) {
         reply("NSMSG_BAD_HANDLE", argv[1]);
@@ -1394,7 +1406,7 @@ static NICKSERV_FUNC(cmd_oregister)
     }
 
     if (nickserv_conf.email_required) {
-        if (!is_valid_email_addr(argv[4])) {
+        if (!valid_email(argv[4])) {
             reply("NSMSG_BAD_EMAIL_ADDR");
             return 0;
         }
@@ -1436,6 +1448,75 @@ static NICKSERV_FUNC(cmd_oregister)
     return 1;
 }
 
+static int
+nickserv_ignore(struct userNode *user, struct handle_info *hi, const char *mask)
+{
+    unsigned int i;
+    char *new_mask = canonicalize_hostmask(strdup(mask));
+    for (i=0; i<hi->ignores->used; i++) {
+        if (!irccasecmp(new_mask, hi->ignores->list[i])) {
+            send_message(user, nickserv, "NSMSG_ADDIGNORE_ALREADY", new_mask);
+            free(new_mask);
+            return 0;
+        }
+    }
+    string_list_append(hi->ignores, new_mask);
+    send_message(user, nickserv, "NSMSG_ADDIGNORE_SUCCESS", new_mask);
+
+    irc_silence(user, new_mask, 1);
+    return 1;
+}
+
+static NICKSERV_FUNC(cmd_addignore)
+{
+    NICKSERV_MIN_PARMS(2);
+
+    return nickserv_ignore(user, user->handle_info, argv[1]);
+}
+
+static NICKSERV_FUNC(cmd_oaddignore)
+{
+    struct handle_info *hi;
+
+    NICKSERV_MIN_PARMS(3);
+    if (!(hi = get_victim_oper(user, argv[1])))
+        return 0;
+    return nickserv_ignore(user, hi, argv[2]);
+}
+
+static int
+nickserv_delignore(struct userNode *user, struct handle_info *hi, const char *del_mask)
+{
+    unsigned int i;
+    for (i=0; i<hi->ignores->used; i++) {
+       if (!strcmp(del_mask, hi->ignores->list[i])) {
+           char *old_mask = hi->ignores->list[i];
+           hi->ignores->list[i] = hi->ignores->list[--hi->ignores->used];
+           send_message(user, nickserv, "NSMSG_DELMASK_SUCCESS", old_mask);
+            irc_silence(user, old_mask, 0);
+           free(old_mask);
+           return 1;
+       }
+    }
+    send_message(user, nickserv, "NSMSG_DELMASK_NOT_FOUND");
+    return 0;
+}
+
+static NICKSERV_FUNC(cmd_delignore)
+{
+    NICKSERV_MIN_PARMS(2);
+    return nickserv_delignore(user, user->handle_info, argv[1]);
+}
+
+static NICKSERV_FUNC(cmd_odelignore)
+{
+    struct handle_info *hi;
+    NICKSERV_MIN_PARMS(3);
+    if (!(hi = get_victim_oper(user, argv[1])))
+        return 0;
+    return nickserv_delignore(user, hi, argv[2]);
+}
+
 static NICKSERV_FUNC(cmd_handleinfo)
 {
     char buff[400];
@@ -1580,6 +1661,26 @@ static NICKSERV_FUNC(cmd_handleinfo)
         reply("NSMSG_HANDLEINFO_MASKS", nsmsg_none);
     }
 
+    if (hi->ignores->used) {
+        for (i=0; i < hi->ignores->used; i++) {
+            herelen = strlen(hi->ignores->list[i]);
+            if (pos + herelen + 1 > ArrayLength(buff)) {
+                i--;
+                goto print_ignore_buff;
+            }
+            memcpy(buff+pos, hi->ignores->list[i], herelen);
+            pos += herelen; buff[pos++] = ' ';
+            if (i+1 == hi->ignores->used) {
+              print_ignore_buff:
+                buff[pos-1] = 0;
+                reply("NSMSG_HANDLEINFO_IGNORES", buff);
+                pos = 0;
+            }
+        }
+    } else {
+        reply("NSMSG_HANDLEINFO_IGNORES", nsmsg_none);
+    }
+
     if (hi->channels) {
        struct userData *channel, *next;
        char *name;
@@ -2405,7 +2506,7 @@ set_list(struct userNode *user, struct handle_info *hi, int override)
     option_func_t *opt;
     unsigned int i;
     char *set_display[] = {
-        "INFO", "WIDTH", "TABLEWIDTH", "COLOR", "PRIVMSG", /* "STYLE", */
+        "INFO", "WIDTH", "TABLEWIDTH", "COLOR", "PRIVMSG", "STYLE",
         "EMAIL", "ANNOUNCEMENTS", "AUTOHIDE", "MAXLOGINS", "LANGUAGE",
         "FAKEHOST", "TITLE", "EPITHET"
     };
@@ -2556,31 +2657,39 @@ static OPTION_FUNC(opt_autohide)
     return 1;
 }
 
-/*
 static OPTION_FUNC(opt_style)
 {
     char *style;
 
     if (argc > 1) {
-       if (!irccasecmp(argv[1], "Zoot"))
-           hi->userlist_style = HI_STYLE_ZOOT;
-       else if (!irccasecmp(argv[1], "def"))
-           hi->userlist_style = HI_STYLE_DEF;
-    }
+        if (!irccasecmp(argv[1], "Clean"))
+            hi->userlist_style = HI_STYLE_CLEAN;
+        else if (!irccasecmp(argv[1], "Advanced"))
+            hi->userlist_style = HI_STYLE_ADVANCED;
+        else if (!irccasecmp(argv[1], "Classic"))
+            hi->userlist_style = HI_STYLE_CLASSIC;
+        else  /* Default to normal */
+            hi->userlist_style = HI_STYLE_NORMAL;
+    } /* TODO: give error if unknow style is chosen */
 
     switch (hi->userlist_style) {
-    case HI_STYLE_DEF:
-       style = "def";
-       break;
-    case HI_STYLE_ZOOT:
-    default:
-       style = "Zoot";
+        case HI_STYLE_ADVANCED:
+            style = "Advanced";
+            break;
+        case HI_STYLE_CLASSIC:
+            style = "Classic";
+            break;
+        case HI_STYLE_CLEAN:
+            style = "Clean";
+            break;
+        case HI_STYLE_NORMAL:
+        default:
+        style = "Normal";
     }
 
     send_message(user, nickserv, "NSMSG_SET_STYLE", style);
     return 1;
 }
-*/
 
 static OPTION_FUNC(opt_announcements)
 {
@@ -2654,7 +2763,7 @@ static OPTION_FUNC(opt_email)
 {
     if (argc > 1) {
         const char *str;
-        if (!is_valid_email_addr(argv[1])) {
+        if (!valid_email(argv[1])) {
             send_message(user, nickserv, "NSMSG_BAD_EMAIL_ADDR");
             return 0;
         }
@@ -3098,6 +3207,8 @@ nickserv_saxdb_write(struct saxdb_context *ctx) {
         saxdb_write_int(ctx, KEY_LAST_SEEN, hi->lastseen);
         if (hi->masks->used)
             saxdb_write_string_list(ctx, KEY_MASKS, hi->masks);
+        if (hi->ignores->used)
+            saxdb_write_string_list(ctx, KEY_IGNORES, hi->ignores);
         if (hi->maxlogins)
             saxdb_write_int(ctx, KEY_MAXLOGINS, hi->maxlogins);
         if (hi->nicks) {
@@ -3125,6 +3236,7 @@ nickserv_saxdb_write(struct saxdb_context *ctx) {
         saxdb_write_string(ctx, KEY_USERLIST_STYLE, flags);
         saxdb_end_record(ctx);
     }
+
     return 0;
 }
 
@@ -3189,6 +3301,16 @@ static NICKSERV_FUNC(cmd_merge)
             string_list_append(hi_to->masks, strdup(mask));
     }
 
+    /* Merge the ignores. */
+    for (ii=0; ii<hi_from->ignores->used; ii++) {
+        char *ignore = hi_from->ignores->list[ii];
+        for (jj=0; jj<hi_to->ignores->used; jj++)
+            if (match_ircglobs(hi_to->ignores->list[jj], ignore))
+                break;
+        if (jj==hi_to->ignores->used) /* Nothing from the "to" handle covered this mask, so add it. */
+            string_list_append(hi_to->ignores, strdup(ignore));
+    }
+
     /* Merge the lists of authed users. */
     if (hi_to->users) {
         for (last_user=hi_to->users; last_user->next_authed; last_user=last_user->next_authed) ;
@@ -3597,7 +3719,7 @@ static void
 nickserv_db_read_handle(const char *handle, dict_t obj)
 {
     const char *str;
-    struct string_list *masks, *slist;
+    struct string_list *masks, *slist, *ignores;
     struct handle_info *hi;
     struct userNode *authed_users;
     struct userData *channels;
@@ -3635,6 +3757,8 @@ nickserv_db_read_handle(const char *handle, dict_t obj)
     hi->channels = channels;
     masks = database_get_data(obj, KEY_MASKS, RECDB_STRING_LIST);
     hi->masks = masks ? string_list_copy(masks) : 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);
     hi->maxlogins = str ? strtoul(str, NULL, 0) : 0;
     str = database_get_data(obj, KEY_LANGUAGE, RECDB_QSTRING);
@@ -3661,7 +3785,7 @@ nickserv_db_read_handle(const char *handle, dict_t obj)
             hi->flags |= 1 << (handle_inverse_flags[(unsigned char)str[ii]] - 1);
     }
     str = database_get_data(obj, KEY_USERLIST_STYLE, RECDB_QSTRING);
-    hi->userlist_style = str ? str[0] : HI_STYLE_ZOOT;
+    hi->userlist_style = str ? str[0] : HI_DEFAULT_STYLE;
     str = database_get_data(obj, KEY_ANNOUNCEMENTS, RECDB_QSTRING);
     hi->announcements = str ? str[0] : '?';
     str = database_get_data(obj, KEY_SCREEN_WIDTH, RECDB_QSTRING);
@@ -3972,6 +4096,9 @@ nickserv_conf_read(void)
     str = database_get_data(conf_node, KEY_TITLEHOST_SUFFIX, RECDB_QSTRING);
     nickserv_conf.titlehost_suffix = str ? str : "example.net";
 
+    str = database_get_data(conf_node, KEY_DEFAULT_STYLE, RECDB_QSTRING);
+    nickserv_conf.default_style = str ? str[0] : HI_DEFAULT_STYLE;
+
     str = database_get_data(conf_node, KEY_AUTO_OPER, RECDB_QSTRING);
     nickserv_conf.auto_oper = str ? str : "";
 
@@ -4181,6 +4308,7 @@ init_nickserv(const char *nick)
     conf_register_reload(nickserv_conf_read);
     nickserv_opt_dict = dict_new();
     nickserv_email_dict = dict_new();
+
     dict_set_free_keys(nickserv_email_dict, free);
     dict_set_free_data(nickserv_email_dict, nickserv_free_email_addr);
 
@@ -4225,6 +4353,11 @@ init_nickserv(const char *nick)
         dict_insert(nickserv_opt_dict, "EMAIL", opt_email);
     }
     nickserv_define_func("GHOST", cmd_ghost, -1, 1, 0);
+    /* ignore commands */
+    nickserv_define_func("ADDIGNORE", cmd_addignore, -1, 1, 0);
+    nickserv_define_func("OADDIGNORE", cmd_oaddignore, 0, 1, 0);
+    nickserv_define_func("DELIGNORE", cmd_delignore, -1, 1, 0);
+    nickserv_define_func("ODELIGNORE", cmd_odelignore, 0, 1, 0);
     /* miscellaneous commands */
     nickserv_define_func("STATUS", cmd_status, -1, 0, 0);
     nickserv_define_func("SEARCH", cmd_search, 100, 1, 0);
@@ -4238,7 +4371,7 @@ init_nickserv(const char *nick)
     dict_insert(nickserv_opt_dict, "COLOR", opt_color);
     dict_insert(nickserv_opt_dict, "PRIVMSG", opt_privmsg);
     dict_insert(nickserv_opt_dict, "AUTOHIDE", opt_autohide);
-/*    dict_insert(nickserv_opt_dict, "STYLE", opt_style); */
+    dict_insert(nickserv_opt_dict, "STYLE", opt_style); 
     dict_insert(nickserv_opt_dict, "PASS", opt_password);
     dict_insert(nickserv_opt_dict, "PASSWORD", opt_password);
     dict_insert(nickserv_opt_dict, "FLAGS", opt_flags);