unrealircd- supernets unrealircd source & configuration |
git clone git://git.acid.vegas/unrealircd.git |
Log | Files | Refs | Archive | README | LICENSE |
secureonly.c (5276B)
1 /* 2 * Only allow secure users to join UnrealIRCd Module (Channel Mode +z) 3 * (C) Copyright 2014 Travis McArthur (Heero) and the UnrealIRCd team 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 1, or (at your option) 8 * any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 */ 19 20 #include "unrealircd.h" 21 22 ModuleHeader MOD_HEADER 23 = { 24 "chanmodes/secureonly", 25 "4.2", 26 "Channel Mode +z", 27 "UnrealIRCd Team", 28 "unrealircd-6", 29 }; 30 31 Cmode_t EXTCMODE_SECUREONLY; 32 33 #define IsSecureOnly(channel) (channel->mode.mode & EXTCMODE_SECUREONLY) 34 35 int secureonly_check_join(Client *client, Channel *channel, const char *key, char **errmsg); 36 int secureonly_channel_sync (Channel *channel, int merge, int removetheirs, int nomode); 37 int secureonly_check_secure(Channel *channel); 38 int secureonly_check_sajoin(Client *target, Channel *channel, Client *requester); 39 int secureonly_pre_local_join(Client *client, Channel *channel, const char *key); 40 41 MOD_TEST() 42 { 43 return MOD_SUCCESS; 44 } 45 46 MOD_INIT() 47 { 48 CmodeInfo req; 49 50 memset(&req, 0, sizeof(req)); 51 req.paracount = 0; 52 req.letter = 'z'; 53 req.is_ok = extcmode_default_requirechop; 54 CmodeAdd(modinfo->handle, req, &EXTCMODE_SECUREONLY); 55 56 HookAdd(modinfo->handle, HOOKTYPE_PRE_LOCAL_JOIN, 0, secureonly_pre_local_join); 57 HookAdd(modinfo->handle, HOOKTYPE_CAN_JOIN, 0, secureonly_check_join); 58 HookAdd(modinfo->handle, HOOKTYPE_CHANNEL_SYNCED, 0, secureonly_channel_sync); 59 HookAdd(modinfo->handle, HOOKTYPE_IS_CHANNEL_SECURE, 0, secureonly_check_secure); 60 HookAdd(modinfo->handle, HOOKTYPE_CAN_SAJOIN, 0, secureonly_check_sajoin); 61 62 63 MARK_AS_OFFICIAL_MODULE(modinfo); 64 return MOD_SUCCESS; 65 } 66 67 MOD_LOAD() 68 { 69 return MOD_SUCCESS; 70 } 71 72 MOD_UNLOAD() 73 { 74 return MOD_SUCCESS; 75 } 76 77 78 /** Kicks all insecure users on a +z channel 79 * Returns 1 if the channel was destroyed as a result of this. 80 */ 81 static int secureonly_kick_insecure_users(Channel *channel) 82 { 83 Member *member, *mb2; 84 Client *client; 85 int i = 0; 86 Hook *h; 87 char *comment = "Insecure user not allowed on secure channel (+z)"; 88 89 if (!IsSecureOnly(channel)) 90 return 0; 91 92 for (member = channel->members; member; member = mb2) 93 { 94 mb2 = member->next; 95 client = member->client; 96 if (MyUser(client) && !IsSecureConnect(client) && !IsULine(client)) 97 { 98 char *prefix = NULL; 99 MessageTag *mtags = NULL; 100 101 if (invisible_user_in_channel(client, channel)) 102 { 103 /* Send only to chanops */ 104 prefix = "ho"; 105 } 106 107 new_message(&me, NULL, &mtags); 108 109 RunHook(HOOKTYPE_LOCAL_KICK, &me, &me, client, channel, mtags, comment); 110 111 sendto_channel(channel, &me, client, 112 prefix, 0, 113 SEND_LOCAL, mtags, 114 ":%s KICK %s %s :%s", 115 me.name, channel->name, client->name, comment); 116 117 sendto_prefix_one(client, &me, mtags, ":%s KICK %s %s :%s", me.name, channel->name, client->name, comment); 118 119 sendto_server(NULL, 0, 0, mtags, ":%s KICK %s %s :%s", me.id, channel->name, client->id, comment); 120 121 free_message_tags(mtags); 122 123 if (remove_user_from_channel(client, channel, 0) == 1) 124 return 1; /* channel was destroyed */ 125 } 126 } 127 return 0; 128 } 129 130 int secureonly_check_join(Client *client, Channel *channel, const char *key, char **errmsg) 131 { 132 Link *lp; 133 134 if (IsSecureOnly(channel) && !(client->umodes & UMODE_SECURE)) 135 { 136 if (ValidatePermissionsForPath("channel:override:secureonly",client,NULL,channel,NULL)) 137 { 138 /* if the channel is +z we still allow an ircop to bypass it 139 * if they are invited. 140 */ 141 if (is_invited(client, channel)) 142 return HOOK_CONTINUE; 143 } 144 *errmsg = STR_ERR_SECUREONLYCHAN; 145 return ERR_SECUREONLYCHAN; 146 } 147 return 0; 148 } 149 150 int secureonly_check_secure(Channel *channel) 151 { 152 if (IsSecureOnly(channel)) 153 { 154 return 1; 155 } 156 157 return 0; 158 } 159 160 int secureonly_channel_sync(Channel *channel, int merge, int removetheirs, int nomode) 161 { 162 if (!merge && !removetheirs && !nomode) 163 return secureonly_kick_insecure_users(channel); /* may return 1, meaning channel is destroyed */ 164 return 0; 165 } 166 167 int secureonly_check_sajoin(Client *target, Channel *channel, Client *requester) 168 { 169 if (IsSecureOnly(channel) && !IsSecure(target)) 170 { 171 sendnotice(requester, "You cannot SAJOIN %s to %s because the channel is +z and the user is not connected via TLS", 172 target->name, channel->name); 173 return HOOK_DENY; 174 } 175 176 return HOOK_CONTINUE; 177 } 178 179 /* Special check for +z in set::modes-on-join. Needs to be done early. 180 * Perhaps one day this will be properly handled in the core so this can be removed. 181 */ 182 int secureonly_pre_local_join(Client *client, Channel *channel, const char *key) 183 { 184 if ((channel->users == 0) && (MODES_ON_JOIN & EXTCMODE_SECUREONLY) && !IsSecure(client) && !IsOper(client)) 185 { 186 sendnumeric(client, ERR_SECUREONLYCHAN, channel->name); 187 return HOOK_DENY; 188 } 189 return HOOK_CONTINUE; 190 }