]> jfr.im git - irc/evilnet/x3.git/blobdiff - src/proto-p10.c
Changed "sslfp" to "certfp" and "SSL fingerprint" to "client certificate fingerprint...
[irc/evilnet/x3.git] / src / proto-p10.c
index 7505d587cf911b0c6cab898800812c52243acb75..731b1cf7d477028158f0f6fba94e2e17b64600cb 100644 (file)
 #define CMD_SVSPART             "SVSPART"
 #define CMD_SVSQUIT             "SVSQUIT"
 #define CMD_SWHOIS              "SWHOIS"
+#define CMD_TEMPSHUN            "TEMPSHUN"
 #define CMD_TIME                "TIME"
 #define CMD_TOPIC               "TOPIC"
 #define CMD_TRACE               "TRACE"
 #define TOK_SVSPART             "SP"
 #define TOK_SVSQUIT             "SX"
 #define TOK_SWHOIS              "SW"
+#define TOK_TEMPSHUN            "TS"
 #define TOK_TIME                "TI"
 #define TOK_TOPIC               "T"
 #define TOK_TRACE               "TR"
 #define P10_SVSPART             TYPE(SVSPART)
 #define P10_SVSQUIT            TYPE(SVSQUIT)
 #define P10_SWHOIS              TYPE(SWHOIS)
+#define P10_TEMPSHUN            TYPE(TEMPSHUN)
 #define P10_TIME                TYPE(TIME)
 #define P10_TOPIC               TYPE(TOPIC)
 #define P10_TRACE               TYPE(TRACE)
@@ -837,8 +840,8 @@ irc_gline(struct server *srv, struct gline *gline, int silent)
 void
 irc_shun(struct server *srv, struct shun *shun)
 {
-    putsock("%s " P10_SHUN " %s +%s " FMT_TIME_T " :<%s> %s",
-            self->numeric, (srv ? srv->numeric : "*"), shun->target, shun->expires-now, shun->issuer, shun->reason);
+    putsock("%s " P10_SHUN " %s +%s " FMT_TIME_T " " FMT_TIME_T " :<%s> %s",
+            self->numeric, (srv ? srv->numeric : "*"), shun->target, shun->expires-now, now, shun->issuer, shun->reason);
 }
 
 void
@@ -859,7 +862,7 @@ irc_ungline(const char *mask)
 void
 irc_unshun(const char *mask)
 {
-    putsock("%s " P10_SHUN " * -%s", self->numeric, mask);
+    putsock("%s " P10_SHUN " * -%s " FMT_TIME_T, self->numeric, mask, now);
 }
 
 void
@@ -1092,6 +1095,12 @@ irc_swhois(struct userNode *from, struct userNode *target, const char *message)
 
 }
 
+void
+irc_tempshun(struct userNode *from, struct userNode *target, int remove, const char *reason)
+{
+    putsock("%s " P10_TEMPSHUN " %s %s :%s", from->numeric, (remove ? "-" : "+"), target->numeric, reason);
+}
+
 void
 irc_part(struct userNode *who, struct chanNode *what, const char *reason)
 {
@@ -1181,6 +1190,34 @@ void
 irc_mark(struct userNode *user, char *mark)
 {
     char *host = user->hostname;
+    int type = 4;
+    const char *tstr = NULL;
+    unsigned int ii = 0;
+    int markfound = 0;
+
+    tstr = conf_get_data("server/type", RECDB_QSTRING);
+    if(tstr)
+        type = atoi(tstr);
+    else
+        type = 4;
+
+    if (user->marks)
+        for (ii=0; ii<user->marks->used; ii++)
+            if (!irccasecmp(user->marks->list[ii], mark))
+                markfound = 1;
+
+    if (!markfound)
+    {
+        if (!user->marks)
+            user->marks = alloc_string_list(1);
+        string_list_append(user->marks, strdup(mark));
+    }
+
+    if (type >= 9)
+    {
+        putsock("%s " CMD_MARK " %s MARK %s", self->numeric, user->nick, mark);
+        return;
+    }
 
     /* TODO: Allow mark overwrite. If they are marked, and their fakehost is oldmark.hostname, update it to newmark.hostname so mark can be called multiple times. Probably requires ircd modification also */
     if(user->mark)
@@ -1463,7 +1500,7 @@ static CMD_FUNC(cmd_sasl)
     if (!serv)
       return 0;
 
-    call_sasl_input_func(serv, argv[2], argv[3], argv[4], (argc>5 ? argv[5] : NULL));
+    call_sasl_input_func(serv, argv[2], argv[3], argv[4], (argc>5 ? argv[argc-1] : NULL));
 
     return 1;
 }
@@ -1702,7 +1739,8 @@ static struct {
   P(SHUN),           P(LOCAL_SHUN),     P(WIDE_SHUN),     P(ZLINE),
   P(LOCAL_ZLINE),    P(WIDE_ZLINE),     P(LIST_CHAN),     P(WHOIS_NOTICE),
   P(HIDE_IDLE),      P(XTRAOP),         P(HIDE_CHANNELS), P(DISPLAY_MODE),
-  P(FREEFORM),       P(REMOVE),         P(SPAMFILTER),
+  P(FREEFORM),       P(REMOVE),         P(SPAMFILTER),    P(ADMIN),
+  P(APASS_OPMODE),   P(HIDE_OPER),      P(REMOTE),        P(SERVICE),
 #undef P
   { 0, 0 }
 };
@@ -1972,33 +2010,55 @@ static CMD_FUNC(cmd_burst)
     return res;
 }
 
