unrealircd- supernets unrealircd source & configuration |
git clone git://git.acid.vegas/unrealircd.git |
Log | Files | Refs | Archive | README | LICENSE |
certfp.c (3222B)
1 /* 2 * Extended ban to ban/exempt by certificate fingerprint (+b ~S:certfp) 3 * (C) Copyright 2015 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 #include "unrealircd.h" 20 21 ModuleHeader MOD_HEADER 22 = { 23 "extbans/certfp", 24 "4.2", 25 "ExtBan ~S - Ban/exempt by SHA256 TLS certificate fingerprint", 26 "UnrealIRCd Team", 27 "unrealircd-6", 28 }; 29 30 /* Forward declarations */ 31 int extban_certfp_is_ok(BanContext *b); 32 const char *extban_certfp_conv_param(BanContext *b, Extban *extban); 33 int extban_certfp_is_banned(BanContext *b); 34 35 Extban *register_certfp_extban(ModuleInfo *modinfo) 36 { 37 ExtbanInfo req; 38 39 memset(&req, 0, sizeof(req)); 40 req.letter = 'S'; 41 req.name = "certfp"; 42 req.is_ok = extban_certfp_is_ok; 43 req.conv_param = extban_certfp_conv_param; 44 req.is_banned = extban_certfp_is_banned; 45 req.is_banned_events = BANCHK_ALL|BANCHK_TKL; 46 req.options = EXTBOPT_INVEX|EXTBOPT_TKL; 47 return ExtbanAdd(modinfo->handle, req); 48 } 49 50 /* Called upon module test */ 51 MOD_TEST() 52 { 53 if (!register_certfp_extban(modinfo)) 54 { 55 config_error("could not register extended ban type"); 56 return MOD_FAILED; 57 } 58 59 return MOD_SUCCESS; 60 } 61 62 /* Called upon module init */ 63 MOD_INIT() 64 { 65 if (!register_certfp_extban(modinfo)) 66 { 67 config_error("could not register extended ban type"); 68 return MOD_FAILED; 69 } 70 71 MARK_AS_OFFICIAL_MODULE(modinfo); 72 73 return MOD_SUCCESS; 74 } 75 76 /* Called upon module load */ 77 MOD_LOAD() 78 { 79 return MOD_SUCCESS; 80 } 81 82 /* Called upon unload */ 83 MOD_UNLOAD() 84 { 85 return MOD_SUCCESS; 86 } 87 88 #define CERT_FP_LEN 64 89 90 int extban_certfp_usage(Client *client) 91 { 92 sendnotice(client, "ERROR: ExtBan ~S expects an SHA256 fingerprint in hexadecimal format (no colons). " 93 "For example: +e ~S:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef)"); 94 return EX_DENY; 95 } 96 97 int extban_certfp_is_ok(BanContext *b) 98 { 99 if (b->is_ok_check == EXCHK_PARAM) 100 { 101 const char *p; 102 103 if (strlen(b->banstr) != CERT_FP_LEN) 104 return extban_certfp_usage(b->client); 105 106 for (p = b->banstr; *p; p++) 107 if (!isxdigit(*p)) 108 return extban_certfp_usage(b->client); 109 110 return EX_ALLOW; 111 } 112 return EX_ALLOW; 113 } 114 115 /* Obtain targeted certfp from the ban string */ 116 const char *extban_certfp_conv_param(BanContext *b, Extban *extban) 117 { 118 static char retbuf[EVP_MAX_MD_SIZE * 2 + 1]; 119 char *p; 120 121 strlcpy(retbuf, b->banstr, sizeof(retbuf)); 122 123 for (p = retbuf; *p; p++) 124 { 125 *p = tolower(*p); 126 } 127 128 return retbuf; 129 } 130 131 int extban_certfp_is_banned(BanContext *b) 132 { 133 const char *fp = moddata_client_get(b->client, "certfp"); 134 135 if (!fp) 136 return 0; /* not using TLS */ 137 138 if (!strcmp(b->banstr, fp)) 139 return 1; 140 141 return 0; 142 }