Added OpenSSL support, ported from diff distributed against 1.4.x bahamut
authorMatthew Mondor <mmondor@pulsar-zone.net>
Thu, 13 Jan 2005 10:38:30 +0000 (10:38 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Thu, 13 Jan 2005 10:38:30 +0000 (10:38 +0000)
19 files changed:
configure
include/config.h
include/confparse.h
include/h.h
include/numeric.h
include/ssl.h [new file with mode: 0644]
include/struct.h
src/Makefile.in
src/bsd.c
src/channel.c
src/ircd.c
src/m_who.c
src/s_bsd.c
src/s_conf.c
src/s_err.c
src/s_misc.c
src/s_serv.c
src/s_user.c
src/ssl.c [new file with mode: 0644]

index 7f5fb61..cb42f4c 100755 (executable)
--- a/configure
+++ b/configure
@@ -5678,6 +5678,8 @@ if test "X$cf_enable_openssl" != "Xno" ; then
     echo "$as_me:$LINENO: result: $cf_openssl_basedir" >&5
 echo "${ECHO_T}$cf_openssl_basedir" >&6
     cf_enable_openssl="yes"
+       USESSL="-DUSE_SSL"
+       SSLLIB="-lssl"
     encryption="enabled"
     cat >>confdefs.h <<\_ACEOF
 #define HAVE_ENCRYPTION_ON 1
@@ -7726,6 +7728,8 @@ s,@PACKAGE@,$PACKAGE,;t t
 s,@VERSION@,$VERSION,;t t
 s,@CC@,$CC,;t t
 s,@CFLAGS@,$CFLAGS,;t t
+s,@USESSL@,$USESSL,;t t
+s,@SSLLIB@,$SSLLIB,;t t
 s,@LDFLAGS@,$LDFLAGS,;t t
 s,@CPPFLAGS@,$CPPFLAGS,;t t
 s,@ac_ct_CC@,$ac_ct_CC,;t t
index 011829f..e52366c 100644 (file)
@@ -18,7 +18,7 @@
  *
  */
 
-/* $Id: config.h,v 1.4 2005/01/13 09:11:39 mmondor Exp $ */
+/* $Id: config.h,v 1.5 2005/01/13 10:35:43 mmondor Exp $ */
 
 #ifndef        __config_include__
 #define        __config_include__
  */
 #define FAKEHOST
 
+/* SSL
+ * SSL support stolen from fqircd
+ */
+#ifdef USE_SSL
+#define IRCDSSL_KPATH "ircd.key"
+#define IRCDSSL_CPATH "ircd.crt"
+
+#define RECV_CHECK_SSL(from, buf, len) (IsSSL(from) && from->ssl) ?\
+                                       safe_SSL_read(from, buf, len) :\
+                                       recv(from->fd, buf, len, 0)
+#define SEND_CHECK_SSL(to, buf, len) (IsSSL(to) && to->ssl) ?\
+                                       safe_SSL_write(to, buf, len) :\
+                                       send(to->fd, buf, len, 0)
+
+#define WRITEV_CHECK_SSL(to, iov, len) (IsSSL(to) && to->ssl) ?\
+                                                                               safe_SSL_write(to,iov->iov_base,iov->iov_len) :\
+                                                                               writev(to->fd, iov, len);
+#endif
+
+
 /******************************************************************
  * STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP STOP
  *
index c45c874..d3492d7 100644 (file)
@@ -4,7 +4,7 @@
  * Apply the GPL here.
  */
 
-/* $Id: confparse.h,v 1.2 2005/01/13 06:19:56 mmondor Exp $ */
+/* $Id: confparse.h,v 1.3 2005/01/13 10:35:43 mmondor Exp $ */
 
 /* our structures */
 
@@ -288,6 +288,9 @@ sConf confporttab[] =
     {SCONFT_PORT, SCONFF_PORT, VARTYPE_INT},
     {SCONFT_BIND, SCONFF_BIND, VARTYPE_NAME},
     {SCONFT_IPMASK, SCONFF_IPMASK, VARTYPE_NAME},
+#ifdef USE_SSL
+       {SCONFT_TYPE, SCONFF_TYPE, VARTYPE_NAME},
+#endif
     {(char *) 0, 0, 0}
 };
 
index a14c10f..2f54788 100644 (file)
@@ -25,7 +25,7 @@
  * 
  */
 
-/* $Id: h.h,v 1.1 2005/01/12 07:44:58 mmondor Exp $ */
+/* $Id: h.h,v 1.2 2005/01/13 10:35:43 mmondor Exp $ */
 
 #include "send.h"
 #include "ircsprintf.h"
@@ -336,3 +336,7 @@ void remove_from_list(DLink **, void *, DLink *);
 void print_list_memory(aClient *);
 
 #include "find.h"
+
+#ifdef USE_SSL
+#include "ssl.h"
+#endif
index b21a88e..768f220 100644 (file)
@@ -18,7 +18,7 @@
  *
  */
 
-/* $Id: numeric.h,v 1.1 2005/01/12 07:44:58 mmondor Exp $ */
+/* $Id: numeric.h,v 1.2 2005/01/13 10:35:43 mmondor Exp $ */
 
 
 #define        RPL_WELCOME          001
 #define RPL_SILELIST         271
 #define RPL_ENDOFSILELIST    272
 
+#ifdef USE_SSL
+#define RPL_USINGSSL         275
+#endif
+
 #define        RPL_NONE             300
 #define RPL_AWAY             301
 #define RPL_USERHOST         302
 #define ERR_NONONREG         486
 #define ERR_MSGSERVICES      487
 
