added Channel Mode +S (SSL): Only allow SSL Users joining the channel
[ircu2.10.12-pk.git] / ircd / channel.c
index 30b9f1de6d3864cf78b71756416c9190184b3d81..e22935c4c10c585a0c8ef348938a1a7dce68dd8b 100644 (file)
@@ -374,7 +374,7 @@ struct Membership* find_channel_member(struct Client* cptr, struct Channel* chpt
  * @param[in] banlist The list of bans to test.
  * @return Pointer to a matching ban, or NULL if none exit.
  */
-struct Ban *find_ban(struct Client *cptr, struct Ban *banlist)
+static struct Ban *find_ban_with_nick(struct Client *cptr, const char *nick, struct Ban *banlist)
 {
   char        nu[NICKLEN + USERLEN + 2];
   char        tmphost[HOSTLEN + 1];
@@ -386,7 +386,7 @@ struct Ban *find_ban(struct Client *cptr, struct Ban *banlist)
 
   /* Build nick!user and alternate host names. */
   ircd_snprintf(0, nu, sizeof(nu), "%s!%s",
-                cli_name(cptr), cli_user(cptr)->username);
+                (nick ? nick : cli_name(cptr)), cli_user(cptr)->username);
   ircd_ntoa_r(iphost, &cli_ip(cptr));
 
   /* Check for all three possible hosts:
@@ -439,6 +439,10 @@ struct Ban *find_ban(struct Client *cptr, struct Ban *banlist)
   return found;
 }
 
+struct Ban *find_ban(struct Client *cptr, struct Ban *banlist) {
+    return find_ban_with_nick(cptr, NULL, banlist);
+}
+
 /**
  * This function returns true if the user is banned on the said channel.
  * This function will check the ban cache if applicable, otherwise will
@@ -462,6 +466,13 @@ static int is_banned(struct Membership* member)
   }
 }
 
+static int is_banned_with_nick(struct Membership* member, const char *nick) {
+  if (find_ban_with_nick(member->user, nick, member->channel->banlist))
+    return 1;
+  else
+    return 0;
+}
+
 /** add a user to a channel.
  * adds a user to a channel by adding another link to the channels member
  * chain.
@@ -783,7 +794,8 @@ int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int r
    */
   if (!member) {
     if ((chptr->mode.mode & (MODE_NOPRIVMSGS|MODE_MODERATED)) ||
-       ((chptr->mode.mode & MODE_REGONLY) && !IsAccount(cptr)))
+       ((chptr->mode.mode & MODE_REGONLY) && !IsAccount(cptr)) ||
+    ((chptr->mode.mode & MODE_SSLCHAN) && !IsSSL(cptr)))
       return 0;
     else
       return !find_ban(cptr, chptr->banlist);
@@ -796,11 +808,12 @@ int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int r
  * the name of the first channel banned on.
  *
  * @param cptr         The client
+ * @param new_nick The new nick of the client
  *
  * @returns the name of the first channel banned on, or NULL if the user
  *          can change nicks.
  */
-const char* find_no_nickchange_channel(struct Client* cptr)
+const char* find_no_nickchange_channel(struct Client* cptr, const char *new_nick)
 {
   if (MyUser(cptr)) {
     struct Membership* member;
@@ -810,7 +823,8 @@ const char* find_no_nickchange_channel(struct Client* cptr)
         continue;
       if ((member->channel->mode.mode & MODE_MODERATED)
           || (member->channel->mode.mode & MODE_REGONLY && !IsAccount(cptr))
-          || is_banned(member))
+          || (member->channel->mode.mode & MODE_SSLCHAN && !IsSSL(cptr))
+          || is_banned(member) || (new_nick && is_banned_with_nick(member, new_nick)))
         return member->channel->chname;
     }
   }
@@ -877,6 +891,8 @@ void channel_modes(struct Client *cptr, char *mbuf, char *pbuf, int buflen,
     *mbuf++ = 'Q';
   if (chptr->mode.mode & MODE_AUDITORIUM)
     *mbuf++ = 'u';
+  if (chptr->mode.mode & MODE_SSLCHAN)
+    *mbuf++ = 'S';
   if (chptr->mode.limit) {
     *mbuf++ = 'l';
     ircd_snprintf(0, pbuf, buflen, "%u", chptr->mode.limit);
@@ -1594,6 +1610,7 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all)
        MODE_NONOTICE,  'N',
        MODE_QUARANTINE,  'Q',
        MODE_AUDITORIUM,  'u',
+    MODE_SSLCHAN,     'S',
     0x0, 0x0
   };
   static ulong64 local_flags[] = {
@@ -2035,7 +2052,7 @@ modebuf_mode(struct ModeBuf *mbuf, ulong64 mode)
           MODE_TOPICLIMIT | MODE_INVITEONLY | MODE_NOPRIVMSGS | MODE_REGONLY |
            MODE_DELJOINS | MODE_WASDELJOINS | MODE_REGISTERED | MODE_PERSIST |
            MODE_NOCOLOUR | MODE_NOCTCP | MODE_NOAMSGS | MODE_NONOTICE | 
-                  MODE_QUARANTINE | MODE_AUDITORIUM);
+                  MODE_QUARANTINE | MODE_AUDITORIUM | MODE_SSLCHAN);
 
   if (!(mode & ~(MODE_ADD | MODE_DEL))) /* don't add empty modes... */
     return;
@@ -2213,6 +2230,7 @@ modebuf_extract(struct ModeBuf *mbuf, char *buf)
        MODE_ALTCHAN,    'F',
        MODE_ACCESS,    'a',
        MODE_AUDITORIUM, 'u',
+    MODE_SSLCHAN,    'S',
        MODE_NOFLOOD,   'f',
     0x0, 0x0
   };
@@ -3747,6 +3765,7 @@ mode_parse(struct ModeBuf *mbuf, struct Client *cptr, struct Client *sptr,
        MODE_ALTCHAN,        'F',
     MODE_ACCESS,        'a',
        MODE_AUDITORIUM,    'u',
+    MODE_SSLCHAN,       'S',
        MODE_NOFLOOD,       'f',
     MODE_ADD,          '+',
     MODE_DEL,          '-',