Merge branch 'AuthPing'

* AuthPing:
  Add documentation for "RequireAuthPing" configuration option
  New configuration option "RequireAuthPing": PING-PONG on login
This commit is contained in:
Alexander Barton 2011-03-27 20:58:18 +02:00
commit d61fbfc6e3
10 changed files with 136 additions and 16 deletions

View File

@ -159,6 +159,11 @@
# messages to clients while connecting.
;NoticeAuth = no
# Let ngIRCd send an "authentication PING" when a new client connects,
# and register this client only after receiving the corresponding
# "PONG" reply.
;RequireAuthPing = no
# Set this hostname for every client instead of the real one.
# Please note: don't use the percentage sign ("%"), it is reserved for
# future extensions!

View File

@ -256,6 +256,11 @@ Normally ngIRCd doesn't send any messages to a client until it is registered.
Enable this option to let the daemon send "NOTICE AUTH" messages to clients
while connecting. Default: no.
.TP
\fBRequireAuthPing\fR (boolean)
Let ngIRCd send an "authentication PING" when a new client connects, and
register this client only after receiving the corresponding "PONG" reply.
Default: no.
.TP
\fBCloakHost\fR (string)
Set this hostname for every client instead of the real one. Default: empty,
don't change.

View File

@ -26,6 +26,9 @@
#define CLIENT_SERVICE 64 /* client is a service */
#define CLIENT_UNKNOWNSERVER 128 /* unregistered server connection */
#define CLIENT_GOTPASS_2813 256 /* client did send PASS, RFC 2813 style */
#ifndef STRICT_RFC
# define CLIENT_WAITAUTHPING 512 /* waiting for AUTH PONG from client */
#endif
#define CLIENT_TYPE int

View File

@ -354,9 +354,12 @@ Conf_Test( void )
printf(" MaxNickLength = %u\n", Conf_MaxNickLength - 1);
printf(" NoticeAuth = %s\n", yesno_to_str(Conf_NoticeAuth));
printf(" CloakHost = %s\n", Conf_CloakHost);
printf(" CloakUserToNick = %s\n\n", yesno_to_str(Conf_CloakUserToNick));
printf(" CloakUserToNick = %s\n", yesno_to_str(Conf_CloakUserToNick));
#ifndef STRICT_RFC
printf(" RequireAuthPing = %s\n", yesno_to_str(Conf_AuthPing));
#endif
puts("[FEATURES]");
printf("\n[FEATURES]\n");
printf(" DNS = %s\n", yesno_to_str(Conf_DNS));
printf(" Ident = %s\n", yesno_to_str(Conf_Ident));
printf(" PAM = %s\n", yesno_to_str(Conf_PAM));
@ -643,6 +646,11 @@ Set_Defaults(bool InitServers)
Conf_SyslogFacility = 0;
#endif
#endif
#ifndef STRICT_RFC
Conf_AuthPing = false;
#endif
Set_Defaults_Optional();
/* Initialize server configuration structures */
@ -1255,6 +1263,13 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
Conf_SyslogFacility);
return;
}
#endif
#ifndef STRICT_RFC
if (strcasecmp(Var, "RequireAuthPing") == 0 ) {
/* Require new clients to do an "autheticatin PING-PONG" */
Conf_AuthPing = Check_ArgIsTrue(Arg);
return;
}
#endif
Config_Error(LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!",
NGIRCd_ConfFile, Line, Var);

View File

@ -202,6 +202,13 @@ GLOBAL int Conf_MaxConnectionsIP;
/** Maximum length of a nick name */
GLOBAL unsigned int Conf_MaxNickLength;
#ifndef STRICT_RFC
/** Require "AUTH PING-PONG" on login */
GLOBAL bool Conf_AuthPing;
#endif
#ifdef SYSLOG
/* Syslog "facility" */

View File

@ -2303,6 +2303,25 @@ Conn_GetFromProc(int fd)
} /* Conn_GetFromProc */
#ifndef STRICT_RFC
GLOBAL long
Conn_GetAuthPing(CONN_ID Idx)
{
assert (Idx != NONE);
return My_Connections[Idx].auth_ping;
} /* Conn_GetAuthPing */
GLOBAL void
Conn_SetAuthPing(CONN_ID Idx, long ID)
{
assert (Idx != NONE);
My_Connections[Idx].auth_ping = ID;
} /* Conn_SetAuthPing */
#endif
#ifdef SSL_SUPPORT
/**

View File

@ -91,6 +91,9 @@ typedef struct _Connection
#ifdef SSL_SUPPORT
struct ConnSSL_State ssl_state; /* SSL/GNUTLS state information */
#endif
#ifndef STRICT_RFC
long auth_ping; /** PING response expected on login */
#endif
} CONNECTION;
GLOBAL CONNECTION *My_Connections;
@ -132,6 +135,11 @@ GLOBAL long Conn_Count PARAMS((void));
GLOBAL long Conn_CountMax PARAMS((void));
GLOBAL long Conn_CountAccepted PARAMS((void));
#ifndef STRICT_RFC
GLOBAL long Conn_GetAuthPing PARAMS((CONN_ID Idx));
GLOBAL void Conn_SetAuthPing PARAMS((CONN_ID Idx, long ID));
#endif
#ifdef DEBUG
GLOBAL void Conn_DebugDump PARAMS((void));
#endif