+#ifdef USE_SSL
+#define ERR_NOSSL            488
+#endif
+
 #define ERR_NOOPERHOST       491
 
 #define ERR_UMODEUNKNOWNFLAG 501
diff --git a/include/ssl.h b/include/ssl.h
new file mode 100644 (file)
index 0000000..0435a6e
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __SSL_INCLUDE__
+#define __SSL_INCLUDE__
+
+int safe_SSL_read(aClient *, void *, int);
+int safe_SSL_write(aClient *, const void *, int);
+int safe_SSL_accept(aClient *, int);
+int SSL_smart_shutdown(SSL *);
+int initssl(void);
+int rehash_ssl(void);
+
+#endif
index 446936f..76275a3 100644 (file)
@@ -20,7 +20,7 @@
  *
  */
 
-/* $Id: struct.h,v 1.4 2005/01/13 06:21:18 mmondor Exp $ */
+/* $Id: struct.h,v 1.5 2005/01/13 10:35:43 mmondor Exp $ */
 
 #ifndef        __struct_include__
 #define __struct_include__
 #endif
 #endif
 
+#ifdef USE_SSL
+
+#include <openssl/rsa.h>       /* OpenSSL stuff */
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+#endif
+
 #define REPORT_DO_DNS_    ":%s NOTICE AUTH :*** Looking up your hostname..."
 #define REPORT_FIN_DNS_           ":%s NOTICE AUTH :*** Found your hostname"
 #define REPORT_FIN_DNSC_   ":%s NOTICE AUTH :*** Found your hostname, cached"
@@ -230,6 +241,9 @@ typedef struct MotdItem aMotd;
 #define FLAGS_RC4OUT       0x2000000  /* This link is rc4 encrypted. */
 #define FLAGS_ZIPPED_IN           0x4000000  /* This link is gzipped. */
 #define FLAGS_ZIPPED_OUT   0x8000000 /* This link is gzipped. */
+#ifdef USE_SSL
+#define FLAGS_SSL          0x20000000 /* client is using SSL */
+#endif
 
 /* Capabilities of the ircd or clients */
 
@@ -291,9 +305,9 @@ typedef struct MotdItem aMotd;
 #define UMODE_h     0x20000     /* umode +h - Helper */
 #define UMODE_m     0x40000     /* umode +m - spambot notices */
 #define UMODE_R     0x80000     /* unmode +R - No non registered msgs */
-#ifdef DCCALLOW
+/* #define UMODE_e */
 #define UMODE_e     0x100000    /* umode +e - oper notices for the above +D */
-#endif
+/* #endif */
 #define UMODE_x     0x200000    /* umode +x - Squelch with notice */
 #define UMODE_X     0x400000    /* umode +X - Squelch without notice */
 #ifdef DCCALLOW
@@ -303,6 +317,10 @@ typedef struct MotdItem aMotd;
 #define UMODE_j            0x2000000   /* umode +j - client rejection notices */
 #define UMODE_K     0x4000000   /* umode +K - U: lined server kill messages */
 #define UMODE_I     0x8000000   /* umode +I - invisible oper (masked) */
+#ifdef USE_SSL
+#define UMODE_S     0x10000000  /* umode +S - SSL user */
+#endif
+
 
 /* for sendto_ops_lev */
 
@@ -379,6 +397,9 @@ typedef struct MotdItem aMotd;
 #define        IsUmodek(x)             ((x)->umode & UMODE_k)
 #define        IsUmodes(x)             ((x)->umode & UMODE_s)
 #define        IsUmodeI(x)             ((x)->umode & UMODE_I)
+#ifdef USE_SSL
+#define IsUmodeS(x)            ((x)->umode & UMODE_S)
+#endif
 #define IsNoNonReg(x)           ((x)->umode & UMODE_R)
 #define IsWSquelch(x)           ((x)->umode & UMODE_x)
 #define IsSSquelch(x)           ((x)->umode & UMODE_X)
@@ -401,6 +422,11 @@ typedef struct MotdItem aMotd;
 #define SendGlobops(x)          ((x)->umode & UMODE_g)
 #define SendChatops(x)          ((x)->umode & UMODE_b)
 #define SendRnotice(x)          ((x)->umode & UMODE_n)
+#ifdef USE_SSL
+#define IsSSL(x)                ((x)->flags & FLAGS_SSL)
+#define SetSSL(x)               ((x)->flags |= FLAGS_SSL)
+#define SetSSLUmode(x)          ((x)->umode |= UMODE_S)
+#endif
 #define NoMsgThrottle(x)       ((x)->umode & UMODE_F)
 #define        IsListening(x)          ((x)->flags & FLAGS_LISTEN)
 #define        IsLocal(x)              ((x)->flags & FLAGS_LOCAL)
@@ -758,6 +784,7 @@ struct Conf_Port
        char *allow;
        char *address;
        int   port;
+       char *type;
     aListener *lstn;
        int   legal;
        aPort *next;
@@ -794,6 +821,12 @@ struct Listener {
         u_long          ccount;   /* total number of clients to connect here */
         int             clients;  /* number of clients currently on this */
         aPort           *aport;   /* link to the P: line I came from */
+#ifdef USE_SSL
+               long                    flags;
+        SSL             *ssl;
+        X509            *client_cert;
+#endif
+
 };
 
 
@@ -987,6 +1020,10 @@ struct Client
                                 * this socket? */
     int capabilities;           /* what this server/client supports */
     aClass  *class;             /* our current effective class */
