1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-06-12 19:14:46 +02:00

You can now use "password" multiple times in the conf (eg in allow::password).

allow {
	mask *;
	password "secret";
	password "letmein";
}

This is always an "OR" type of match, any match means you pass.

I was actually doing this for the dual-cert stuff from previous commit,
where this can come in handy:

link irc1.example.org {
...
    password "AHMYBevUxXKU/S3pdBSjXP4zi4VOetYQQVJXoNYiBR0=" { spkifp; };
    password "jNw8P4QMg9tqjEJ4/lFikXBNHdIGSeN2B4/T322VjIo=" { spkifp; };
...
}
This commit is contained in:
Bram Matthys
2025-09-21 11:31:31 +02:00
parent 877d151da4
commit 4c6e259681
6 changed files with 78 additions and 73 deletions
+1 -1
View File
@@ -538,7 +538,7 @@ extern int b64_encode(unsigned char const *src, size_t srclength, char *target,
extern int b64_decode(char const *src, unsigned char *target, size_t targsize);
extern AuthenticationType Auth_FindType(const char *hash, const char *type);
extern AuthConfig *AuthBlockToAuthConfig(ConfigEntry *ce);
extern void AuthBlockToAuthConfig(ConfigEntry *ce, AuthConfig **list);
extern void Auth_FreeAuthConfig(AuthConfig *as);
extern int Auth_Check(Client *cptr, AuthConfig *as, const char *para);
extern const char *Auth_Hash(AuthenticationType type, const char *text);
+1
View File
@@ -1638,6 +1638,7 @@ typedef struct AuthConfig AuthConfig;
* configuration file.
*/
struct AuthConfig {
AuthConfig *prev, *next;
AuthenticationType type; /**< Type of data, one of AUTHTYPE_* */
char *data; /**< Data associated with this record */
};
+56 -37
View File
@@ -265,7 +265,7 @@ int Auth_CheckError(ConfigEntry *ce, int warn_on_plaintext)
/** Convert an authentication block from the configuration file
* into an AuthConfig structure so it can be used at runtime.
*/
AuthConfig *AuthBlockToAuthConfig(ConfigEntry *ce)
void AuthBlockToAuthConfig(ConfigEntry *ce, AuthConfig **list)
{
AuthenticationType type = AUTHTYPE_PLAINTEXT;
AuthConfig *as = NULL;
@@ -277,14 +277,17 @@ AuthConfig *AuthBlockToAuthConfig(ConfigEntry *ce)
as = safe_alloc(sizeof(AuthConfig));
safe_strdup(as->data, ce->value);
as->type = type;
return as;
AddListItem(as, *list);
}
/** Free an AuthConfig struct */
void Auth_FreeAuthConfig(AuthConfig *as)
{
if (as)
AuthConfig *as_next;
for (; as; as = as_next)
{
as_next = as->next;
safe_free(as->data);
safe_free(as);
}
@@ -448,48 +451,64 @@ int Auth_Check(Client *client, AuthConfig *as, const char *para)
if (!as || !as->data)
return 0; /* Should not happen, but better be safe.. */
switch (as->type)
for (; as; as = as->next)
{
case AUTHTYPE_PLAINTEXT:
if (!para)
return 0;
if (!strcmp(as->data, "changemeplease") && !strcmp(para, as->data))
{
unreal_log(ULOG_INFO, "auth", "AUTH_REJECT_DEFAULT_PASSWORD", client,
"Rejecting default password 'changemeplease'. "
"Please change the password in the configuration file.");
return 0;
}
/* plain text compare */
if (!strcmp(para, as->data))
return 1;
return 0;
switch (as->type)
{
case AUTHTYPE_PLAINTEXT:
if (!para)
return 0;
if (!strcmp(as->data, "changemeplease") && !strcmp(para, as->data))
{
unreal_log(ULOG_INFO, "auth", "AUTH_REJECT_DEFAULT_PASSWORD", client,
"Rejecting default password 'changemeplease'. "
"Please change the password in the configuration file.");
return 0;
}
/* plain text compare */
if (!strcmp(para, as->data))
return 1;
break;
case AUTHTYPE_ARGON2:
return authcheck_argon2(client, as, para);
case AUTHTYPE_ARGON2:
if (authcheck_argon2(client, as, para))
return 1;
break;
case AUTHTYPE_BCRYPT:
return authcheck_bcrypt(client, as, para);
case AUTHTYPE_BCRYPT:
if (authcheck_bcrypt(client, as, para))
return 1;
break;
case AUTHTYPE_UNIXCRYPT:
if (!para)
return 0;
res = crypt(para, as->data);
if (res && !strcmp(res, as->data))
return 1;
return 0;
case AUTHTYPE_UNIXCRYPT:
if (!para)
return 0;
res = crypt(para, as->data);
if (res && !strcmp(res, as->data))
return 1;
break;
case AUTHTYPE_TLS_CLIENTCERT:
return authcheck_tls_clientcert(client, as, para);
case AUTHTYPE_TLS_CLIENTCERT:
if (authcheck_tls_clientcert(client, as, para))
return 1;
break;
case AUTHTYPE_TLS_CLIENTCERTFP:
return authcheck_tls_clientcert_fingerprint(client, as, para);
case AUTHTYPE_TLS_CLIENTCERTFP:
if (authcheck_tls_clientcert_fingerprint(client, as, para))
return 1;
break;
case AUTHTYPE_SPKIFP:
return authcheck_spkifp(client, as, para);
case AUTHTYPE_SPKIFP:
if (authcheck_spkifp(client, as, para))
return 1;
break;
case AUTHTYPE_INVALID:
return 0; /* Should never happen */
case AUTHTYPE_INVALID:
#ifdef DEBUGMODE
abort();
#endif
break; /* Should never happen */
}
}
return 0;
}
+18 -33
View File
@@ -4247,7 +4247,7 @@ int _conf_oper(ConfigFile *conf, ConfigEntry *ce)
if (!strcmp(cep->name, "operclass"))
safe_strdup(oper->operclass, cep->value);
if (!strcmp(cep->name, "password"))
oper->auth = AuthBlockToAuthConfig(cep);
AuthBlockToAuthConfig(cep, &oper->auth);
else if (!strcmp(cep->name, "class"))
{
oper->class = find_class(cep->value);
@@ -4351,12 +4351,6 @@ int _test_oper(ConfigFile *conf, ConfigEntry *ce)
/* oper::password */
if (!strcmp(cep->name, "password"))
{
if (has_password)
{
config_warn_duplicate(cep->file->filename,
cep->line_number, "oper::password");
continue;
}
has_password = 1;
if (ce->value && cep->value &&
@@ -4567,12 +4561,6 @@ int _test_oper(ConfigFile *conf, ConfigEntry *ce)
}
else if (!strcmp(cep->name, "password"))
{
if (has_password)
{
config_warn_duplicate(cep->file->filename,
cep->line_number, "oper::password");
continue;
}
has_password = 1;
if (Auth_CheckError(cep, 1) < 0)
errors++;
@@ -4700,7 +4688,7 @@ int _test_proxy(ConfigFile *conf, ConfigEntry *ce)
} else
if (!strcmp(cep->name, "password"))
{
config_detect_duplicate(&has_password, cep, &errors);
has_password = 1;
if (Auth_CheckError(cep, 0) < 0)
errors++;
}
@@ -4785,7 +4773,7 @@ int _conf_proxy(ConfigFile *conf, ConfigEntry *ce)
if (!strcmp(cep->name, "mask") || !strcmp(cep->name, "match"))
conf_match_block(conf, cep, &proxy->mask);
else if (!strcmp(cep->name, "password"))
proxy->auth = AuthBlockToAuthConfig(cep);
AuthBlockToAuthConfig(cep, &proxy->auth);
else if (!strcmp(cep->name, "type"))
proxy->type = proxy_type_string_to_value(cep->value);
}
@@ -5076,19 +5064,9 @@ int _conf_drpass(ConfigFile *conf, ConfigEntry *ce)
for (cep = ce->items; cep; cep = cep->next)
{
if (!strcmp(cep->name, "restart"))
{
if (conf_drpass->restartauth)
Auth_FreeAuthConfig(conf_drpass->restartauth);
conf_drpass->restartauth = AuthBlockToAuthConfig(cep);
}
AuthBlockToAuthConfig(cep, &conf_drpass->restartauth);
else if (!strcmp(cep->name, "die"))
{
if (conf_drpass->dieauth)
Auth_FreeAuthConfig(conf_drpass->dieauth);
conf_drpass->dieauth = AuthBlockToAuthConfig(cep);
}
AuthBlockToAuthConfig(cep, &conf_drpass->dieauth);
}
return 1;
}
@@ -5940,7 +5918,7 @@ int _conf_allow(ConfigFile *conf, ConfigEntry *ce)
conf_match_block(conf, cep, &allow->match);
}
else if (!strcmp(cep->name, "password"))
allow->auth = AuthBlockToAuthConfig(cep);
AuthBlockToAuthConfig(cep, &allow->auth);
else if (!strcmp(cep->name, "class"))
{
allow->class = find_class(cep->value);
@@ -6146,8 +6124,7 @@ int _test_allow(ConfigFile *conf, ConfigEntry *ce)
}
else if (!strcmp(cep->name, "password"))
{
config_detect_duplicate(&has_password, cep, &errors);
/* some auth check stuff? */
has_password = 1;
if (Auth_CheckError(cep, 0) < 0)
errors++;
}
@@ -6614,7 +6591,7 @@ int _conf_link(ConfigFile *conf, ConfigEntry *ce)
}
}
else if (!strcmp(cep->name, "password"))
link->auth = AuthBlockToAuthConfig(cep);
AuthBlockToAuthConfig(cep, &link->auth);
else if (!strcmp(cep->name, "hub"))
safe_strdup(link->hub, cep->value);
else if (!strcmp(cep->name, "leaf"))
@@ -6795,12 +6772,13 @@ int _test_link(ConfigFile *conf, ConfigEntry *ce)
}
else if (!strcmp(cep->name, "password"))
{
config_detect_duplicate(&has_password, cep, &errors);
has_password = 1;
if (Auth_CheckError(cep, 0) < 0)
{
errors++;
} else {
AuthConfig *auth = AuthBlockToAuthConfig(cep);
AuthConfig *auth;
AuthBlockToAuthConfig(cep, &auth);
/* hm. would be nicer if handled @auth-system I think. ah well.. */
if ((auth->type != AUTHTYPE_PLAINTEXT) && (auth->type != AUTHTYPE_TLS_CLIENTCERT) &&
(auth->type != AUTHTYPE_TLS_CLIENTCERTFP) && (auth->type != AUTHTYPE_SPKIFP))
@@ -10915,6 +10893,13 @@ int _test_secret(ConfigFile *conf, ConfigEntry *ce)
if (!strcmp(cep->name, "password"))
{
int n;
if (has_password)
{
config_error("%s:%d: you can only have one password here",
cep->file->filename, cep->line_number);
errors++;
continue;
}
has_password = 1;
CheckNull(cep);
if (cep->items ||
+1 -1
View File
@@ -474,7 +474,7 @@ int rpc_config_run_rpc_user(ConfigFile *cf, ConfigEntry *ce, int type)
} else
if (!strcmp(cep->name, "password"))
{
e->auth = AuthBlockToAuthConfig(cep);
AuthBlockToAuthConfig(cep, &e->auth);
} else
if (!strcmp(cep->name, "rpc-class"))
{
+1 -1
View File
@@ -282,7 +282,7 @@ int vhost_config_run(ConfigFile *conf, ConfigEntry *ce, int type)
else if (!strcmp(cep->name, "login"))
safe_strdup(vhost->login, cep->value);
else if (!strcmp(cep->name, "password"))
vhost->auth = AuthBlockToAuthConfig(cep);
AuthBlockToAuthConfig(cep, &vhost->auth);
else if (!strcmp(cep->name, "match") || !strcmp(cep->name, "mask"))
{
conf_match_block(conf, cep, &vhost->match);