]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/irc-info.c
IRC_USERHOST(): respect hostname cloaking
[ngircd-alex.git] / src / ngircd / irc-info.c
index 28722e71fca86b388a3a63a5166afed15c5c4790..3da4c83ff00937ed2bb6dd7486e2cd24800db819 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2009 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
  *
  * 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
@@ -25,9 +25,7 @@
 #include "ngircd.h"
 #include "conn-func.h"
 #include "conn-zip.h"
-#include "client.h"
 #include "channel.h"
-#include "resolve.h"
 #include "conf.h"
 #include "defines.h"
 #include "log.h"
@@ -629,42 +627,51 @@ IRC_TIME( CLIENT *Client, REQUEST *Req )
 } /* IRC_TIME */
 
 
+/**
+ * Handler for the IRC command "USERHOST".
+ * See RFC 2812 section 4.8.
+ */
 GLOBAL bool
-IRC_USERHOST( CLIENT *Client, REQUEST *Req )
+IRC_USERHOST(CLIENT *Client, REQUEST *Req)
 {
        char rpl[COMMAND_LEN];
        CLIENT *c;
        int max, i;
 
-       assert( Client != NULL );
-       assert( Req != NULL );
+       assert(Client != NULL);
+       assert(Req != NULL);
 
-       if(( Req->argc < 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
+       if ((Req->argc < 1))
+               return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+                                         Client_ID(Client), Req->command);
 
-       if( Req->argc > 5 ) max = 5;
-       else max = Req->argc;
+       if (Req->argc > 5)
+               max = 5;
+       else
+               max = Req->argc;
 
-       strlcpy( rpl, RPL_USERHOST_MSG, sizeof rpl );
-       for( i = 0; i < max; i++ )
-       {
-               c = Client_Search( Req->argv[i] );
-               if( c && ( Client_Type( c ) == CLIENT_USER ))
-               {
+       strlcpy(rpl, RPL_USERHOST_MSG, sizeof rpl);
+       for (i = 0; i < max; i++) {
+               c = Client_Search(Req->argv[i]);
+               if (c && (Client_Type(c) == CLIENT_USER)) {
                        /* This Nick is "online" */
-                       strlcat( rpl, Client_ID( c ), sizeof( rpl ));
-                       if( Client_HasMode( c, 'o' )) strlcat( rpl, "*", sizeof( rpl ));
-                       strlcat( rpl, "=", sizeof( rpl ));
-                       if( Client_HasMode( c, 'a' )) strlcat( rpl, "-", sizeof( rpl ));
-                       else strlcat( rpl, "+", sizeof( rpl ));
-                       strlcat( rpl, Client_User( c ), sizeof( rpl ));
-                       strlcat( rpl, "@", sizeof( rpl ));
-                       strlcat( rpl, Client_Hostname( c ), sizeof( rpl ));
-                       strlcat( rpl, " ", sizeof( rpl ));
+                       strlcat(rpl, Client_ID(c), sizeof(rpl));
+                       if (Client_HasMode(c, 'o'))
+                               strlcat(rpl, "*", sizeof(rpl));
+                       strlcat(rpl, "=", sizeof(rpl));
+                       if (Client_HasMode(c, 'a'))
+                               strlcat(rpl, "-", sizeof(rpl));
+                       else
+                               strlcat(rpl, "+", sizeof(rpl));
+                       strlcat(rpl, Client_User(c), sizeof(rpl));
+                       strlcat(rpl, "@", sizeof(rpl));
+                       strlcat(rpl, Client_HostnameCloaked(c), sizeof(rpl));
+                       strlcat(rpl, " ", sizeof(rpl));
                }
        }
-       ngt_TrimLastChr( rpl, ' ');
+       ngt_TrimLastChr(rpl, ' ');
 
-       return IRC_WriteStrClient( Client, rpl, Client_ID( Client ) );
+       return IRC_WriteStrClient(Client, rpl, Client_ID(Client));
 } /* IRC_USERHOST */
 
 
@@ -941,8 +948,11 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
 
        if(( Client_NextHop( target ) != Client_ThisServer( )) && ( Client_Type( Client_NextHop( target )) == CLIENT_SERVER )) return IRC_WriteStrClientPrefix( target, from, "WHOIS %s :%s", Req->argv[0], Req->argv[1] );
 
-       /* Nick, user and name */
-       if( ! IRC_WriteStrClient( from, RPL_WHOISUSER_MSG, Client_ID( from ), Client_ID( c ), Client_User( c ), Client_Hostname( c ), Client_Info( c ))) return DISCONNECTED;
+       /* Nick, user, hostname and client info */
+       if (!IRC_WriteStrClient(from, RPL_WHOISUSER_MSG, Client_ID(from),
+                               Client_ID(c), Client_User(c),
+                               Client_HostnameCloaked(c), Client_Info(c)))
+               return DISCONNECTED;
 
        /* Server */
        if( ! IRC_WriteStrClient( from, RPL_WHOISSERVER_MSG, Client_ID( from ), Client_ID( c ), Client_ID( Client_Introducer( c )), Client_Info( Client_Introducer( c )))) return DISCONNECTED;
@@ -993,6 +1003,13 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
                if( ! IRC_WriteStrClient( from, RPL_WHOISOPERATOR_MSG, Client_ID( from ), Client_ID( c ))) return DISCONNECTED;
        }
 
+       /* Connected using SSL? */
+       if (Conn_UsesSSL(Client_Conn(c))) {
+               if (!IRC_WriteStrClient
+                   (from, RPL_WHOISSSL_MSG, Client_ID(from), Client_ID(c)))
+                       return DISCONNECTED;
+       }
+
        /* Idle and signon time (local clients only!) */
        if (Client_Conn(c) > NONE ) {
                if (! IRC_WriteStrClient(from, RPL_WHOISIDLE_MSG,
@@ -1176,6 +1193,10 @@ IRC_Send_LUSERS( CLIENT *Client )
        if(! IRC_WriteStrClient(Client, RPL_NETUSERS_MSG, Client_ID(Client),
                        cnt, max, cnt, max))
                return DISCONNECTED;
+       /* Connection counters */
+       if (! IRC_WriteStrClient(Client, RPL_STATSCONN_MSG, Client_ID(Client),
+                       Conn_CountMax(), Conn_CountAccepted()))
+               return DISCONNECTED;
 #endif
        
        return CONNECTED;
@@ -1222,45 +1243,30 @@ static inline bool Show_MOTD_SSLInfo(UNUSED CLIENT *c) { return true; }
 GLOBAL bool
 IRC_Show_MOTD( CLIENT *Client )
 {
-       char line[127];
-       FILE *fd;
+       const char *line;
+       size_t len_tot, len_str;
 
        assert( Client != NULL );
 
-       if (Conf_MotdPhrase[0]) {
-               if (!Show_MOTD_Start(Client))
-                       return DISCONNECTED;
-               if (!Show_MOTD_Sendline(Client, Conf_MotdPhrase))
-                       return DISCONNECTED;
-               goto out;
-       }
+       len_tot = array_bytes(&Conf_Motd);
+       if (len_tot == 0 && !Conn_UsesSSL(Client_Conn(Client)))
+               return IRC_WriteStrClient(Client, ERR_NOMOTD_MSG, Client_ID(Client));
 
-       fd = fopen( Conf_MotdFile, "r" );
-       if( ! fd ) {
-               Log( LOG_WARNING, "Can't read MOTD file \"%s\": %s", Conf_MotdFile, strerror( errno ));
-               if (Conn_UsesSSL(Client_Conn(Client))) {
-                       if (!Show_MOTD_Start(Client))
-                               return DISCONNECTED;
-                       goto out;
-               }
-               return IRC_WriteStrClient( Client, ERR_NOMOTD_MSG, Client_ID( Client ) );
-       }
+       if (!Show_MOTD_Start(Client))
+               return DISCONNECTED;
 
-       if (!Show_MOTD_Start( Client )) {
-               fclose(fd);
-               return false;
-       }
+       line = array_start(&Conf_Motd);
+       while (len_tot > 0) {
+               len_str = strlen(line) + 1;
 
-       while (fgets( line, (int)sizeof line, fd )) {
-               ngt_TrimLastChr( line, '\n');
+               assert(len_tot >= len_str);
+               len_tot -= len_str;
 
-               if( ! Show_MOTD_Sendline( Client, line)) {
-                       fclose( fd );
-                       return false;
-               }
+               if (!Show_MOTD_Sendline(Client, line))
+                       return DISCONNECTED;
+               line += len_str;
        }
-       fclose(fd);
-out:
+
        if (!Show_MOTD_SSLInfo(Client))
                return DISCONNECTED;
        return Show_MOTD_End(Client);