]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/conn.c
New configuration option "OperChanPAutoOp"
[ngircd-alex.git] / src / ngircd / conn.c
index 09f726ca2bf91016d54a8d2b2c7c10029943fa68..f4511642c7c7b309c0e302de58cd7e184c172166 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
+ * 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
 # include <netinet/ip.h>
 #endif
 
-#ifdef HAVE_STDINT_H
-# include <stdint.h>                   /* e.g. for Mac OS X */
-#endif
-
 #ifdef TCPWRAP
 # include <tcpd.h>                     /* for TCP Wrappers */
 #endif
@@ -88,7 +84,7 @@
 
 static bool Handle_Write PARAMS(( CONN_ID Idx ));
 static bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
-static int New_Connection PARAMS(( int Sock ));
+static int New_Connection PARAMS(( int Sock, bool IsSSL ));
 static CONN_ID Socket2Index PARAMS(( int Sock ));
 static void Read_Request PARAMS(( CONN_ID Idx ));
 static unsigned int Handle_Buffer PARAMS(( CONN_ID Idx ));
@@ -134,7 +130,7 @@ static void
 cb_listen(int sock, short irrelevant)
 {
        (void) irrelevant;
-       (void) New_Connection(sock);
+       (void) New_Connection(sock, false);
 }
 
 
@@ -152,7 +148,7 @@ cb_listen_ssl(int sock, short irrelevant)
        int fd;
 
        (void) irrelevant;
-       fd = New_Connection(sock);
+       fd = New_Connection(sock, true);
        if (fd < 0)
                return;
        io_event_setcb(My_Connections[fd].sock, cb_clientserver_ssl);
@@ -918,6 +914,30 @@ va_dcl
        return ok;
 } /* Conn_WriteStr */
 
+GLOBAL char*
+Conn_Password( CONN_ID Idx )
+{
+       assert( Idx > NONE );
+       if (My_Connections[Idx].pwd == NULL)
+               return (char*)"\0";
+       else
+               return My_Connections[Idx].pwd;
+} /* Conn_Password */
+
+GLOBAL void
+Conn_SetPassword( CONN_ID Idx, const char *Pwd )
+{
+       assert( Idx > NONE );
+
+       if (My_Connections[Idx].pwd)
+               free(My_Connections[Idx].pwd);
+
+       My_Connections[Idx].pwd = strdup(Pwd);
+       if (My_Connections[Idx].pwd == NULL) {
+               Log(LOG_EMERG, "Can't allocate memory! [Conn_SetPassword]");
+               exit(1);
+       }
+} /* Conn_SetPassword */
 
 /**
  * Append Data to the outbound write buffer of a connection.
@@ -1146,6 +1166,8 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
 
        array_free(&My_Connections[Idx].rbuf);
        array_free(&My_Connections[Idx].wbuf);
+       if (My_Connections[Idx].pwd != NULL)
+               free(My_Connections[Idx].pwd);
 
        /* Clean up connection structure (=free it) */
        Init_Conn_Struct( Idx );
@@ -1336,17 +1358,18 @@ Count_Connections(ng_ipaddr_t *a)
  * Initialize new client connection on a listening socket.
  *
  * @param Sock Listening socket descriptor.
+ * @param IsSSL        true if this socket expects SSL-encrypted data.
  * @returns    Accepted socket descriptor or -1 on error.
  */
 static int