+#ifdef USE_SSL
+    SSL     *ssl;
+    X509    *client_cert;
+#endif
 
 #ifdef MSG_TARGET_LIMIT
     struct {
@@ -1240,6 +1277,10 @@ struct Channel
 #define MODE_MODREG     0x10000
 #define MODE_LISTED    0x20000
 #define MODE_JOINRATE  0x40000
+#ifdef USE_SSL
+#define MODE_SSL        0x80000
+#endif
+
 
 /* mode flags which take another parameter (With PARAmeterS) */
 
@@ -1463,6 +1504,8 @@ typedef struct SearchOptions
 /* internal defines for cptr->sockerr */
 #define IRCERR_BUFALLOC           -11
 #define IRCERR_ZIP        -12
+#define IRCERR_SSL         -13
+
 
 #endif /* __struct_include__ */
 
index 3abbff2..2f7035a 100644 (file)
@@ -1,7 +1,7 @@
 CC=@CC@
 RM=@RM@
 MV=@MV@
-IRCDLIBS=@LIBS@ ../zlib/libz.a
+IRCDLIBS=@LIBS@ ../zlib/libz.a @SSLLIB@
 INCLUDEDIR=-I../include
 OPENSSLINC=@SSL_INCLUDES@
 ENGINE=@SENGINE@
@@ -9,7 +9,7 @@ CRYPTO=@ENCRYPT_SRC@
 INSTALL=@INSTALL@
 INSTALL_BIN=@INSTALL_PROGRAM@
 INSTALL_DIR=@INSTALL_DIR@
-CFLAGS=@CFLAGS@
+CFLAGS=@CFLAGS@ 
 
 RES_SRC =
 
@@ -22,7 +22,7 @@ SOURCES = blalloc.c bsd.c channel.c clientlist.c clones.c confparse.c \
           modules.c packet.c parse.c pcre.c res.c s_auth.c s_bsd.c s_conf.c \
           s_debug.c s_err.c s_misc.c s_numeric.c s_serv.c s_user.c sbuf.c \
           scache.c send.c struct.c support.c throttle.c userban.c whowas.c \
-          zlink.c \
+          zlink.c ssl.c \
           $(ENGINE) $(CRYPTO)
 
 OBJECTS = $(SOURCES:.c=.o) version.o
@@ -307,6 +307,8 @@ whowas.o: whowas.c ../include/struct.h ../include/config.h \
   ../include/sbuf.h ../include/common.h ../include/sys.h \
   ../include/numeric.h ../include/h.h ../include/send.h \
   ../include/fdlist.h ../include/ircsprintf.h ../include/find.h
+ssl.o: ssl.c \
+../include/ssl.h
 
 dh.o: dh.c \
  ../include/patchlevel.h
index 08cc2b0..dc4ba5c 100644 (file)
--- a/src/bsd.c
+++ b/src/bsd.c
@@ -18,7 +18,7 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* $Id: bsd.c,v 1.1 2005/01/12 07:44:56 mmondor Exp $ */
+/* $Id: bsd.c,v 1.2 2005/01/13 10:35:43 mmondor Exp $ */
 
 #include "struct.h"
 #include "common.h"
@@ -84,10 +84,18 @@ int deliver_it(aClient *cptr, char *str, int len)
     writecalls++;
 #endif
 #ifdef WRITEV_IOV
+#ifdef USE_SSL
+       retval = WRITEV_CHECK_SSL(cptr, iov, len);
+#else
     retval = writev(cptr->fd, iov, len);
+#endif
+#else
+#ifdef USE_SSL
+    retval = SEND_CHECK_SSL(cptr, str, len);
 #else
     retval = send(cptr->fd, str, len, 0);
 #endif
+#endif
     /*
      * Convert WOULDBLOCK to a return of "0 bytes moved". This 
      * should occur only if socket was non-blocking. Note, that all is
index ae8182a..31ea9ef 100644 (file)
@@ -18,7 +18,7 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* $Id: channel.c,v 1.1 2005/01/12 07:44:56 mmondor Exp $ */
+/* $Id: channel.c,v 1.2 2005/01/13 10:35:43 mmondor Exp $ */
 
 #include "struct.h"
 #include "common.h"
@@ -1026,6 +1026,11 @@ static void channel_modes(aClient *cptr, char *mbuf, char *pbuf,
         *mbuf++ = 'O';
     if (chptr->mode.mode & MODE_MODREG)
         *mbuf++ = 'M';
+#ifdef USE_SSL
+    if (chptr->mode.mode & MODE_SSL)
+        *mbuf++ = 'S';
+#endif
+
 #ifdef USE_CHANMODE_L
     if (chptr->mode.mode & MODE_LISTED)
         *mbuf++ = 'L';
@@ -1387,6 +1392,9 @@ static int set_mode(aClient *cptr, aClient *sptr, aChannel *chptr,
         MODE_TOPICLIMIT, 't', MODE_REGONLY, 'R',
         MODE_INVITEONLY, 'i', MODE_NOCOLOR, 'c', MODE_OPERONLY, 'O',
         MODE_MODREG, 'M', 
+#ifdef USE_SSL
+        MODE_SSL, 'S',
+#endif
 #ifdef USE_CHANMODE_L
         MODE_LISTED, 'L',
 #endif
@@ -2173,6 +2181,13 @@ static int can_join(aClient *sptr, aChannel *chptr, char *key)
         r = "+l";
         error = ERR_CHANNELISFULL;
     }
+#ifdef USE_SSL
+    else if (chptr->mode.mode & MODE_SSL && !IsSSL(sptr) && !IsOper(sptr))
+    {
+        r = "+S";
+        error = ERR_NOSSL;
+    }
+#endif
     else if (chptr->mode.mode & MODE_REGONLY && !IsRegNick(sptr))
         error = ERR_NEEDREGGEDNICK;
     else if (*chptr->mode.key && (BadPtr(key) || mycmp(chptr->mode.key, key)))
@@ -4197,6 +4212,9 @@ int m_sjoin(aClient *cptr, aClient *sptr, int parc, char *parv[])
             SJ_MODEADD('M', MODE_MODREG);
             SJ_MODEADD('c', MODE_NOCOLOR);
             SJ_MODEADD('O', MODE_OPERONLY);
+#ifdef USE_SSL
+               SJ_MODEADD('S', MODE_SSL);
+#endif
 #ifdef USE_CHANMODE_L
             SJ_MODEADD('L', MODE_LISTED);
 #endif
@@ -4356,6 +4374,10 @@ int m_sjoin(aClient *cptr, aClient *sptr, int parc, char *parv[])
 #ifdef USE_CHANMODE_L
         SJ_MODEPLUS('L', MODE_LISTED);
 #endif
+#ifdef USE_SSL
+    SJ_MODEPLUS('S', MODE_SSL);
+#endif
+
 
         SJ_MODEMINUS('p', MODE_PRIVATE);
         SJ_MODEMINUS('s', MODE_SECRET);
@@ -4371,6 +4393,9 @@ int m_sjoin(aClient *cptr, aClient *sptr, int parc, char *parv[])
 #ifdef USE_CHANMODE_L
         SJ_MODEMINUS('L', MODE_LISTED);
 #endif
+#ifdef USE_SSL
+    SJ_MODEMINUS('S', MODE_SSL);
+#endif
 
     }
 
index d7d7076..cbd3194 100644 (file)
@@ -18,7 +18,7 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* $Id: ircd.c,v 1.1 2005/01/12 07:44:56 mmondor Exp $ */
+/* $Id: ircd.c,v 1.2 2005/01/13 10:35:44 mmondor Exp $ */
 
 #include "struct.h"
 #include "common.h"
@@ -656,6 +656,9 @@ main(int argc, char *argv[])
     char        tmp[PATH_MAX];
     FILE        *mcsfp;
     char        *conferr;
+#ifdef USE_SSL
+    extern int ssl_capable;
+#endif
         
     if ((timeofday = time(NULL)) == -1) 
     {
@@ -895,6 +898,18 @@ main(int argc, char *argv[])
     R_fail_id = strlen(REPORT_FAIL_ID);
         
     NOW = time(NULL);
+
+#ifdef USE_SSL
+    fprintf(stderr, "SSL: Trying to intialize SSL support . . .\n");
+    if(!(ssl_capable = initssl()))
+        fprintf(stderr, "SSL: failure. (did you generate your "
+                "certificate ?)\nSSL: Server running with SSL "
+                "code disabled, consult the above error log for "
+                "details.\n");
+    else
+        fprintf(stderr, "SSL: success.\n");
+#endif
+
         
     init_sys();
     forked = 1;
index a556464..7d54061 100644 (file)
@@ -20,7 +20,7 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* $Id: m_who.c,v 1.1 2005/01/12 07:44:56 mmondor Exp $ */
+/* $Id: m_who.c,v 1.2 2005/01/13 10:35:44 mmondor Exp $ */
 
 #include "struct.h"
 #include "common.h"
@@ -724,10 +724,19 @@ int m_who(aClient *cptr, aClient *sptr, int parc, char *parv[])
            }
            else
            {
+#ifdef USE_SSL
+               i = 0;
+               status[i++]=(ac->user->away==NULL ? 'H' : 'G');
+               status[i]=(IsAnOper(ac) ? '*' : (IsInvisible(ac) &&
+                                                                                IsAnOper(sptr) ? '%' : 0));
+               status[((status[i]) ? ++i : i)]=(IsUmodeS(ac) ? 'S' : 0);
+               status[++i]=0;
+#else
                status[0]=(ac->user->away==NULL ? 'H' : 'G');
                status[1]=(IsAnOper(ac) ? '*' : (IsInvisible(ac) &&
                                                 IsAnOper(sptr) ? '%' : 0));
                status[2]=0;
+#endif
                sendto_one(sptr, getreply(RPL_WHOREPLY), me.name, sptr->name,
                           wsopts.show_chan ? first_visible_channel(ac, sptr)
                           : "*", ac->user->username, WHO_HOST(ac),
@@ -765,6 +774,10 @@ int m_who(aClient *cptr, aClient *sptr, int parc, char *parv[])
                status[i++]=(ac->user->away==NULL ? 'H' : 'G');
                status[i]=(IsAnOper(ac) ? '*' : ((IsInvisible(ac) &&
                                                  IsOper(sptr)) ? '%' : 0));
+#ifdef USE_SSL
+                status[((status[i]) ? ++i : i)]=(IsUmodeS(ac) ? 'S' : 0);
+#endif
+
                status[((status[i]) ? ++i : i)]=((cm->flags&CHFL_CHANOP) ? 
                                                 '@' : ((cm->flags&CHFL_VOICE)
                                                        ? '+' : 0));
index 3af59b8..a0bf5ba 100644 (file)
@@ -18,7 +18,7 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* $Id: s_bsd.c,v 1.1 2005/01/12 07:44:57 mmondor Exp $ */
+/* $Id: s_bsd.c,v 1.2 2005/01/13 10:35:44 mmondor Exp $ */
 
 #include "struct.h"
 #include "common.h"
@@ -61,6 +61,8 @@
 #include "fdlist.h"
 #include "fds.h"
 
+
+
 extern void      engine_init();
 extern fdlist default_fdlist;
 extern int forked;
@@ -274,6 +276,10 @@ int add_listener(aPort *aport)
     struct sockaddr_in server;
     int ad[4], len = sizeof(server);
     char ipname[20];
+#ifdef USE_SSL
+    extern int ssl_capable;
+#endif
+
 
     memset(&lstn, 0, sizeof(aListener));
     ad[0] = ad[1] = ad[2] = ad[3] = 0;
@@ -360,6 +366,16 @@ int add_listener(aPort *aport)
     aport->lstn = lptr;
 
     set_listener_non_blocking(lptr->fd, lptr);
+
+#ifdef USE_SSL
+    if(aport->type && (strcmp(aport->type, "SSL")) == 0 && ssl_capable) {
+        SetSSL(lptr);
+        lptr->ssl = NULL;
+        lptr->client_cert = NULL;
+    }
+#endif
+
+
     add_fd(lptr->fd, FDT_LISTENER, lptr);
     set_fd_flags(lptr->fd, FDF_WANTREAD);
 
@@ -895,8 +911,20 @@ void close_connection(aClient *cptr)
 
     if (cptr->fd >= 0)
     {
+#ifdef USE_SSL
+        if(!IsDead(cptr))
+#endif
         dump_connections(cptr->fd);
         local[cptr->fd] = NULL;
+#ifdef USE_SSL
+        if(IsSSL(cptr) && cptr->ssl) {
+            SSL_set_shutdown(cptr->ssl, SSL_RECEIVED_SHUTDOWN);
+            SSL_smart_shutdown(cptr->ssl);
+            SSL_free(cptr->ssl);
+            cptr->ssl = NULL;
+        }
+#endif
+
         del_fd(cptr->fd);
         close(cptr->fd);
         cptr->fd = -2;
@@ -1299,6 +1327,45 @@ aClient *add_connection(aListener *lptr, int fd)
     start_auth(acptr);
 #endif
     check_client_fd(acptr);
+#ifdef USE_SSL
+    if (IsSSL(lptr))
+    {
+        extern SSL_CTX *ircdssl_ctx;
+
+        acptr->ssl = NULL;
+
+        /*SSL client init.*/
+        if((acptr->ssl = SSL_new(ircdssl_ctx)) == NULL)
+        {
+          sendto_realops_lev(DEBUG_LEV, "SSL creation of "
+                    "new SSL object failed [client %s]",
+                    acptr->sockhost);
+          fprintf(stderr, "SSL creation of "
+                    "new SSL object failed [client %s]\n", acptr->sockhost );
+            ircstp->is_ref++;
+            acptr->fd = -2;
+            free_client(acptr);
+            return NULL ;
+        }
+        SetSSL(acptr);
+        set_non_blocking(fd, acptr);
+        set_sock_opts(fd, acptr);
+        SSL_set_fd(acptr->ssl, fd);
+
+        if (!safe_SSL_accept(acptr, fd))
+        {
+            SSL_set_shutdown(acptr->ssl, SSL_RECEIVED_SHUTDOWN);
+            SSL_smart_shutdown(acptr->ssl);
+            SSL_free(acptr->ssl);
+            ircstp->is_ref++;
+            acptr->fd = -2;
+            free_client(acptr);
+            (void) close(fd);
+            return NULL;
+        }
+    }
+#endif
+
     return acptr;
 }
 
@@ -1382,7 +1449,19 @@ int read_packet(aClient * cptr)
     if (!(IsPerson(cptr) && SBufLength(&cptr->recvQ) > MAX_CLIENT_RECVQ)) 
     {
         errno = 0;
-    
+   
+#ifdef USE_SSL
+#if defined ( MAXBUFFERS )
+        if (IsPerson(cptr))
+            length = RECV_CHECK_SSL(cptr, readbuf, 8192 * sizeof(char));
+        else
+            length = RECV_CHECK_SSL(cptr, readbuf, rcvbufmax * sizeof(char));
+#else
+            length = RECV_CHECK_SSL(cptr, readbuf, sizeof(readbuf));
+#endif
+
+#else
 #if defined(MAXBUFFERS)
         if (IsPerson(cptr))
             length = recv(cptr->fd, readbuf, 8192 * sizeof(char), 0);
@@ -1392,6 +1471,8 @@ int read_packet(aClient * cptr)
         length = recv(cptr->fd, readbuf, sizeof(readbuf), 0);
 #endif
 
+#endif
+
         cptr->lasttime = timeofday;
         if (cptr->lasttime > cptr->since)
             cptr->since = cptr->lasttime;
@@ -1561,6 +1642,15 @@ int readwrite_client(aClient *cptr, int isread, int iswrite)
      * - the socket is waiting for a connect() call
      * - the socket is blocked
      */
+#ifdef USE_SSL
+    if (cptr->ssl != NULL && IsSSL(cptr) &&
+            !SSL_is_init_finished(cptr->ssl))
+    {
+        if(IsDead(cptr) || (!safe_SSL_accept(cptr, cptr->fd)))
+            close_connection(cptr);
+        return 1;
+    }
+#endif
 
     if(iswrite)
     {
index 16c2dee..08954c7 100644 (file)
@@ -18,7 +18,7 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* $Id: s_conf.c,v 1.3 2005/01/13 08:04:03 mmondor Exp $ */
+/* $Id: s_conf.c,v 1.4 2005/01/13 10:35:45 mmondor Exp $ */
 
 #include "struct.h"
 #include "common.h"
@@ -196,6 +196,9 @@ free_oper(aOper *ptr)
 void
 free_port(aPort *ptr)
 {
+#ifdef USE_SSL
+       MyFree(ptr->type);
+#endif
     MyFree(ptr->allow);
     MyFree(ptr->address);
     MyFree(ptr);
@@ -1262,6 +1265,19 @@ confadd_port(cVar *vars[], int lnum)
             tmp->type = NULL;
             x->port = atoi(tmp->value);
         }
+#ifdef USE_SSL
+               else if(tmp->type && (tmp->type->flag & SCONFF_TYPE))
+               {
+                       if (x->type)
+                       {
+                               confparse_error("Multiple port types", lnum);
+                               free_port(x);
+                               return -1;
+                       }
+                       tmp->type = NULL;
+                       DupString(x->type, tmp->value);
+               }
+#endif
     }
     if(!(x->port > 0))
     {
index 565f831..7baca0f 100644 (file)
@@ -300,7 +300,7 @@ static char *replies[] =
     /* 272 RPL_ENDOFSILELIST*/ ":%s 272 %s :End of /SILENCE list.",
     /* 273 */                  NULL,
     /* 274 */                  NULL,
-    /* 275 */                  NULL,   /* In use by Undernet */
+    /* 275 */                   ":%s 275 %s %s :is using a secure connection (SSL)",
     /* 276 */                  NULL,
     /* 277 */                  NULL,
     /* 278 */                  NULL,
@@ -552,7 +552,8 @@ static char *replies[] =
                                 "registered nick to private message %s",
     /* 487 ERR_MSGSERVICES */  ":%s 487 %s :Error! \"/msg %s\" is no longer supported. "
                                 "Use \"/msg %s@%s\" or \"/%s\" instead.",
-    /* 488 */                  NULL,
+    /* 488 ERR_NOPRIVILEGES */  ":%s 488 %s :SSL Only channel (+S), You must connect "
+                                "using SSL to join this channel.",
     /* 489 */                  NULL,   /* In use by Undernet */
     /* 490 */                  NULL,
     /* 491 ERR_NOOPERHOST */   ":%s 491 %s :No Oper block for your host",
index ee7dc69..09e8228 100644 (file)
@@ -21,7 +21,7 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* $Id: s_misc.c,v 1.2 2005/01/13 06:20:45 mmondor Exp $ */
+/* $Id: s_misc.c,v 1.3 2005/01/13 10:35:45 mmondor Exp $ */
 
 #include <sys/time.h>
 #include "struct.h"
@@ -683,7 +683,11 @@ exit_client(aClient *cptr, aClient *sptr, aClient *from, char *comment)
             }
         }
 #endif
-        if (sptr->fd >= 0) 
+        if (sptr->fd >= 0
+#ifdef USE_SSL
+                && !IsDead(sptr)
+#endif
+) 
         {
             if (cptr != NULL && sptr != cptr)
                 sendto_one(sptr, "ERROR :Closing Link: %s %s (%s)",
index 7acba49..f045e12 100644 (file)
@@ -21,7 +21,7 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* $Id: s_serv.c,v 1.1 2005/01/12 07:44:57 mmondor Exp $ */
+/* $Id: s_serv.c,v 1.2 2005/01/13 10:35:45 mmondor Exp $ */
 
 #include "struct.h"
 #include "common.h"
@@ -2421,6 +2421,17 @@ m_rehash(aClient *cptr, aClient *sptr, int parc, char *parv[])
             remove_simbans_match_flags(SBAN_CHAN|SBAN_TEMPORARY, 0);
             return 0;
         }
+#ifdef USE_SSL
+        else if(mycmp(parv[1], "SSL") == 0)
+        {
+            sendto_ops("%s is reloading SSL support", parv[0]);
+            sendto_one(sptr, rpl_str(RPL_REHASHING), me.name, parv[0],
+                 "SSL support");
+
+            rehash_ssl();
+        }
+#endif
+
     }
     else 
     {
index 2db04b5..364bc6d 100644 (file)
@@ -21,7 +21,7 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/* $Id: s_user.c,v 1.3 2005/01/13 06:20:45 mmondor Exp $ */
+/* $Id: s_user.c,v 1.4 2005/01/13 10:35:45 mmondor Exp $ */
 
 #include "struct.h"
 #include "common.h"
@@ -90,6 +90,9 @@ int  user_modes[] =
     UMODE_x, 'x',
     UMODE_X, 'X',
     UMODE_j, 'j',
+#ifdef USE_SSL
+    UMODE_S, 'S',
+#endif
     UMODE_K, 'K',
     UMODE_I, 'I',
     0, 0
@@ -998,9 +1001,16 @@ register_user(aClient *cptr, aClient *sptr, char *nick, char *username)
                        client_set_fakehost(sptr,pwaconf);
 #endif
 
+#ifdef USE_SSL
+        sendto_realops_lev(CCONN_LEV, "Client connecting: %s (%s@%s) [%s] {%d} %s",
+                           nick, user->username, user->host, sptr->hostip,
+                           sptr->class->name, IsSSL(sptr) ? "SSL" : "");
+#else
+
         sendto_realops_lev(CCONN_LEV, "Client connecting: %s (%s@%s) [%s] {%s}",
                            nick, user->username, user->host, sptr->hostip,
                            sptr->class->name);
+#endif
 
         send_lusers(sptr, sptr, 1, parv);
                 
@@ -2036,6 +2046,11 @@ m_whois(aClient *cptr, aClient *sptr, int parc, char *parv[])
         if (user->away)
             sendto_one(sptr, rpl_str(RPL_AWAY), me.name, parv[0], name, 
                        user->away);
+#ifdef USE_SSL
+        if (IsUmodeS(acptr))
+            sendto_one(sptr, rpl_str(RPL_USINGSSL), me.name, parv[0], name);
+#endif
+
         
         buf[0] = '\0';
         if (IsAnOper(acptr))
@@ -2132,6 +2147,10 @@ do_user(char *nick, aClient *cptr, aClient *sptr, char *username, char *host,
 #ifndef NO_DEFAULT_INVISIBLE
         sptr->umode |= UMODE_i;
 #endif
+#ifdef USE_SSL
+        if(IsSSL(sptr))
+            SetSSLUmode(sptr);
+#endif
 #ifdef NO_USER_SERVERKILLS
         sptr->umode &= ~UMODE_k;
 #endif
diff --git a/src/ssl.c b/src/ssl.c
new file mode 100644 (file)
index 0000000..554c504
--- /dev/null
+++ b/src/ssl.c
@@ -0,0 +1,292 @@
+/************************************************************************
+ *   IRC - Internet Relay Chat, src/ssl.c
+ *   Copyright (C) 2002 Barnaba Marcello <vjt@azzurra.org>
+ *
+ *   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 1, or (at your option)
+ *   any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *   
+ *   SSL functions . . .
+ */
+
+#include "struct.h"
+#include "common.h"
+#include "sys.h"
+#include <sys/types.h>
+#include "h.h"
+
+#ifdef USE_SSL
+
+
+#define SAFE_SSL_READ  1
+#define SAFE_SSL_WRITE 2
+#define SAFE_SSL_ACCEPT        3
+
+extern int errno;
+
+SSL_CTX *ircdssl_ctx;
+int ssl_capable = 0;
+
+int initssl(void)
+{
+    SSL_load_error_strings();
+    SSLeay_add_ssl_algorithms();
+    ircdssl_ctx = SSL_CTX_new(SSLv23_server_method());
+    if (!ircdssl_ctx) {
+       ERR_print_errors_fp(stderr);
+       return 0;
+    }
+    if (SSL_CTX_use_certificate_file(ircdssl_ctx,
+               IRCDSSL_CPATH, SSL_FILETYPE_PEM) <= 0) {
+       ERR_print_errors_fp(stderr);
+       SSL_CTX_free(ircdssl_ctx);
+       return 0;
+    }
+    if (SSL_CTX_use_PrivateKey_file(ircdssl_ctx,
+               IRCDSSL_KPATH, SSL_FILETYPE_PEM) <= 0) {
+       ERR_print_errors_fp(stderr);
+       SSL_CTX_free(ircdssl_ctx);
+       return 0;
+    }
+    if (!SSL_CTX_check_private_key(ircdssl_ctx)) {
+       fprintf(stderr, "Server certificate does not match Server key");
+       SSL_CTX_free(ircdssl_ctx);
+       return 0;
+    }
+    return 1;
+}
+
+static void disable_ssl(int do_errors)
+{
+    if(do_errors)
+    {
+       char buf[256];
+       unsigned long e;
+
+       while((e = ERR_get_error()))
+       {
+           ERR_error_string_n(e, buf, sizeof(buf) - 1);
+           sendto_realops("SSL ERROR: %s", buf);
+       }
+    }
+
+    if(ircdssl_ctx)
+       SSL_CTX_free(ircdssl_ctx);
+
+    sendto_ops("Disabling SSL support due to unrecoverable SSL errors. /Rehash again to retry.");
+    ssl_capable = 0;
+    
+    return;
+}
+
+int rehash_ssl(void)
+{
+    if(ircdssl_ctx)
+       SSL_CTX_free(ircdssl_ctx);
+
+    if(!(ircdssl_ctx = SSL_CTX_new(SSLv23_server_method())))
+    {
+       disable_ssl(1);
+       return 0;
+    }
+
+    if (SSL_CTX_use_certificate_file(ircdssl_ctx,
+               IRCDSSL_CPATH, SSL_FILETYPE_PEM) <= 0)
+    {
+       disable_ssl(1);
+
+       return 0;
+    }
+
+    if (SSL_CTX_use_PrivateKey_file(ircdssl_ctx,
+               IRCDSSL_KPATH, SSL_FILETYPE_PEM) <= 0)
+    {
+       disable_ssl(1);
+
+       return 0;
+    }
+
+    if (!SSL_CTX_check_private_key(ircdssl_ctx)) 
+    {
+       sendto_realops("SSL ERROR: Server certificate does not match server key");
+       disable_ssl(0);
+
+       return 0;
+    }
+
+    return 1;
+}
+
+static int fatal_ssl_error(int, int, aClient *);
+
+int safe_SSL_read(aClient *acptr, void *buf, int sz)
+{
+    int len, ssl_err;
+
+    len = SSL_read(acptr->ssl, buf, sz);
+    if (len <= 0)
+    {
+       switch(ssl_err = SSL_get_error(acptr->ssl, len)) {
+           case SSL_ERROR_SYSCALL:
+               if (errno == EWOULDBLOCK || errno == EAGAIN ||
+                       errno == EINTR) {
+           case SSL_ERROR_WANT_READ:
+                   errno = EWOULDBLOCK;
+                   return 0;
+               }
+           case SSL_ERROR_SSL:
+               if(errno == EAGAIN)
+                   return 0;
+           default:
+               return fatal_ssl_error(ssl_err, SAFE_SSL_READ, acptr);
+       }
+    }
+    return len;
+}
+
+int safe_SSL_write(aClient *acptr, const void *buf, int sz)
+{
+    int len, ssl_err;
+
+    len = SSL_write(acptr->ssl, buf, sz);
+    if (len <= 0)
+    {
+       switch(ssl_err = SSL_get_error(acptr->ssl, len)) {
+           case SSL_ERROR_SYSCALL:
+               if (errno == EWOULDBLOCK || errno == EAGAIN ||
+                       errno == EINTR) {
+           case SSL_ERROR_WANT_WRITE:
+           case SSL_ERROR_WANT_READ:
+                   errno = EWOULDBLOCK;
+                   return 0;
+               }
+           case SSL_ERROR_SSL:
+               if(errno == EAGAIN)
+                   return 0;
+           default:
+               return fatal_ssl_error(ssl_err, SAFE_SSL_WRITE, acptr);
+       }
+    }
+    return len;
+}
+
+int safe_SSL_accept(aClient *acptr, int fd) {
+
+    int ssl_err;
+
+    if((ssl_err = SSL_accept(acptr->ssl)) <= 0) {
+       switch(ssl_err = SSL_get_error(acptr->ssl, ssl_err)) {
+           case SSL_ERROR_SYSCALL:
+               if (errno == EINTR || errno == EWOULDBLOCK
+                       || errno == EAGAIN)
+           case SSL_ERROR_WANT_READ:
+           case SSL_ERROR_WANT_WRITE:
+                   /* handshake will be completed later . . */
+                   return 1;
+           default:
+               return fatal_ssl_error(ssl_err, SAFE_SSL_ACCEPT, acptr);
+               
+       }
+       /* NOTREACHED */
+       return -1;
+    }
+    return 1;
+}
+
+int SSL_smart_shutdown(SSL *ssl) {
+    char i;
+    int rc;
+
+    rc = 0;
+    for(i = 0; i < 4; i++) {
+       if((rc = SSL_shutdown(ssl)))
+           break;
+    }
+
+    return rc;
+}
+
+static int fatal_ssl_error(int ssl_error, int where, aClient *sptr)
+{
+    /* don`t alter errno */
+    int errtmp = errno;
+    char *errstr = strerror(errtmp);
+    char *ssl_errstr, *ssl_func;
+
+    switch(where) {
+       case SAFE_SSL_READ:
+           ssl_func = "SSL_read()";
+           break;
+       case SAFE_SSL_WRITE:
+           ssl_func = "SSL_write()";
+           break;
+       case SAFE_SSL_ACCEPT:
+           ssl_func = "SSL_accept()";
+           break;
+       default:
+           ssl_func = "undefined SSL func [this is a bug] report to vjt@azzurra.org";
+    }
+
+    switch(ssl_error) {
+       case SSL_ERROR_NONE:
+           ssl_errstr = "No error";
+           break;
+       case SSL_ERROR_SSL:
+           ssl_errstr = "Internal OpenSSL error or protocol error";
+           break;
+       case SSL_ERROR_WANT_READ:
+           ssl_errstr = "OpenSSL functions requested a read()";
+           break;
+       case SSL_ERROR_WANT_WRITE:
+           ssl_errstr = "OpenSSL functions requested a write()";
+           break;
+       case SSL_ERROR_WANT_X509_LOOKUP:
+           ssl_errstr = "OpenSSL requested a X509 lookup which didn`t arrive";
+           break;
+       case SSL_ERROR_SYSCALL:
+           ssl_errstr = "Underlying syscall error";
+           break;
+       case SSL_ERROR_ZERO_RETURN:
+           ssl_errstr = "Underlying socket operation returned zero";
+           break;
+       case SSL_ERROR_WANT_CONNECT:
+           ssl_errstr = "OpenSSL functions wanted a connect()";
+           break;
+       default:
+           ssl_errstr = "Unknown OpenSSL error (huh?)";
+    }
+
+    sendto_realops_lev(DEBUG_LEV, "%s to "
+               "%s!%s@%s aborted with%serror (%s). [%s]", 
+               ssl_func, *sptr->name ? sptr->name : "<unknown>",
+               (sptr->user && sptr->user->username) ? sptr->user->
+               username : "<unregistered>", sptr->sockhost,
+               (errno > 0) ? " " : " no ", errstr, ssl_errstr);
+#ifdef USE_SYSLOG
+    syslog(LOG_ERR, "SSL error in %s: %s [%s]", ssl_func, errstr,
+           ssl_errstr);
+#endif
+
+    /* if we reply() something here, we might just trigger another
+     * fatal_ssl_error() call and loop until a stack overflow... 
+     * the client won`t get the ERROR : ... string, but this is
+     * the only way to do it.
+     * IRC protocol wasn`t SSL enabled .. --vjt
+     */
+
+    errno = errtmp ? errtmp : EIO; /* Stick a generic I/O error */
+    sptr->sockerr = IRCERR_SSL;
+    sptr->flags |= FLAGS_DEADSOCKET;
+    return -1;
+}
+#endif