View File

@ -271,6 +271,17 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
/* Register new nickname of this client */
Client_SetID( target, Req->argv[0] );
#ifndef STRICT_RFC
if (Conf_AuthPing) {
Conn_SetAuthPing(Client_Conn(Client), random());
IRC_WriteStrClient(Client, "PING :%ld",
Conn_GetAuthPing(Client_Conn(Client)));
LogDebug("Connection %d: sent AUTH PING %ld ...",
Client_Conn(Client),
Conn_GetAuthPing(Client_Conn(Client)));
}
#endif
/* If we received a valid USER command already then
* register the new client! */
if( Client_Type( Client ) == CLIENT_GOTUSER )
@ -797,18 +808,32 @@ GLOBAL bool
IRC_PONG(CLIENT *Client, REQUEST *Req)
{
CLIENT *target, *from;
CONN_ID conn;
#ifndef STRICT_RFC
long auth_ping;
#endif
char *s;
assert(Client != NULL);
assert(Req != NULL);
/* Wrong number of arguments? */
if (Req->argc < 1)
return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG,
Client_ID(Client));
if (Req->argc > 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if (Req->argc < 1) {
if (Client_Type(Client) == CLIENT_USER)
return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG,
Client_ID(Client));
else
return CONNECTED;
}
if (Req->argc > 2) {
if (Client_Type(Client) == CLIENT_USER)
return IRC_WriteStrClient(Client,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client),
Req->command);
else
return CONNECTED;
}
/* Forward? */
if (Req->argc == 2 && Client_Type(Client) == CLIENT_SERVER) {
@ -837,15 +862,35 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
/* The connection timestamp has already been updated when the data has
* been read from so socket, so we don't need to update it here. */
conn = Client_Conn(Client);
#ifndef STRICT_RFC
/* Check authentication PING-PONG ... */
auth_ping = Conn_GetAuthPing(conn);
if (auth_ping) {
LogDebug("AUTH PONG: waiting for token \"%ld\", got \"%s\" ...",
auth_ping, Req->argv[0]);
if (auth_ping == atoi(Req->argv[0])) {
Conn_SetAuthPing(conn, 0);
if (Client_Type(Client) == CLIENT_WAITAUTHPING)
Hello_User(Client);
} else
if (!IRC_WriteStrClient(Client,
"To connect, type /QUOTE PONG %ld",
auth_ping))
return DISCONNECTED;
}
#endif
#ifdef DEBUG
if (Client_Conn(Client) > NONE)
if (conn > NONE)
Log(LOG_DEBUG,
"Connection %d: received PONG. Lag: %ld seconds.",
Client_Conn(Client),
"Connection %d: received PONG. Lag: %ld seconds.", conn,
time(NULL) - Conn_LastPing(Client_Conn(Client)));
else
Log(LOG_DEBUG,
"Connection %d: received PONG.", Client_Conn(Client));
"Connection %d: received PONG.", conn);
#endif
return CONNECTED;
} /* IRC_PONG */
@ -867,12 +912,25 @@ Hello_User(CLIENT * Client)
{
#ifdef PAM
int pipefd[2], result;
CONN_ID conn;
pid_t pid;
#endif
CONN_ID conn;
assert(Client != NULL);
conn = Client_Conn(Client);
#ifndef STRICT_RFC
if (Conf_AuthPing) {
/* Did we receive the "auth PONG" already? */
if (Conn_GetAuthPing(conn)) {
Client_SetType(Client, CLIENT_WAITAUTHPING);
LogDebug("Connection %d: Waiting for AUTH PONG ...", conn);
return CONNECTED;
}
}
#endif
#ifdef PAM
if (!Conf_PAM) {
/* Don't do any PAM authentication at all, instead emulate
* the beahiour of the daemon compiled without PAM support:
@ -903,8 +961,6 @@ Hello_User(CLIENT * Client)
exit(0);
}
#else
assert(Client != NULL);
/* Check global server password ... */
if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
/* Bad password! */

View File

@ -289,6 +289,8 @@ main( int argc, const char *argv[] )
exit(1);
}
srandom(getpid());
/* Create protocol and server identification. The syntax
* used by ngIRCd in PASS commands and the known "extended
* flags" are described in doc/Protocol.txt. */

View File

@ -82,7 +82,7 @@ static COMMAND My_Commands[] =
{ "PART", IRC_PART, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "PASS", IRC_PASS, 0xFFFF, 0, 0, 0 },
{ "PING", IRC_PING, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "PONG", IRC_PONG, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "PONG", IRC_PONG, 0xFFFF, 0, 0, 0 },
{ "PRIVMSG", IRC_PRIVMSG, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
{ "QUIT", IRC_QUIT, 0xFFFF, 0, 0, 0 },
{ "REHASH", IRC_REHASH, CLIENT_USER, 0, 0, 0 },