-New_Connection(int Sock)
+New_Connection(int Sock, UNUSED bool IsSSL)
 {
 #ifdef TCPWRAP
        struct request_info req;
 #endif
        ng_ipaddr_t new_addr;
        char ip_str[NG_INET_ADDRSTRLEN];
-       int new_sock, new_sock_len, identsock;
+       int new_sock, new_sock_len;
        CLIENT *c;
        long cnt;
 
@@ -1466,30 +1489,56 @@ New_Connection(int Sock)
        Log(LOG_INFO, "Accepted connection %d from %s:%d on socket %d.",
            new_sock, My_Connections[new_sock].host,
            ng_ipaddr_getport(&new_addr), Sock);
+       Account_Connection();
+
+#ifdef SSL_SUPPORT
+       /* Delay connection initalization until SSL handshake is finished */
+       if (!IsSSL)
+#endif
+               Conn_StartLogin(new_sock);
+
+       return new_sock;
+} /* New_Connection */
+
+
+/**
+ * Finish connection initialization, start resolver subprocess.
+ *
+ * @param Idx Connection index.
+ */
+GLOBAL void
+Conn_StartLogin(CONN_ID Idx)
+{
+       int ident_sock = -1;
+
+       assert(Idx >= 0);
+
+       /* Nothing to do if DNS (and resolver subprocess) is disabled */
+       if (!Conf_DNS)
+               return;
 
-       identsock = new_sock;
 #ifdef IDENTAUTH
-       if (!Conf_Ident)
-               identsock = -1;
+       /* Should we make an IDENT request? */
+       if (Conf_Ident)
+               ident_sock = My_Connections[Idx].sock;
 #endif
-       if (Conf_DNS) {
-               if (Conf_NoticeAuth) {
+
+       if (Conf_NoticeAuth) {
+               /* Send "NOTICE AUTH" messages to the client */
 #ifdef IDENTAUTH
-                       if (Conf_Ident)
-                               (void)Conn_WriteStr(new_sock,
-                                       "NOTICE AUTH :*** Looking up your hostname and checking ident");
-                       else
+               if (Conf_Ident)
+                       (void)Conn_WriteStr(Idx,
+                               "NOTICE AUTH :*** Looking up your hostname and checking ident");
+               else
 #endif
-                               (void)Conn_WriteStr(new_sock,
-                                       "NOTICE AUTH :*** Looking up your hostname");
-               }
-               Resolve_Addr(&My_Connections[new_sock].proc_stat, &new_addr,
-                            identsock, cb_Read_Resolver_Result);
+                       (void)Conn_WriteStr(Idx,
+                               "NOTICE AUTH :*** Looking up your hostname");
+               (void)Handle_Write(Idx);
        }
 
-       Account_Connection();
-       return new_sock;
-} /* New_Connection */
+       Resolve_Addr(&My_Connections[Idx].proc_stat, &My_Connections[Idx].addr,
+                    ident_sock, cb_Read_Resolver_Result);
+}
 
 
 /**
@@ -1839,10 +1888,10 @@ Check_Connections(void)
                                if (My_Connections[i].lastping <
                                    time(NULL) - Conf_PongTimeout) {
                                        /* Timeout */
-                                       LogDebug
-                                           ("Connection %d: Ping timeout: %d seconds.",
-                                            i, Conf_PongTimeout);
-                                       snprintf(msg, sizeof(msg), "Ping timeout: %d seconds", Conf_PongTimeout);
+                                       snprintf(msg, sizeof(msg),
+                                                "Ping timeout: %d seconds",
+                                                Conf_PongTimeout);
+                                       LogDebug("Connection %d: %s.", i, msg);
                                        Conn_Close(i, NULL, msg, true);
                                }
                        } else if (My_Connections[i].lastdata <
@@ -1935,6 +1984,14 @@ New_Server( int Server , ng_ipaddr_t *dest)
 
        assert( Server > NONE );
 
+       /* Make sure that the remote server hasn't re-linked to this server
+        * asynchronously on its own */
+       if (Conf_Server[Server].conn_id > NONE) {
+               Log(LOG_INFO,
+                       "Connection to \"%s\" meanwhile re-established, aborting preparation.");
+               return;
+       }
+
        if (!ng_ipaddr_tostr_r(dest, ip_str)) {
                Log(LOG_WARNING, "New_Server: Could not convert IP to string");
                return;
@@ -2008,7 +2065,7 @@ New_Server( int Server , ng_ipaddr_t *dest)
        Client_SetToken( c, TOKEN_OUTBOUND );
 
        /* Register connection */
-       Conf_Server[Server].conn_id = new_sock;
+       Conf_SetServer(Server, new_sock);
        My_Connections[new_sock].sock = new_sock;
        My_Connections[new_sock].addr = *dest;
        My_Connections[new_sock].client = c;
@@ -2223,7 +2280,8 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
                Client_SetHostname(c, readbuf);
                if (Conf_NoticeAuth)
                        (void)Conn_WriteStr(i,
-                                       "NOTICE AUTH :*** Found your hostname");
+                                       "NOTICE AUTH :*** Found your hostname: %s",
+                                       My_Connections[i].host);
 #ifdef IDENTAUTH
                ++identptr;
                if (*identptr) {
@@ -2248,8 +2306,10 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
                        }
                        if (Conf_NoticeAuth) {
                                (void)Conn_WriteStr(i,
-                                       "NOTICE AUTH :*** Got %sident response",
-                                       *ptr ? "invalid " : "");
+                                       "NOTICE AUTH :*** Got %sident response%s%s",
+                                       *ptr ? "invalid " : "",
+                                       *ptr ? "" : ": ",
+                                       *ptr ? "" : identptr);
                        }
                } else {
                        Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
@@ -2258,6 +2318,10 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
                                        "NOTICE AUTH :*** No ident response");
                }
 #endif
+
+               if (Conf_NoticeAuth)
+                       (void)Handle_Write(i);
+
                Class_HandleServerBans(c);
        }
 #ifdef DEBUG