]> arthur.barton.de Git - ngircd-alex.git/commitdiff
New "login" source file
authorAlexander Barton <alex@barton.de>
Sat, 31 Mar 2012 13:38:46 +0000 (15:38 +0200)
committerAlexander Barton <alex@barton.de>
Sat, 31 Mar 2012 13:38:46 +0000 (15:38 +0200)
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.

contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj
src/ngircd/Makefile.am
src/ngircd/irc-login.c
src/ngircd/login.c [new file with mode: 0644]
src/ngircd/login.h [new file with mode: 0644]

index b6e51c7ff7a6d05081b9bd308a3e213f4800e2b3..d3098f4d62a5cbfe33ef6c3e7e3281abadbaf12f 100644 (file)
@@ -41,6 +41,7 @@
                FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA3D2790F139CDC00B2447E /* conn-ssl.c */; };
                FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA97C55124A271400D5BBA9 /* sighandlers.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 */; };
 /* End PBXBuildFile section */
 
                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>"; };
                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>"; };
                FAE22BD415270EA300F1A5AB /* Contributing.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Contributing.txt; sourceTree = "<group>"; };
                FAE22BD515270EB500F1A5AB /* HowToRelease.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = HowToRelease.txt; sourceTree = "<group>"; };
                                FA322CFF0CEF74B1001761B3 /* lists.h */,
                                FA322D000CEF74B1001761B3 /* log.c */,
                                FA322D010CEF74B1001761B3 /* log.h */,
+                               FAD5853615272C2500328741 /* login.c */,
+                               FAD5853715272C2500328741 /* login.h */,
                                FA322D030CEF74B1001761B3 /* match.c */,
                                FA322D040CEF74B1001761B3 /* match.h */,
                                FA322D050CEF74B1001761B3 /* messages.h */,
                                FA2D564A11EA158B00D37A35 /* pam.c in Sources */,
                                FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */,
                                FAACD5F514A6099C006ED74F /* class.c in Sources */,
+                               FAD5853815272C2600328741 /* login.c in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index cacd1c3c8a8f0d5571d213b51949c1e52649da3f..e96d14bee835d7a73246bc1a709b13eb5f4792e8 100644 (file)
@@ -42,6 +42,7 @@ ngircd_SOURCES = \
        irc-write.c \
        lists.c \
        log.c \
+       login.c \
        match.c \
        numeric.c \
        op.c \
@@ -81,6 +82,7 @@ noinst_HEADERS = \
        irc-write.h \
        lists.h \
        log.h \
+       login.h \
        match.h \
        messages.h \
        numeric.h \
index 53069f00ff24c7e749db0e18a53f0d65ccbfc1d4..bf3254c985807e62ff24232e46ab1f6babc32752 100644 (file)
 
 #include "imp.h"
 #include <assert.h>
-#include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 #include <strings.h>
-#include <signal.h>
-#include <unistd.h>
 
-#include "ngircd.h"
 #include "conn-func.h"
 #include "class.h"
 #include "conf.h"
 #include "channel.h"
-#include "io.h"
 #include "log.h"
+#include "login.h"
 #include "messages.h"
-#include "pam.h"
 #include "parse.h"
 #include "irc.h"
 #include "irc-info.h"
 #include "exp.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 ));
-#ifdef PAM
-static void cb_Read_Auth_Result PARAMS((int r_fd, UNUSED short events));
-#endif
 
 /**
  * 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
                         * register the new client! */
                        if( Client_Type( Client ) == CLIENT_GOTUSER )
-                               return Hello_User( Client );
+                               return Login_User( Client );
                        else
                                Client_SetType( Client, CLIENT_GOTNICK );
                } else {
@@ -452,7 +440,7 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
                LogDebug("Connection %d: got valid USER command ...",
                    Client_Conn(Client));
                if (Client_Type(Client) == CLIENT_GOTNICK)
-                       return Hello_User(Client);
+                       return Login_User(Client);
                else
                        Client_SetType(Client, CLIENT_GOTUSER);
                return CONNECTED;
@@ -875,7 +863,7 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
                if (auth_ping == atoi(Req->argv[0])) {
                        Conn_SetAuthPing(conn, 0);
                        if (Client_Type(Client) == CLIENT_WAITAUTHPING)
-                               Hello_User(Client);
+                               Login_User(Client);
                } else
                        if (!IRC_WriteStrClient(Client,
                                        "To connect, type /QUOTE PONG %ld",
@@ -898,196 +886,6 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
 } /* 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.
  *
diff --git a/src/ngircd/login.c b/src/ngircd/login.c
new file mode 100644 (file)
index 0000000..2c30540
--- /dev/null
@@ -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- */
diff --git a/src/ngircd/login.h b/src/ngircd/login.h
new file mode 100644 (file)
index 0000000..6e3a21d
--- /dev/null
@@ -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- */