Skip to content
8 changes: 4 additions & 4 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ AlignOperands: Align
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Always
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Always
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterReturnType: None
Expand All @@ -33,7 +33,7 @@ BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
ColumnLimit: 0
ColumnLimit: 80
CompactNamespaces: false
ContinuationIndentWidth: 8
IndentCaseLabels: true
Expand Down
22 changes: 4 additions & 18 deletions common/struct_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ typedef enum Status {
#define FLAGS_WXAUTH 0x0004000 /* same as above, but also prevent parsing */
#define FLAGS_NONL 0x0008000 /* No \n in buffer */
#define FLAGS_CBURST 0x0010000 /* set to mark connection burst being sent */
#define DEFER_USER_REG 0x0020000 /* iauth wants ircd to defer register_user() */
#define FLAGS_QUIT 0x0040000 /* QUIT :comment shows it's not a split */
#define FLAGS_SPLIT 0x0080000 /* client QUITting because of a netsplit */
#define FLAGS_HIDDEN 0x0100000 /* netsplit is behind a hostmask,
Expand Down Expand Up @@ -194,9 +195,7 @@ typedef enum Status {
#define FLAGS_AWAY 0x0020 /* user is away */
#define FLAGS_EXEMPT 0x0040 /* user is exempted from k-lines */
#define FLAGS_CLOAKED 0x0080 /* user's hostname is cloaked */
#ifdef XLINE
#define FLAGS_XLINED 0x0100 /* X-lined client */
#endif
#define FLAGS_TLS 0x0200 /* user is on a secure connection port (SSL/TLS) -- mh 2020-04-27 */
#define SEND_UMODES (FLAGS_INVISIBLE|FLAGS_OPER|FLAGS_WALLOP|FLAGS_AWAY|FLAGS_RESTRICT)
#define ALL_UMODES (SEND_UMODES|FLAGS_LOCOP)
Expand Down Expand Up @@ -261,11 +260,9 @@ typedef enum Status {
#define ClearXAuth(x) ((x)->flags &= ~FLAGS_XAUTH)
#define ClearWXAuth(x) ((x)->flags &= ~FLAGS_WXAUTH)
#define ClearListenerInactive(x) ((x)->flags &= ~FLAGS_LISTENINACTIVE)
#ifdef XLINE
#define IsXlined(x) ((x)->user && (x)->user->flags & FLAGS_XLINED)
#define SetXlined(x) ((x)->user->flags |= FLAGS_XLINED)
#define ClearXlined(x) ((x)->user->flags &= ~FLAGS_XLINED)
#endif
#define IsCloaked(x) ((x)->user && (x)->user->flags & FLAGS_CLOAKED)
#define SetCloaked(x) ((x)->user->flags |= FLAGS_CLOAKED)
#define HAS_CLOAK_IP(x) (!IN6_IS_ADDR_UNSPECIFIED(&((x)->cloak_ip)))
Expand Down Expand Up @@ -317,9 +314,7 @@ struct ConfItem {
char *passwd;
char *name;
char *name2;
#ifdef XLINE
char *name3;
#endif
int port;
long flags; /* I-line flags */
int pref; /* preference value */
Expand Down Expand Up @@ -365,9 +360,7 @@ struct ListItem {
#define CONF_TKILL 0x200000
#define CONF_TOTHERKILL 0x400000
#endif
#ifdef XLINE
#define CONF_XLINE 0x800000
#endif
#define CONF_OPS CONF_OPERATOR
#define CONF_SERVER_MASK (CONF_CONNECT_SERVER | CONF_NOCONNECT_SERVER |\
CONF_ZCONNECT_SERVER)
Expand All @@ -381,9 +374,7 @@ struct ListItem {
#define CFLAG_NORESOLVE 0x00010
#define CFLAG_FALL 0x00020
#define CFLAG_NORESOLVEMATCH 0x00040
#ifdef XLINE
#define CFLAG_XEXEMPT 0x00080
#endif
#define CFLAG_REQUIRE_SASL 0x00100

/* K-Line flags */
Expand All @@ -397,9 +388,7 @@ struct ListItem {
#define IsConfNoResolve(x) ((x)->flags & CFLAG_NORESOLVE)
#define IsConfNoResolveMatch(x) ((x)->flags & CFLAG_NORESOLVEMATCH)
#define IsConfFallThrough(x) ((x)->flags & CFLAG_FALL)
#ifdef XLINE
#define IsConfXlineExempt(x) ((x)->flags & CFLAG_XEXEMPT)
#endif
#define IsConfRequireSASL(x) ((x)->flags & CFLAG_REQUIRE_SASL)

#define PFLAG_DELAYED 0x00001
Expand Down Expand Up @@ -577,13 +566,12 @@ struct Client {
char passwd[PASSWDLEN+1];
char exitc;
char *reason; /* additional exit message */
#ifdef XLINE
/* Those logically should be in anUser struct, but would be null for
** all remote users... so better waste two pointers for all local
** non-users than two pointers for all remote users. --B. */
** all remote users... so better waste three pointers for all local
** non-users than three pointers for all remote users. --B. */
char *user1; /* 1st param of USER */
char *user2; /* 2nd param of USER */
char *user3; /* 3rd param of USER */
#endif
int caps; /* Enabled capabilities */
int cap_negotation; /* CAP negotiation is in progress. Registration must wait for "CAP END" */
aClient *sasl_service; /* The SASL service that is responsible for this user. */
Expand Down Expand Up @@ -978,9 +966,7 @@ typedef enum ServerChannels {
#define EXITC_AREF 'U' /* Unauthorized by iauth */
#define EXITC_AREFQ 'u' /* Unauthorized by iauth, be quiet */
#define EXITC_VIRUS 'v' /* joined a channel used by PrettyPark virus */
#ifdef XLINE
#define EXITC_XLINE 'X' /* Forbidden GECOS */
#endif
#define EXITC_YLINEMAX 'Y' /* Y:line max clients limit */

/* eXternal authentication slave OPTions */
Expand Down
148 changes: 138 additions & 10 deletions iauth/a_conf.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/************************************************************************
* IRC - Internet Relay Chat, iauth/a_conf.c
* Copyright (C) 1998 Christophe Kalt
* Copyright (C) 2025 IRCnet.com team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -241,6 +242,10 @@ char *conf_read(char *cfile)
(*last)->address = NULL;
(*last)->timeout = timeout;
(*last)->reason = NULL;
(*last)->wait_for_reg = 0;
(*last)->skip_if_sasl = 0;
(*last)->wait_for_ident = 0;
(*last)->skip_if_ident = 0;
(*last)->delayed = o_del;
(*last)->port = 0;
if (Mlist[i] == &Module_rfc931)
Expand Down Expand Up @@ -278,16 +283,110 @@ char *conf_read(char *cfile)
}
*ch = '\0';
if (!strncasecmp(buffer+1, "option = ", 9))
{
{
if ((*last)->opt)
conf_err(lnnb,
"Duplicate option keyword: ignored.",
cfile);
conf_err(lnnb, "Duplicate option keyword: ignored.",
cfile);
else
(*last)->opt =
mystrdup(buffer + 10);
{
/* Parse comma-separated option tokens */
const char *p = buffer + 10, *q;
char tmpbuf[512];
int j = 0;

(*last)->opt = mystrdup(buffer + 10);

/* trim leading spaces/tabs */
while (*p == ' ' || *p == '\t')
{
p++;
}
/* copy line to tmpbuf in lowercase */
while (*p && *p != '\n' && j < (int) sizeof(tmpbuf) - 1)
{
char ch2 = *p++;
if (ch2 >= 'A' && ch2 <= 'Z')
{
ch2 = (char) (ch2 - 'A' + 'a');
}
tmpbuf[j++] = ch2;
}
tmpbuf[j] = '\0';

/* iterate tokens split by commas; token may be key
* or key=value */
q = tmpbuf;
while (*q)
{
char *eq, token[256];
const char *start, *end;
size_t token_len;

/* skip separators and whitespace */
while (*q == ' ' || *q == '\t' || *q == ',')
{
q++;
}
if (!*q)
{
break;
}
start = q;
while (*q && *q != ',')
{
q++;
}
end = q;

/* trim trailing spaces */
while (end > start &&
(end[-1] == ' ' || end[-1] == '\t'))
{
end--;
}
if (end <= start)
{
continue;
}

/* extract token */
token_len = (size_t) (end - start);
if (token_len >= sizeof(token))
{
token_len = sizeof(token) - 1;
}
memcpy(token, start, token_len);
token[token_len] = '\0';

/* split name[=value] */
eq = strchr(token, '=');
if (eq)
{
/* we only care about the name */
*eq = '\0';
}
if (!strcmp(token, "wait_for_reg"))
{
(*last)->wait_for_reg = 1;
}
else if (!strcmp(token, "skip_if_sasl"))
{
(*last)->wait_for_reg = 1;
(*last)->skip_if_sasl = 1;
}
else if (!strcmp(token, "wait_for_ident"))
{
(*last)->wait_for_ident = 1;
}
else if (!strcmp(token, "skip_if_ident"))
{
(*last)->wait_for_ident = 1;
(*last)->skip_if_ident = 1;
}
}
}
continue;
}
}
if (!strncasecmp(buffer+1, "reason = ", 9))
{
if ((*last)->reason)
Expand Down Expand Up @@ -487,11 +586,18 @@ char *conf_read(char *cfile)
printf("\t\tport: %u\n",
itmp->port);
if (itmp->mod->init)
{
{
err = itmp->mod->init(itmp);
printf("\t\tInitialization: %s\n",
(err) ? err : "Successful");
}
(err) ? err : "Successful");

if (err == NULL && itmp->mod->ginit)
{
int grc = itmp->mod->ginit(itmp);
printf("\t\tGlobal initialization: %s\n",
(grc < 0) ? "Failed" : "Successful");
}
}
itmp = itmp->nexti;
}
}
Expand All @@ -502,6 +608,11 @@ char *conf_read(char *cfile)
if (itmp->mod->init)
{
itmp->mod->init(itmp);

if (itmp->mod->ginit)
{
itmp->mod->ginit(itmp);
}
}
itmp = itmp->nexti;
}
Expand All @@ -524,6 +635,23 @@ int conf_match(u_int cl, AnInstance *inst)
{
aTarget *ttmp;

/*
* If the module is configured with option wait_for_ident,
* do not start it until the ident lookup has finished:
* - A_GOTIDENT: ident succeeded (USERID available)
* - A_NOIDENT: ident is definitively unavailable (timeout/refused/fail)
*
* If neither flag is set yet, ask the scheduler to try again later.
*/
if (inst->wait_for_ident || inst->skip_if_ident)
{
if ((cldata[cl].state & (A_GOTIDENT | A_NOIDENT)) == 0)
{
/* try again later */
return 1;
}
}

/* general case, always matches */
if (inst->address == NULL && inst->hostname == NULL)
return 0;
Expand Down
11 changes: 11 additions & 0 deletions iauth/a_conf_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ struct Module
* done (incoming data, timeout..) */
int (*timeout)(u_int); /* called when timeout is reached */
void (*clean)(u_int); /* finish/abort: cleanup*/

/* Optional global (module-wide) lifecycle hooks */
int (*ginit)(AnInstance *); /* initialize persistent resources */
void (*gtick)(AnInstance *); /* invoked periodically */
int (*gwork)(AnInstance *); /* handle global events (if any) */
void (*grelease)(AnInstance *); /* cleanup persistent resources */
};

struct Instance
Expand All @@ -46,6 +52,11 @@ struct Instance
aTarget *hostname;
u_int timeout;
u_int port;
u_char wait_for_reg; /* wait until client sent NICK/USER
(and possibly CAP/AUTHENTICATE) */
u_char skip_if_sasl; /* skip module if SASL authentication succeeded. */
u_char wait_for_ident; /* wait until ident lookup completes */
u_char skip_if_ident; /* skip module if we got an ident reply */
char *reason; /* reject reason */
u_char delayed; /* delayed execution mode */
};
Expand Down
Loading
Loading