mirror of
https://github.com/osmarks/ngircd.git
synced 2024-12-12 01:40:27 +00:00
New "login" source file
Rename Hello_User[_PostAuth] to Login_User[_PostAuth] and move it to the new login.c; and move cb_Read_Auth_Result(), too. This will enable further code to easily call Login_User() when required.
This commit is contained in:
parent
ee362b3bd2
commit
edfcc2f9d5
@ -41,6 +41,7 @@
|
|||||||
FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA3D2790F139CDC00B2447E /* conn-ssl.c */; };
|
FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA3D2790F139CDC00B2447E /* conn-ssl.c */; };
|
||||||
FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA97C55124A271400D5BBA9 /* sighandlers.c */; };
|
FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA97C55124A271400D5BBA9 /* sighandlers.c */; };
|
||||||
FAACD5F514A6099C006ED74F /* class.c in Sources */ = {isa = PBXBuildFile; fileRef = FAACD5F314A6099C006ED74F /* class.c */; };
|
FAACD5F514A6099C006ED74F /* class.c in Sources */ = {isa = PBXBuildFile; fileRef = FAACD5F314A6099C006ED74F /* class.c */; };
|
||||||
|
FAD5853815272C2600328741 /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = FAD5853615272C2500328741 /* login.c */; };
|
||||||
FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */ = {isa = PBXBuildFile; fileRef = FAE5CC2D0CF2308A007D69B6 /* numeric.c */; };
|
FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */ = {isa = PBXBuildFile; fileRef = FAE5CC2D0CF2308A007D69B6 /* numeric.c */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
@ -231,6 +232,8 @@
|
|||||||
FAA97C56124A271400D5BBA9 /* sighandlers.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = sighandlers.h; sourceTree = "<group>"; };
|
FAA97C56124A271400D5BBA9 /* sighandlers.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = sighandlers.h; sourceTree = "<group>"; };
|
||||||
FAACD5F314A6099C006ED74F /* class.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = class.c; sourceTree = "<group>"; };
|
FAACD5F314A6099C006ED74F /* class.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = class.c; sourceTree = "<group>"; };
|
||||||
FAACD5F414A6099C006ED74F /* class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = class.h; sourceTree = "<group>"; };
|
FAACD5F414A6099C006ED74F /* class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = class.h; sourceTree = "<group>"; };
|
||||||
|
FAD5853615272C2500328741 /* login.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = login.c; sourceTree = "<group>"; };
|
||||||
|
FAD5853715272C2500328741 /* login.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = login.h; sourceTree = "<group>"; };
|
||||||
FAE22BD215270EA300F1A5AB /* Bopm.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bopm.txt; sourceTree = "<group>"; };
|
FAE22BD215270EA300F1A5AB /* Bopm.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bopm.txt; sourceTree = "<group>"; };
|
||||||
FAE22BD415270EA300F1A5AB /* Contributing.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Contributing.txt; sourceTree = "<group>"; };
|
FAE22BD415270EA300F1A5AB /* Contributing.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Contributing.txt; sourceTree = "<group>"; };
|
||||||
FAE22BD515270EB500F1A5AB /* HowToRelease.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = HowToRelease.txt; sourceTree = "<group>"; };
|
FAE22BD515270EB500F1A5AB /* HowToRelease.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = HowToRelease.txt; sourceTree = "<group>"; };
|
||||||
@ -351,6 +354,8 @@
|
|||||||
FA322CFF0CEF74B1001761B3 /* lists.h */,
|
FA322CFF0CEF74B1001761B3 /* lists.h */,
|
||||||
FA322D000CEF74B1001761B3 /* log.c */,
|
FA322D000CEF74B1001761B3 /* log.c */,
|
||||||
FA322D010CEF74B1001761B3 /* log.h */,
|
FA322D010CEF74B1001761B3 /* log.h */,
|
||||||
|
FAD5853615272C2500328741 /* login.c */,
|
||||||
|
FAD5853715272C2500328741 /* login.h */,
|
||||||
FA322D030CEF74B1001761B3 /* match.c */,
|
FA322D030CEF74B1001761B3 /* match.c */,
|
||||||
FA322D040CEF74B1001761B3 /* match.h */,
|
FA322D040CEF74B1001761B3 /* match.h */,
|
||||||
FA322D050CEF74B1001761B3 /* messages.h */,
|
FA322D050CEF74B1001761B3 /* messages.h */,
|
||||||
@ -730,6 +735,7 @@
|
|||||||
FA2D564A11EA158B00D37A35 /* pam.c in Sources */,
|
FA2D564A11EA158B00D37A35 /* pam.c in Sources */,
|
||||||
FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */,
|
FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */,
|
||||||
FAACD5F514A6099C006ED74F /* class.c in Sources */,
|
FAACD5F514A6099C006ED74F /* class.c in Sources */,
|
||||||
|
FAD5853815272C2600328741 /* login.c in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -42,6 +42,7 @@ ngircd_SOURCES = \
|
|||||||
irc-write.c \
|
irc-write.c \
|
||||||
lists.c \
|
lists.c \
|
||||||
log.c \
|
log.c \
|
||||||
|
login.c \
|
||||||
match.c \
|
match.c \
|
||||||
numeric.c \
|
numeric.c \
|
||||||
op.c \
|
op.c \
|
||||||
@ -81,6 +82,7 @@ noinst_HEADERS = \
|
|||||||
irc-write.h \
|
irc-write.h \
|
||||||
lists.h \
|
lists.h \
|
||||||
log.h \
|
log.h \
|
||||||
|
login.h \
|
||||||
match.h \
|
match.h \
|
||||||
messages.h \
|
messages.h \
|
||||||
numeric.h \
|
numeric.h \
|
||||||
|
@ -18,22 +18,16 @@
|
|||||||
|
|
||||||
#include "imp.h"
|
#include "imp.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "ngircd.h"
|
|
||||||
#include "conn-func.h"
|
#include "conn-func.h"
|
||||||
#include "class.h"
|
#include "class.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "channel.h"
|
#include "channel.h"
|
||||||
#include "io.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "login.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
#include "pam.h"
|
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "irc.h"
|
#include "irc.h"
|
||||||
#include "irc-info.h"
|
#include "irc-info.h"
|
||||||
@ -42,13 +36,7 @@
|
|||||||
#include "exp.h"
|
#include "exp.h"
|
||||||
#include "irc-login.h"
|
#include "irc-login.h"
|
||||||
|
|
||||||
|
|
||||||
static bool Hello_User PARAMS(( CLIENT *Client ));
|
|
||||||
static bool Hello_User_PostAuth PARAMS(( CLIENT *Client ));
|
|
||||||
static void Kill_Nick PARAMS(( char *Nick, char *Reason ));
|
static void Kill_Nick PARAMS(( char *Nick, char *Reason ));
|
||||||
#ifdef PAM
|
|
||||||
static void cb_Read_Auth_Result PARAMS((int r_fd, UNUSED short events));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for the IRC "PASS" command.
|
* Handler for the IRC "PASS" command.
|
||||||
@ -280,7 +268,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
|
|||||||
/* If we received a valid USER command already then
|
/* If we received a valid USER command already then
|
||||||
* register the new client! */
|
* register the new client! */
|
||||||
if( Client_Type( Client ) == CLIENT_GOTUSER )
|
if( Client_Type( Client ) == CLIENT_GOTUSER )
|
||||||
return Hello_User( Client );
|
return Login_User( Client );
|
||||||
else
|
else
|
||||||
Client_SetType( Client, CLIENT_GOTNICK );
|
Client_SetType( Client, CLIENT_GOTNICK );
|
||||||
} else {
|
} else {
|
||||||
@ -452,7 +440,7 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
|
|||||||
LogDebug("Connection %d: got valid USER command ...",
|
LogDebug("Connection %d: got valid USER command ...",
|
||||||
Client_Conn(Client));
|
Client_Conn(Client));
|
||||||
if (Client_Type(Client) == CLIENT_GOTNICK)
|
if (Client_Type(Client) == CLIENT_GOTNICK)
|
||||||
return Hello_User(Client);
|
return Login_User(Client);
|
||||||
else
|
else
|
||||||
Client_SetType(Client, CLIENT_GOTUSER);
|
Client_SetType(Client, CLIENT_GOTUSER);
|
||||||
return CONNECTED;
|
return CONNECTED;
|
||||||
@ -875,7 +863,7 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
|
|||||||
if (auth_ping == atoi(Req->argv[0])) {
|
if (auth_ping == atoi(Req->argv[0])) {
|
||||||
Conn_SetAuthPing(conn, 0);
|
Conn_SetAuthPing(conn, 0);
|
||||||
if (Client_Type(Client) == CLIENT_WAITAUTHPING)
|
if (Client_Type(Client) == CLIENT_WAITAUTHPING)
|
||||||
Hello_User(Client);
|
Login_User(Client);
|
||||||
} else
|
} else
|
||||||
if (!IRC_WriteStrClient(Client,
|
if (!IRC_WriteStrClient(Client,
|
||||||
"To connect, type /QUOTE PONG %ld",
|
"To connect, type /QUOTE PONG %ld",
|
||||||
@ -898,196 +886,6 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
|
|||||||
} /* IRC_PONG */
|
} /* IRC_PONG */
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initiate client registration.
|
|
||||||
*
|
|
||||||
* This function is called after the daemon received the required NICK and
|
|
||||||
* USER commands of a new client. If the daemon is compiled with support for
|
|
||||||
* PAM, the authentication sub-processs is forked; otherwise the global server
|
|
||||||
* password is checked.
|
|
||||||
*
|
|
||||||
* @param Client The client logging in.
|
|
||||||
* @returns CONNECTED or DISCONNECTED.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
Hello_User(CLIENT * Client)
|
|
||||||
{
|
|
||||||
#ifdef PAM
|
|
||||||
int pipefd[2], result;
|
|
||||||
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:
|
|
||||||
* because there can't be any "server password", all
|
|
||||||
* passwords supplied are classified as "wrong". */
|
|
||||||
if(Client_Password(Client)[0] == '\0')
|
|
||||||
return Hello_User_PostAuth(Client);
|
|
||||||
Client_Reject(Client, "Non-empty password", false);
|
|
||||||
return DISCONNECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Conf_PAMIsOptional && strcmp(Client_Password(Client), "") == 0) {
|
|
||||||
/* Clients are not required to send a password and to be PAM-
|
|
||||||
* authenticated at all. If not, they won't become "identified"
|
|
||||||
* and keep the "~" in their supplied user name.
|
|
||||||
* Therefore it is sensible to either set Conf_PAMisOptional or
|
|
||||||
* to enable IDENT lookups -- not both. */
|
|
||||||
return Hello_User_PostAuth(Client);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fork child process for PAM authentication; and make sure that the
|
|
||||||
* process timeout is set higher than the login timeout! */
|
|
||||||
pid = Proc_Fork(Conn_GetProcStat(conn), pipefd,
|
|
||||||
cb_Read_Auth_Result, Conf_PongTimeout + 1);
|
|
||||||
if (pid > 0) {
|
|
||||||
LogDebug("Authenticator for connection %d created (PID %d).",
|
|
||||||
conn, pid);
|
|
||||||
return CONNECTED;
|
|
||||||
} else {
|
|
||||||
/* Sub process */
|
|
||||||
Log_Init_Subprocess("Auth");
|
|
||||||
Conn_CloseAllSockets(NONE);
|
|
||||||
result = PAM_Authenticate(Client);
|
|
||||||
if (write(pipefd[1], &result, sizeof(result)) != sizeof(result))
|
|
||||||
Log_Subprocess(LOG_ERR,
|
|
||||||
"Failed to pipe result to parent!");
|
|
||||||
Log_Exit_Subprocess("Auth");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* Check global server password ... */
|
|
||||||
if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
|
|
||||||
/* Bad password! */
|
|
||||||
Client_Reject(Client, "Bad server password", false);
|
|
||||||
return DISCONNECTED;
|
|
||||||
}
|
|
||||||
return Hello_User_PostAuth(Client);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef PAM
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read result of the authenticatior sub-process from pipe
|
|
||||||
*
|
|
||||||
* @param r_fd File descriptor of the pipe.
|
|
||||||
* @param events (ignored IO specification)
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
cb_Read_Auth_Result(int r_fd, UNUSED short events)
|
|
||||||
{
|
|
||||||
CONN_ID conn;
|
|
||||||
CLIENT *client;
|
|
||||||
int result;
|
|
||||||
size_t len;
|
|
||||||
PROC_STAT *proc;
|
|
||||||
|
|
||||||
LogDebug("Auth: Got callback on fd %d, events %d", r_fd, events);
|
|
||||||
conn = Conn_GetFromProc(r_fd);
|
|
||||||
if (conn == NONE) {
|
|
||||||
/* Ops, none found? Probably the connection has already
|
|
||||||
* been closed!? We'll ignore that ... */
|
|
||||||
io_close(r_fd);
|
|
||||||
LogDebug("Auth: Got callback for unknown connection!?");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
proc = Conn_GetProcStat(conn);
|
|
||||||
client = Conn_GetClient(conn);
|
|
||||||
|
|
||||||
/* Read result from pipe */
|
|
||||||
len = Proc_Read(proc, &result, sizeof(result));
|
|
||||||
Proc_Close(proc);
|
|
||||||
if (len == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (len != sizeof(result)) {
|
|
||||||
Log(LOG_CRIT, "Auth: Got malformed result!");
|
|
||||||
Client_Reject(client, "Internal error", false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == true) {
|
|
||||||
Client_SetUser(client, Client_OrigUser(client), true);
|
|
||||||
(void)Hello_User_PostAuth(client);
|
|
||||||
} else
|
|
||||||
Client_Reject(client, "Bad password", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finish client registration.
|
|
||||||
*
|
|
||||||
* Introduce the new client to the network and send all "hello messages"
|
|
||||||
* to it after authentication has been succeeded.
|
|
||||||
*
|
|
||||||
* @param Client The client logging in.
|
|
||||||
* @returns CONNECTED or DISCONNECTED.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
Hello_User_PostAuth(CLIENT *Client)
|
|
||||||
{
|
|
||||||
assert(Client != NULL);
|
|
||||||
|
|
||||||
if (Class_HandleServerBans(Client) != CONNECTED)
|
|
||||||
return DISCONNECTED;
|
|
||||||
|
|
||||||
Client_Introduce(NULL, Client, CLIENT_USER);
|
|
||||||
|
|
||||||
if (!IRC_WriteStrClient
|
|
||||||
(Client, RPL_WELCOME_MSG, Client_ID(Client), Client_Mask(Client)))
|
|
||||||
return false;
|
|
||||||
if (!IRC_WriteStrClient
|
|
||||||
(Client, RPL_YOURHOST_MSG, Client_ID(Client),
|
|
||||||
Client_ID(Client_ThisServer()), PACKAGE_VERSION, TARGET_CPU,
|
|
||||||
TARGET_VENDOR, TARGET_OS))
|
|
||||||
return false;
|
|
||||||
if (!IRC_WriteStrClient
|
|
||||||
(Client, RPL_CREATED_MSG, Client_ID(Client), NGIRCd_StartStr))
|
|
||||||
return false;
|
|
||||||
if (!IRC_WriteStrClient
|
|
||||||
(Client, RPL_MYINFO_MSG, Client_ID(Client),
|
|
||||||
Client_ID(Client_ThisServer()), PACKAGE_VERSION, USERMODES,
|
|
||||||
CHANMODES))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* Features supported by this server (005 numeric, ISUPPORT),
|
|
||||||
* see <http://www.irc.org/tech_docs/005.html> for details. */
|
|
||||||
if (!IRC_Send_ISUPPORT(Client))
|
|
||||||
return DISCONNECTED;
|
|
||||||
|
|
||||||
if (!IRC_Send_LUSERS(Client))
|
|
||||||
return DISCONNECTED;
|
|
||||||
if (!IRC_Show_MOTD(Client))
|
|
||||||
return DISCONNECTED;
|
|
||||||
|
|
||||||
/* Suspend the client for a second ... */
|
|
||||||
IRC_SetPenalty(Client, 1);
|
|
||||||
|
|
||||||
return CONNECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kill all users with a specific nick name in the network.
|
* Kill all users with a specific nick name in the network.
|
||||||
*
|
*
|
||||||
|
234
src/ngircd/login.c
Normal file
234
src/ngircd/login.c
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
/*
|
||||||
|
* ngIRCd -- The Next Generation IRC Daemon
|
||||||
|
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
* Please read the file COPYING, README and AUTHORS for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "portab.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Functions to deal with client logins
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "imp.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "defines.h"
|
||||||
|
#include "conn.h"
|
||||||
|
#include "class.h"
|
||||||
|
#include "client.h"
|
||||||
|
#include "channel.h"
|
||||||
|
#include "conf.h"
|
||||||
|
#include "io.h"
|
||||||
|
#include "parse.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "messages.h"
|
||||||
|
#include "ngircd.h"
|
||||||
|
#include "pam.h"
|
||||||
|
#include "irc-info.h"
|
||||||
|
#include "irc-write.h"
|
||||||
|
|
||||||
|
#include "exp.h"
|
||||||
|
#include "login.h"
|
||||||
|
|
||||||
|
#ifdef PAM
|
||||||
|
static void cb_Read_Auth_Result PARAMS((int r_fd, UNUSED short events));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiate client login.
|
||||||
|
*
|
||||||
|
* This function is called after the daemon received the required NICK and
|
||||||
|
* USER commands of a new client. If the daemon is compiled with support for
|
||||||
|
* PAM, the authentication sub-processs is forked; otherwise the global server
|
||||||
|
* password is checked.
|
||||||
|
*
|
||||||
|
* @param Client The client logging in.
|
||||||
|
* @returns CONNECTED or DISCONNECTED.
|
||||||
|
*/
|
||||||
|
GLOBAL bool
|
||||||
|
Login_User(CLIENT * Client)
|
||||||
|
{
|
||||||
|
#ifdef PAM
|
||||||
|
int pipefd[2], result;
|
||||||
|
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:
|
||||||
|
* because there can't be any "server password", all
|
||||||
|
* passwords supplied are classified as "wrong". */
|
||||||
|
if(Client_Password(Client)[0] == '\0')
|
||||||
|
return Login_User_PostAuth(Client);
|
||||||
|
Client_Reject(Client, "Non-empty password", false);
|
||||||
|
return DISCONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Conf_PAMIsOptional && strcmp(Client_Password(Client), "") == 0) {
|
||||||
|
/* Clients are not required to send a password and to be PAM-
|
||||||
|
* authenticated at all. If not, they won't become "identified"
|
||||||
|
* and keep the "~" in their supplied user name.
|
||||||
|
* Therefore it is sensible to either set Conf_PAMisOptional or
|
||||||
|
* to enable IDENT lookups -- not both. */
|
||||||
|
return Login_User_PostAuth(Client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fork child process for PAM authentication; and make sure that the
|
||||||
|
* process timeout is set higher than the login timeout! */
|
||||||
|
pid = Proc_Fork(Conn_GetProcStat(conn), pipefd,
|
||||||
|
cb_Read_Auth_Result, Conf_PongTimeout + 1);
|
||||||
|
if (pid > 0) {
|
||||||
|
LogDebug("Authenticator for connection %d created (PID %d).",
|
||||||
|
conn, pid);
|
||||||
|
return CONNECTED;
|
||||||
|
} else {
|
||||||
|
/* Sub process */
|
||||||
|
Log_Init_Subprocess("Auth");
|
||||||
|
Conn_CloseAllSockets(NONE);
|
||||||
|
result = PAM_Authenticate(Client);
|
||||||
|
if (write(pipefd[1], &result, sizeof(result)) != sizeof(result))
|
||||||
|
Log_Subprocess(LOG_ERR,
|
||||||
|
"Failed to pipe result to parent!");
|
||||||
|
Log_Exit_Subprocess("Auth");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Check global server password ... */
|
||||||
|
if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
|
||||||
|
/* Bad password! */
|
||||||
|
Client_Reject(Client, "Bad server password", false);
|
||||||
|
return DISCONNECTED;
|
||||||
|
}
|
||||||
|
return Login_User_PostAuth(Client);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish client registration.
|
||||||
|
*
|
||||||
|
* Introduce the new client to the network and send all "hello messages"
|
||||||
|
* to it after authentication has been succeeded.
|
||||||
|
*
|
||||||
|
* @param Client The client logging in.
|
||||||
|
* @return CONNECTED or DISCONNECTED.
|
||||||
|
*/
|
||||||
|
GLOBAL bool
|
||||||
|
Login_User_PostAuth(CLIENT *Client)
|
||||||
|
{
|
||||||
|
assert(Client != NULL);
|
||||||
|
|
||||||
|
if (Class_HandleServerBans(Client) != CONNECTED)
|
||||||
|
return DISCONNECTED;
|
||||||
|
|
||||||
|
Client_Introduce(NULL, Client, CLIENT_USER);
|
||||||
|
|
||||||
|
if (!IRC_WriteStrClient
|
||||||
|
(Client, RPL_WELCOME_MSG, Client_ID(Client), Client_Mask(Client)))
|
||||||
|
return false;
|
||||||
|
if (!IRC_WriteStrClient
|
||||||
|
(Client, RPL_YOURHOST_MSG, Client_ID(Client),
|
||||||
|
Client_ID(Client_ThisServer()), PACKAGE_VERSION, TARGET_CPU,
|
||||||
|
TARGET_VENDOR, TARGET_OS))
|
||||||
|
return false;
|
||||||
|
if (!IRC_WriteStrClient
|
||||||
|
(Client, RPL_CREATED_MSG, Client_ID(Client), NGIRCd_StartStr))
|
||||||
|
return false;
|
||||||
|
if (!IRC_WriteStrClient
|
||||||
|
(Client, RPL_MYINFO_MSG, Client_ID(Client),
|
||||||
|
Client_ID(Client_ThisServer()), PACKAGE_VERSION, USERMODES,
|
||||||
|
CHANMODES))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Features supported by this server (005 numeric, ISUPPORT),
|
||||||
|
* see <http://www.irc.org/tech_docs/005.html> for details. */
|
||||||
|
if (!IRC_Send_ISUPPORT(Client))
|
||||||
|
return DISCONNECTED;
|
||||||
|
|
||||||
|
if (!IRC_Send_LUSERS(Client))
|
||||||
|
return DISCONNECTED;
|
||||||
|
if (!IRC_Show_MOTD(Client))
|
||||||
|
return DISCONNECTED;
|
||||||
|
|
||||||
|
/* Suspend the client for a second ... */
|
||||||
|
IRC_SetPenalty(Client, 1);
|
||||||
|
|
||||||
|
return CONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef PAM
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read result of the authenticatior sub-process from pipe
|
||||||
|
*
|
||||||
|
* @param r_fd File descriptor of the pipe.
|
||||||
|
* @param events (ignored IO specification)
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
cb_Read_Auth_Result(int r_fd, UNUSED short events)
|
||||||
|
{
|
||||||
|
CONN_ID conn;
|
||||||
|
CLIENT *client;
|
||||||
|
int result;
|
||||||
|
size_t len;
|
||||||
|
PROC_STAT *proc;
|
||||||
|
|
||||||
|
LogDebug("Auth: Got callback on fd %d, events %d", r_fd, events);
|
||||||
|
conn = Conn_GetFromProc(r_fd);
|
||||||
|
if (conn == NONE) {
|
||||||
|
/* Ops, none found? Probably the connection has already
|
||||||
|
* been closed!? We'll ignore that ... */
|
||||||
|
io_close(r_fd);
|
||||||
|
LogDebug("Auth: Got callback for unknown connection!?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
proc = Conn_GetProcStat(conn);
|
||||||
|
client = Conn_GetClient(conn);
|
||||||
|
|
||||||
|
/* Read result from pipe */
|
||||||
|
len = Proc_Read(proc, &result, sizeof(result));
|
||||||
|
Proc_Close(proc);
|
||||||
|
if (len == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (len != sizeof(result)) {
|
||||||
|
Log(LOG_CRIT, "Auth: Got malformed result!");
|
||||||
|
Client_Reject(client, "Internal error", false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == true) {
|
||||||
|
Client_SetUser(client, Client_OrigUser(client), true);
|
||||||
|
(void)Login_User_PostAuth(client);
|
||||||
|
} else
|
||||||
|
Client_Reject(client, "Bad password", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* -eof- */
|
25
src/ngircd/login.h
Normal file
25
src/ngircd/login.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* ngIRCd -- The Next Generation IRC Daemon
|
||||||
|
* Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
* Please read the file COPYING, README and AUTHORS for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __login_h__
|
||||||
|
#define __login_h__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Functions to deal with client logins (header)
|
||||||
|
*/
|
||||||
|
|
||||||
|
GLOBAL bool Login_User PARAMS((CLIENT * Client));
|
||||||
|
GLOBAL bool Login_User_PostAuth PARAMS((CLIENT *Client));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* -eof- */
|
Loading…
Reference in New Issue
Block a user