-/* TODO: 
+/* TODO:
  * This is a stub that doesn't actually do anything. It should be completed
  * so that bans on *!*@markname.* match users as it does in nefarious
  */
 static CMD_FUNC(cmd_mark)
 {
+    const char *tstr;
+    int type = 4;
     struct userNode *target;
-    /* 
+    /*
      * log_module(MAIN_LOG, LOG_ERROR, "DEBUG: mark, user %s, type %s, arg %s", argv[1], argv[2], argv[3]);
      */
 
+    tstr = conf_get_data("server/type", RECDB_QSTRING);
+    if(tstr)
+       type = atoi(tstr);
+    else
+       type = 4;/* default to 040 style topics */
+
     if(argc < 4)
         return 0;
     if(!strcasecmp(argv[2], "DNSBL")) {
         /* DNSBL <modes> */
         return 1;
     }
-    else if(!strcasecmp(argv[2], "DNSBL_DATA")) {
+    else if(!strcasecmp(argv[2], "DNSBL_DATA") || !strcasecmp(argv[2], "MARK")) {
+        int markfound = 0;
+        unsigned int ii = 0;
         /* DNSBL_DATA name */
         target = GetUserH(argv[1]);
         if(!target) {
             log_module(MAIN_LOG, LOG_ERROR, "Unable to find user %s whose dnsbl mark is changing.", argv[1]);
             return 0;
         }
-        target->mark = strdup(argv[3]);
+        if (type >= 9) {
+            if (target->marks)
+                for (ii=0; ii<target->marks->used; ii++)
+                    if (!irccasecmp(target->marks->list[ii], argv[3]))
+                         markfound = 1;
+            if (!markfound)
+            {
+                if (!target->marks)
+                    target->marks = alloc_string_list(1);
+                string_list_append(target->marks, strdup(argv[3]));
+            }
+        } else
+            target->mark = strdup(argv[3]);
         return 1;
-        
+
     }
     else if(!strcasecmp(argv[2], "CVERSION")) {
         /* CTCP VERSION mark */
@@ -2313,7 +2373,15 @@ static CMD_FUNC(cmd_silence)
     if (argc < 2)
         return 0;
 
-    user = GetUserN(argv[1]);
+    if (strncmp(argv[1], "*", 2) == 0)
+    {
+        if (!(user = GetUserH(origin))) {
+            log_module(MAIN_LOG, LOG_ERROR, "Could not find SILENCE origin user %s", origin);
+            return 0;
+        }
+    }
+    else
+        user = GetUserN(argv[1]);
 
     /* Sanity, go nuts if this happens */
     if (!user)
@@ -2679,6 +2747,8 @@ init_parse(void)
     dict_insert(irc_func_dict, TOK_SVSPART, cmd_svspart);
     dict_insert(irc_func_dict, CMD_SWHOIS, cmd_dummy);
     dict_insert(irc_func_dict, TOK_SWHOIS, cmd_dummy);
+    dict_insert(irc_func_dict, CMD_TEMPSHUN, cmd_dummy);
+    dict_insert(irc_func_dict, TOK_TEMPSHUN, cmd_dummy);
     dict_insert(irc_func_dict, CMD_WHOIS, cmd_whois);
     dict_insert(irc_func_dict, TOK_WHOIS, cmd_whois);
     dict_insert(irc_func_dict, CMD_GLINE, cmd_gline);
@@ -3027,7 +3097,7 @@ AddLocalUser(const char *nick, const char *ident, const char *hostname, const ch
     if (!hostname)
         hostname = self->name;
     make_numeric(self, local_num, numeric);
-    return AddUser(self, nick, ident, hostname, modes, numeric, desc, now, "AAAAAA");
+    return AddUser(self, nick, ident, hostname, modes, numeric, desc, timestamp, "AAAAAA");
 }
 
 struct userNode *
@@ -3199,8 +3269,11 @@ DelUser(struct userNode* user, struct userNode *killer, int announce, const char
 
     user->uplink->clients--;
     user->uplink->users[user->num_local] = NULL;
-    if (IsOper(user))
+    if (IsOper(user)) {
         userList_remove(&curr_opers, user);
+        if (count_opers > 0 && !IsBotM(user) && !IsService(user) && !IsHideOper(user))
+          count_opers--;
+    }
     /* remove from global dictionary, but not if after a collide */
     if (user == dict_find(clients, user->nick, NULL))
         dict_remove(clients, user->nick);
@@ -3242,6 +3315,8 @@ DelUser(struct userNode* user, struct userNode *killer, int announce, const char
         free(user->mark);
         user->mark = NULL;
     }
+    free_string_list(user->marks);
+    user->marks = NULL;
 
     /* clean up geoip data if any */
     if(user->country_code) free(user->country_code);
@@ -3263,6 +3338,8 @@ static void call_oper_funcs(struct userNode *user);
 
 void mod_usermode(struct userNode *user, const char *mode_change) {
     int add = 1;
+    long setmodes = 0;
+    int donemodes = 0;
     const char *word = mode_change;
 
     if (!user || !mode_change)
@@ -3270,12 +3347,16 @@ void mod_usermode(struct userNode *user, const char *mode_change) {
 
     call_user_mode_funcs(user, mode_change);
 
+    setmodes = user->modes;
+
     while (*word != ' ' && *word) word++;
     while (*word == ' ') word++;
-    while (1) {
+    while (!donemodes) {
 #define do_user_mode(FLAG) do { if (add) user->modes |= FLAG; else user->modes &= ~FLAG; } while (0)
        switch (*mode_change++) {
-       case 0: case ' ': return;
+       case 0: case ' ':
+            donemodes = 1;
+            break;
        case '+': add = 1; break;
        case '-': add = 0; break;
        case 'o':
@@ -3300,6 +3381,7 @@ void mod_usermode(struct userNode *user, const char *mode_change) {
        case 'g': do_user_mode(FLAGS_GLOBAL); break;
        case 'B': do_user_mode(FLAGS_BOT); break;
        case 'n': do_user_mode(FLAGS_HIDECHANS); break;
+    case 'p': do_user_mode(FLAGS_HIDECHANS); break;
        case 'I': do_user_mode(FLAGS_HIDEIDLE); break;
        case 'X': do_user_mode(FLAGS_XTRAOP); break;
        case 'C': do_user_mode(FLAGS_CLOAKHOST);
@@ -3378,6 +3460,37 @@ void mod_usermode(struct userNode *user, const char *mode_change) {
        }
 #undef do_user_mode
     }
+
+    // Set user mode +o
+    if (!(setmodes & FLAGS_OPER) && IsOper(user)) {
+        if (!IsBotM(user) && !IsService(user) && !IsHideOper(user))
+            count_opers++;
+    }
+
+    // Set user mode -o
+    if ((setmodes & FLAGS_OPER) && !IsOper(user)) {
+        if (count_opers > 1 && !(setmodes & FLAGS_BOT) &&
+            !(setmodes & FLAGS_SERVICE) && !(setmodes & FLAGS_HIDEOPER))
+            count_opers--;
+    }
+
+    // Set +H, +k or +B
+    if (!(setmodes & FLAGS_HIDEOPER) &&
+        !(setmodes & FLAGS_SERVICE) &&
+        !(setmodes & FLAGS_BOT) &&
+        (IsHideOper(user) || IsService(user) || IsBotM(user))) {
+        if ((setmodes & FLAGS_OPER) && IsOper(user) && count_opers > 0)
+              count_opers--;
+    }
+
+    // Set -H, -k or -B
+    if (((setmodes & FLAGS_HIDEOPER) ||
+         (setmodes & FLAGS_SERVICE) ||
+         (setmodes & FLAGS_BOT)) &&
+        !IsHideOper(user) && !IsService(user) && !IsBotM(user)) {
+        if ((setmodes & FLAGS_OPER) && IsOper(user))
+            count_opers++;
+    }
 }
 
 static int