unrealircd- supernets unrealircd source & configuration |
git clone git://git.acid.vegas/unrealircd.git |
Log | Files | Refs | Archive | README | LICENSE |
unrealircdctl.c (6899B)
1 /************************************************************************ 2 * UnrealIRCd - Unreal Internet Relay Chat Daemon - src/unrealircdctl 3 * (c) 2022- Bram Matthys and The UnrealIRCd team 4 * 5 * See file AUTHORS in IRC package for additional names of 6 * the programmers. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 1, or (at your option) 11 * any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 23 /** @file 24 * @brief UnrealIRCd Control 25 */ 26 #include "unrealircd.h" 27 28 #ifdef _WIN32 29 #define UNREALCMD "unrealircdctl" 30 #else 31 #define UNREALCMD "./unrealircd" 32 #endif 33 34 35 extern int procio_client(const char *command, int auto_color_logs); 36 37 void unrealircdctl_usage(const char *program_name) 38 { 39 printf("Usage: %s <option>\n" 40 "Where <option> is one of:\n" 41 "rehash - Rehash the server (reread configuration files)\n" 42 "reloadtls - Reload the SSL/TLS certificates\n" 43 "status - Show current status of server\n" 44 "module-status - Show currently loaded modules\n" 45 "mkpasswd - Hash a password\n" 46 "gencloak - Display 3 random cloak keys\n" 47 "spkifp - Display SPKI Fingerprint\n" 48 "\n", program_name); 49 exit(-1); 50 } 51 52 void unrealircdctl_rehash(void) 53 { 54 if (procio_client("REHASH", 1) == 0) 55 { 56 printf("Rehashed succesfully.\n"); 57 exit(0); 58 } 59 printf("Rehash failed.\n"); 60 exit(1); 61 } 62 63 void unrealircdctl_reloadtls(void) 64 { 65 if (procio_client("REHASH -tls", 1) == 0) 66 { 67 printf("Reloading of TLS certificates successful.\n"); 68 exit(0); 69 } 70 printf("Reloading TLS certificates failed.\n"); 71 exit(1); 72 } 73 74 void unrealircdctl_status(void) 75 { 76 if (procio_client("STATUS", 2) == 0) 77 { 78 printf("UnrealIRCd is up and running.\n"); 79 exit(0); 80 } 81 printf("UnrealIRCd status report failed.\n"); 82 exit(1); 83 } 84 85 void unrealircdctl_module_status(void) 86 { 87 if (procio_client("MODULES", 2) == 0) 88 exit(0); 89 printf("Could not retrieve complete module list.\n"); 90 exit(1); 91 } 92 93 void unrealircdctl_mkpasswd(int argc, char *argv[]) 94 { 95 AuthenticationType type; 96 const char *result; 97 char *p = argv[2]; 98 99 type = Auth_FindType(NULL, p); 100 if (type == -1) 101 { 102 type = AUTHTYPE_ARGON2; 103 } else { 104 p = argv[3]; 105 } 106 if (BadPtr(p)) 107 { 108 #ifndef _WIN32 109 p = getpass("Enter password to hash: "); 110 #else 111 printf("ERROR: You should specify a password to hash"); 112 exit(1); 113 #endif 114 } 115 if ((type == AUTHTYPE_UNIXCRYPT) && (strlen(p) > 8)) 116 { 117 /* Hmmm.. is this warning really still true (and always) ?? */ 118 printf("WARNING: Password truncated to 8 characters due to 'crypt' algorithm. " 119 "You are suggested to use the 'argon2' algorithm instead."); 120 p[8] = '\0'; 121 } 122 if (!(result = Auth_Hash(type, p))) { 123 printf("Failed to generate password. Deprecated method? Try 'argon2' instead.\n"); 124 exit(0); 125 } 126 printf("Encrypted password is: %s\n", result); 127 exit(0); 128 } 129 130 void unrealircdctl_gencloak(int argc, char *argv[]) 131 { 132 #define GENERATE_CLOAKKEY_LEN 80 /* Length of cloak keys to generate. */ 133 char keyBuf[GENERATE_CLOAKKEY_LEN + 1]; 134 int keyNum; 135 int charIndex; 136 137 short has_upper; 138 short has_lower; 139 short has_num; 140 141 printf("Here are 3 random cloak keys that you can copy-paste to your configuration file:\n\n"); 142 143 printf("set {\n\tcloak-keys {\n"); 144 for (keyNum = 0; keyNum < 3; ++keyNum) 145 { 146 has_upper = 0; 147 has_lower = 0; 148 has_num = 0; 149 150 for (charIndex = 0; charIndex < sizeof(keyBuf)-1; ++charIndex) 151 { 152 switch (getrandom8() % 3) 153 { 154 case 0: /* Uppercase. */ 155 keyBuf[charIndex] = (char)('A' + (getrandom8() % ('Z' - 'A'))); 156 has_upper = 1; 157 break; 158 case 1: /* Lowercase. */ 159 keyBuf[charIndex] = (char)('a' + (getrandom8() % ('z' - 'a'))); 160 has_lower = 1; 161 break; 162 case 2: /* Digit. */ 163 keyBuf[charIndex] = (char)('0' + (getrandom8() % ('9' - '0'))); 164 has_num = 1; 165 break; 166 } 167 } 168 keyBuf[sizeof(keyBuf)-1] = '\0'; 169 170 if (has_upper && has_lower && has_num) 171 printf("\t\t\"%s\";\n", keyBuf); 172 else 173 /* Try again. For this reason, keyNum must be signed. */ 174 keyNum--; 175 } 176 printf("\t}\n}\n\n"); 177 exit(0); 178 } 179 180 void unrealircdctl_spkifp(int argc, char *argv[]) 181 { 182 char *file = argv[2]; 183 SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method()); 184 SSL *ssl; 185 X509 *cert; 186 const char *spkifp; 187 188 if (!ctx) 189 { 190 printf("Internal failure while initializing SSL/TLS library context\n"); 191 exit(1); 192 } 193 194 if (!file) 195 { 196 printf("NOTE: This script uses the default certificate location (any set::tls settings\n" 197 "are ignored). If this is not what you want then specify a certificate\n" 198 "explicitly like this: %s spkifp conf/tls/example.pem\n\n", UNREALCMD); 199 safe_strdup(file, "tls/server.cert.pem"); 200 convert_to_absolute_path(&file, CONFDIR); 201 } 202 203 if (!file_exists(file)) 204 { 205 printf("Could not open certificate: %s\n" 206 "You can specify a certificate like this: %s spkifp conf/tls/example.pem\n", 207 UNREALCMD, file); 208 exit(1); 209 } 210 211 if (SSL_CTX_use_certificate_chain_file(ctx, file) <= 0) 212 { 213 printf("Could not read certificate '%s'\n", file); 214 exit(1); 215 } 216 217 ssl = SSL_new(ctx); 218 if (!ssl) 219 { 220 printf("Something went wrong when generating the SPKI fingerprint.\n"); 221 exit(1); 222 } 223 224 cert = SSL_get_certificate(ssl); 225 spkifp = spki_fingerprint_ex(cert); 226 printf("The SPKI fingerprint for certificate '%s' is:\n" 227 "%s\n" 228 "\n" 229 "You normally add this password on the other side of the link as:\n" 230 "password \"%s\" { spkifp; };\n" 231 "\n", 232 file, spkifp, spkifp); 233 exit(0); 234 } 235 236 int main(int argc, char *argv[]) 237 { 238 #ifdef _WIN32 239 chdir(".."); /* go up one level from "bin" */ 240 init_winsock(); 241 #else 242 alarm(20); /* 20 second timeout */ 243 #endif 244 dbuf_init(); 245 init_random(); 246 early_init_tls(); 247 248 if (argc == 1) 249 unrealircdctl_usage(argv[0]); 250 251 if (!strcmp(argv[1], "rehash")) 252 unrealircdctl_rehash(); 253 else if (!strcmp(argv[1], "reloadtls")) 254 unrealircdctl_reloadtls(); 255 else if (!strcmp(argv[1], "status")) 256 unrealircdctl_status(); 257 else if (!strcmp(argv[1], "module-status")) 258 unrealircdctl_module_status(); 259 else if (!strcmp(argv[1], "mkpasswd")) 260 unrealircdctl_mkpasswd(argc, argv); 261 else if (!strcmp(argv[1], "gencloak")) 262 unrealircdctl_gencloak(argc, argv); 263 else if (!strcmp(argv[1], "spkifp") || !strcmp(argv[1], "spki")) 264 unrealircdctl_spkifp(argc, argv); 265 else 266 unrealircdctl_usage(argv[0]); 267 exit(0); 268 }