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 }