diff -uPr ircd-hybrid-7.0.3/autoconf/configure.in ircd-hybrid-7.0.3-ssl/autoconf/configure.in
--- ircd-hybrid-7.0.3/autoconf/configure.in	Sat May 31 00:30:23 2003
+++ ircd-hybrid-7.0.3-ssl/autoconf/configure.in	Sun Aug 29 16:24:09 2004
@@ -421,7 +421,7 @@
                 cf_openssl_ciphers="${cf_openssl_ciphers}DES/56 ")
         fi
         CPPFLAGS="$save_CPPFLAGS"
-        SSL_LIBS="$SSL_LIBS -lcrypto"
+        SSL_LIBS="$SSL_LIBS -lcrypto -lssl"
     else
         AC_MSG_RESULT(no - OpenSSL support disabled)
     fi
diff -uPr ircd-hybrid-7.0.3/configure ircd-hybrid-7.0.3-ssl/configure
--- ircd-hybrid-7.0.3/configure	Sat May 31 00:30:18 2003
+++ ircd-hybrid-7.0.3-ssl/configure	Sun Aug 29 17:43:48 2004
@@ -5860,7 +5860,7 @@
 
         fi
         CPPFLAGS="$save_CPPFLAGS"
-        SSL_LIBS="$SSL_LIBS -lcrypto"
+        SSL_LIBS="$SSL_LIBS -lcrypto -lssl"
     else
         echo "$as_me:$LINENO: result: no - OpenSSL support disabled" >&5
 echo "${ECHO_T}no - OpenSSL support disabled" >&6
diff -uPr ircd-hybrid-7.0.3/doc/example.conf ircd-hybrid-7.0.3-ssl/doc/example.conf
--- ircd-hybrid-7.0.3/doc/example.conf	Sat May 31 00:30:25 2003
+++ ircd-hybrid-7.0.3-ssl/doc/example.conf	Sun Aug 29 16:24:09 2004
@@ -86,6 +86,20 @@
 	 *	chmod 0644 rsa.pub
 	 */
 	#rsa_private_key_file = "/usr/local/ircd/etc/rsa.key";
+	
+	/* SSL certificate file, used for client SSL connections
+	 *
+	 * Assuming your private RSA key is stored in rsa.key, you
+	 * must first create a certificate request, then sign it:
+	 *
+	 *  openssl req -new -key rsa.key -out cert.csr
+	 *  openssl x509 -req -in cert.csr -extensions v3_ca \
+	 *   -signkey rsa.key -out cert.pem -trustout
+	 *												-demond
+     *
+     * (see http://www.openssl.org//docs/HOWTO/certificates.txt)
+	 */
+	#ssl_certificate_file = "/usr/local/ircd/etc/cert.pem";
 };
 
 /* admin {}: contains admin information about the server. (OLD A:) */
@@ -169,6 +183,11 @@
 	
 	/* port: listen on all available IPs, ports 6665 to 6669 */
 	port = 6665 .. 6669;
+
+	/* sslport: listen for client SSL connections ONLY!
+	 *											-demond
+	 */
+	sslport = 8181;
 
 	/* host: set a specific IP/host the ports after the line will listen 
 	 * on.  This may be ipv4 or ipv6.
diff -uPr ircd-hybrid-7.0.3/include/channel_mode.h ircd-hybrid-7.0.3-ssl/include/channel_mode.h
--- ircd-hybrid-7.0.3/include/channel_mode.h	Mon Oct 28 14:09:20 2002
+++ ircd-hybrid-7.0.3-ssl/include/channel_mode.h	Sun Aug 29 17:45:55 2004
@@ -100,6 +101,7 @@
 #define MODE_EXCEPTION  0x0800
 #define MODE_INVEX	0x2000
 #define MODE_HIDEOPS    0x4000
+#define MODE_SSLONLY   0x20000	/* only SSL-connected clients allowed */
 
 /*
  * mode flags which take another parameter (With PARAmeterS)
@@ -118,6 +120,7 @@
 #define ParanoidChannel(x)	((x) && ((x)->mode.mode &\
 			        (MODE_PRIVATE|MODE_INVITEONLY))==\
 		                (MODE_PRIVATE|MODE_INVITEONLY))
+#define SSLonlyChannel(x)		((x) && ((x)->mode.mode & MODE_SSLONLY))
 
 struct ChModeChange
 {
diff -uPr ircd-hybrid-7.0.3/include/client.h ircd-hybrid-7.0.3-ssl/include/client.h
--- ircd-hybrid-7.0.3/include/client.h	Sat Oct 25 19:08:12 2003
+++ ircd-hybrid-7.0.3-ssl/include/client.h	Sun Aug 29 18:16:16 2004
@@ -61,6 +61,47 @@
 struct Client;
 struct LocalUser;
 
+struct Repeat
+{
+	struct Channel *chptr;		/* last phrase block */
+	char *text;
+	time_t lastphrase;
+};
+
+struct SLink;
+struct Watch;
+
+typedef struct Client 	aClient;
+typedef struct Channel 	aChannel;
+typedef struct ConfItem aConfItem;
+typedef struct Watch 	aWatch;
+typedef struct Ban 		aBan;
+
+typedef struct SLink Link;
+
+struct SLink
+{
+    struct SLink	*next;
+    union
+    {
+		aClient		*cptr;
+		aChannel	*chptr;
+		aConfItem	*aconf;
+		aBan		*banptr;
+		aWatch		*wptr;
+		char		*cp;
+    } value;
+    int				flags;
+};
+
+struct Watch
+{
+    aWatch	*hnext;
+    time_t	lasttime;
+    Link	*watch;
+    char	nick[1];
+};
+
 /*
  * Client structures
  */
@@ -353,6 +395,7 @@
 
 #define IsOper(x)		((x)->umodes & FLAGS_OPER)
 #define IsAdmin(x)		((x)->umodes & FLAGS_ADMIN)
+#define IsSSLaccept(x)	((x)->umodes & FLAGS_SSLACCEPT)
 
 #define SetConnecting(x)        {(x)->status = STAT_CONNECTING; \
 				 (x)->handler = UNREGISTERED_HANDLER; }
@@ -435,6 +478,7 @@
 /* user information flags, only settable by remote mode or local oper */
 #define FLAGS_OPER         0x20000 /* Operator */
 #define FLAGS_ADMIN        0x40000 /* Admin on server */
+#define FLAGS_SSLACCEPT    0x80000 /* accepting from SSL-connected clients only */
 
 #define FLAGS_ALL	   FLAGS_SERVNOTICE
 
@@ -472,16 +516,15 @@
 #define FLAGS2_PING_COOKIE	0x20000		/* PING Cookie */
 #define FLAGS2_IDLE_LINED       0x40000
 #define FLAGS2_IP_SPOOFING      0x80000        /* client IP is spoofed */
-#define FLAGS2_FLOODDONE        0x200000      /* Flood grace period has
-                                               * been ended. */
+#define FLAGS2_FLOODDONE        0x200000	/* Flood grace period has been ended. */
 
 #define SEND_UMODES  (FLAGS_INVISIBLE | FLAGS_OPER | FLAGS_WALLOP | \
-                      FLAGS_ADMIN)
+                      FLAGS_ADMIN | FLAGS_SSLACCEPT)
 #define ALL_UMODES   (SEND_UMODES | FLAGS_SERVNOTICE | FLAGS_CCONN | \
                       FLAGS_REJ | FLAGS_SKILL | FLAGS_FULL | FLAGS_SPY | \
                       FLAGS_NCHANGE | FLAGS_OPERWALL | FLAGS_DEBUG | \
                       FLAGS_BOTS | FLAGS_EXTERNAL | FLAGS_LOCOPS | \
- 		      FLAGS_ADMIN | FLAGS_UNAUTH | FLAGS_CALLERID)
+ 		      FLAGS_UNAUTH | FLAGS_CALLERID )
 
 #define FLAGS_ID     (FLAGS_NEEDID | FLAGS_GOTID)
 
@@ -518,6 +561,8 @@
 #define IsCanFlood(x)		((x)->flags & FLAGS_CANFLOOD)
 #define IsDefunct(x)            ((x)->flags & (FLAGS_DEADSOCKET|FLAGS_CLOSING| \
 					       FLAGS_KILLED))
+#define SetSSLaccept(x)         ((x)->umodes |= FLAGS_SSLACCEPT)
+#define IsSetSSLaccept(x)       ((x)->umodes & FLAGS_SSLACCEPT)
 
 /* oper flags */
 #define MyOper(x)               (MyConnect(x) && IsOper(x))
@@ -654,6 +699,9 @@
 extern void dead_link_on_read(struct Client *client_p, int error);
 extern void exit_aborted_clients(void);
 extern void free_exited_clients(void);
+
+#define MAXWATCH		128
+#define WATCHHASHSIZE	U_MAX/16	/* reasonable for bnet i think... -demond */
 
 #endif /* INCLUDED_client_h */
 
diff -uPr ircd-hybrid-7.0.3/include/fdlist.h ircd-hybrid-7.0.3-ssl/include/fdlist.h
--- ircd-hybrid-7.0.3/include/fdlist.h	Fri May 24 16:34:07 2002
+++ ircd-hybrid-7.0.3-ssl/include/fdlist.h	Sun Aug 29 16:45:21 2004
@@ -115,6 +115,10 @@
         unsigned int nonblocking:1;
         unsigned int ipc:1;
         unsigned int called_connect:1;
+#ifdef HAVE_LIBCRYPTO
+		unsigned int accept_read:1;
+		unsigned int accept_write:1;
+#endif        
     } flags;
     struct {
         /* We don't need the host here ? */
@@ -124,6 +128,10 @@
         void *data;
         /* We'd also add the retry count here when we get to that -- adrian */
     } connect;
+#ifdef HAVE_LIBCRYPTO
+	SSL *ssl;
+	int accept_failures;
+#endif
 };
 
 
@@ -131,7 +139,7 @@
 
 void fdlist_init(void);
 
-extern void  fd_open(int, unsigned int, const char *);
+extern void  fd_open(int, unsigned int, const char *, void *);
 extern void  fd_close(int);
 extern void  fd_dump(struct Client *source_p);
 #ifndef __GNUC__
diff -uPr ircd-hybrid-7.0.3/include/listener.h ircd-hybrid-7.0.3-ssl/include/listener.h
--- ircd-hybrid-7.0.3/include/listener.h	Fri May 24 16:34:07 2002
+++ ircd-hybrid-7.0.3-ssl/include/listener.h	Sun Aug 29 16:24:09 2004
@@ -45,9 +45,10 @@
   struct irc_inaddr addr;              /* virtual address or INADDR_ANY */
   struct DNSQuery   *dns_query;
   char             vhost[HOSTLEN + 1]; /* virtual name of listener */
+  int	is_ssl;
 };
 
-extern void        add_listener(int port, const char* vaddr_ip);
+extern void        add_listener(int port, const char* vaddr_ip, int is_ssl);
 extern void        close_listener(struct Listener* listener);
 extern void        close_listeners(void);
 extern const char* get_listener_name(const struct Listener* listener);
diff -uPr ircd-hybrid-7.0.3/include/numeric.h ircd-hybrid-7.0.3-ssl/include/numeric.h
--- ircd-hybrid-7.0.3/include/numeric.h	Sat Oct 25 19:08:13 2003
+++ ircd-hybrid-7.0.3-ssl/include/numeric.h	Sun Aug 29 17:50:41 2004
@@ -189,11 +189,9 @@
 /*      RPL_CHANINFO_KICK    295           aircd */
 /*	RPL_HELPIGN	     295	Numeric List: Dalnet */
 /*      RPL_CHANINFO_KICKS   296           aircd */
-
 /*      RPL_END_CHANINFO     299           aircd */
-
 /* numeric_replies */
-
+#define	RPL_WHOISSSL		 297 /* uses SSL */
 #define RPL_NONE             300
 #define RPL_AWAY             301
 #define RPL_USERHOST         302
@@ -207,6 +205,7 @@
 /*      RPL_NOTIFYACTION     308         aircd */
 /*	RPL_WHOISADMIN	     308	Numeric List: Dalnet */
 /*	RPL_RULESSTART	     308	unreal */
+#define RPL_WHOISADMIN       308
 /*      RPL_NICKTRACE        309         aircd */
 /*	RPL_WHOISSADMIN	     309	Numeric List: Dalnet */
 /*	RPL_ENDOFRULES	     309	unreal */
@@ -388,6 +387,7 @@
 #define ERR_MODELESS         477        /* ircu numeric -db */
 #define ERR_BANLISTFULL      478        /* I stole the numeric from ircu -db */
 #define ERR_BADCHANNAME      479
+#define ERR_SSLONLYCHAN      480	/* SSL-connected clients only channel */
 /* 	ERR_LINKFAIL	     479	unreal */
 /*	ERR_CANNOTKNOCK	     480	unreal */
 /*	ERR_NOULINE	     480	austnet */
@@ -407,16 +407,15 @@
 /*      ERR_TSLESSCHAN       488           IRCnet extension (?) */
 /*	ERR_VOICENEEDED      489           Undernet extension */
 #define ERR_NOOPERHOST       491
+#define ERR_DENIEDFROMCHAN   494
 /*      ERR_NOSERVICEHOST    492 	   IRCnet extension */
-
+#define ERR_SSLACCEPTONLY    498        /* accepting from SSL clients only */
+#define ERR_TOOMANYWATCH     500
 #define ERR_UMODEUNKNOWNFLAG 501
 #define ERR_USERSDONTMATCH   502
-
 #define ERR_GHOSTEDCLIENT    503
 /*	ERR_VWORLDWARN	     503	   austnet */
-
 #define ERR_USERNOTONSERV    504
-
 /* #define ERR_LAST_ERR_MSG 505 
  * moved to 999
  */
diff -uPr ircd-hybrid-7.0.3/include/s_bsd.h ircd-hybrid-7.0.3-ssl/include/s_bsd.h
--- ircd-hybrid-7.0.3/include/s_bsd.h	Wed Mar 17 20:57:21 2004
+++ ircd-hybrid-7.0.3-ssl/include/s_bsd.h	Sun Aug 29 16:24:09 2004
@@ -71,7 +71,7 @@
 extern const char * comm_errstr(int status);
 extern int   comm_open(int family, int sock_type, int proto,
                  const char *note);
-extern int   comm_accept(int fd, struct irc_sockaddr *pn);
+extern int   comm_accept(int fd, struct irc_sockaddr *pn, int is_ssl);
 
 /* These must be defined in the network IO loop code of your choice */
 extern void  comm_setselect(int fd, fdlist_t list, unsigned int type,
diff -uPr ircd-hybrid-7.0.3/include/s_conf.h ircd-hybrid-7.0.3-ssl/include/s_conf.h
--- ircd-hybrid-7.0.3/include/s_conf.h	Wed Mar 17 20:57:21 2004
+++ ircd-hybrid-7.0.3-ssl/include/s_conf.h	Sun Aug 29 17:52:00 2004
@@ -258,6 +259,8 @@
   int   use_invex;
   int   use_knock;
   int   use_vchans;
+  int	use_subst;
+  int	use_denies;
   int   knock_delay;
   int	knock_delay_channel;
   int   vchans_oper_only;
@@ -292,6 +295,9 @@
 #ifdef HAVE_LIBCRYPTO
   char *      rsa_private_key_file;
   RSA *       rsa_private_key;
+  char *      ssl_certificate_file;
+  SSL_CTX *   ctx;
+  SSL_METHOD *meth;
 #endif
   int         hub;
   struct      irc_inaddr ip;
diff -uPr ircd-hybrid-7.0.3/include/stdinc.h ircd-hybrid-7.0.3-ssl/include/stdinc.h
--- ircd-hybrid-7.0.3/include/stdinc.h	Fri May 24 16:39:13 2002
+++ ircd-hybrid-7.0.3-ssl/include/stdinc.h	Sun Aug 29 16:24:09 2004
@@ -99,3 +99,8 @@
 #ifdef VMS
 #include <sys/ioctl.h>
 #endif
+
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#endif
diff -uPr ircd-hybrid-7.0.3/include/supported.h ircd-hybrid-7.0.3-ssl/include/supported.h
--- ircd-hybrid-7.0.3/include/supported.h	Tue Jul 16 13:26:47 2002
+++ ircd-hybrid-7.0.3-ssl/include/supported.h	Sun Aug 29 16:24:09 2004
@@ -35,38 +35,69 @@
 #define CASEMAP "ascii"
 #endif
 
-#define FEATURES "WALLCHOPS"\
-                "%s%s%s%s" \
+#ifdef HAVE_LIBCRYPTO
+#define FEATURES "MASK SVS SSL WALLCHOPS"\
+                "%s%s%s%s%s" \
                 " MODES=%i" \
                 " MAXCHANNELS=%i" \
                 " MAXBANS=%i" \
                 " MAXTARGETS=%i" \
                 " NICKLEN=%i" \
                 " TOPICLEN=%i" \
-                " KICKLEN=%i"
+                " KICKLEN=%i" \
+                " WATCH=%i"
+#else                
+#define FEATURES "MASK SVS WALLCHOPS"\
+                "%s%s%s%s%s" \
+                " MODES=%i" \
+                " MAXCHANNELS=%i" \
+                " MAXBANS=%i" \
+                " MAXTARGETS=%i" \
+                " NICKLEN=%i" \
+                " TOPICLEN=%i" \
+                " KICKLEN=%i" \
+                " WATCH=%i"
+#endif
 
 #define FEATURESVALUES ConfigChannel.use_knock ? " KNOCK" : "", \
         ConfigChannel.use_vchans ? " VCHANS" : "", \
         ConfigChannel.use_except ? " EXCEPTS" : "", \
         ConfigChannel.use_invex ? " INVEX" : "", \
+        ConfigChannel.use_subst ? " SUBST" : "", \
         MAXMODEPARAMS,ConfigChannel.max_chans_per_user, \
         ConfigChannel.max_bans, \
-        ConfigFileEntry.max_targets,NICKLEN-1,TOPICLEN,TOPICLEN
+        ConfigFileEntry.max_targets,NICKLEN-1,TOPICLEN,TOPICLEN,MAXWATCH
 
 #define FEATURES2 "CHANTYPES=%s" \
                   " PREFIX=%s" \
-		  " CHANMODES=%s%s%s%s" \
+		  " CHANMODES=%s%s%s%s%s%s%s" \
 		  " NETWORK=%s" \
 		  " CASEMAPPING=%s" \
 		  " CALLERID"
 
+#ifdef USEPACE
+#define FEATURES2VALUES ConfigServerHide.disable_local_channels ? "#" : "#&", \
+                        ConfigChannel.use_halfops ? "(ohv)@%+" : "(ov)@+", \
+                        ConfigChannel.use_except ? "e" : "", \
+                        ConfigChannel.use_denies ? "d" : "", \
+                        ConfigChannel.use_invex ? "I" : "", \
+                        ConfigChannel.use_subst ? "w" : "", \
+                        "b,k,l,imnpst", \
+                        ConfigChannel.use_anonops ? "a" : "", \
+                        "crxzCMRS", \
+                        ServerInfo.network_name, CASEMAP
+#else                        
 #define FEATURES2VALUES ConfigServerHide.disable_local_channels ? "#" : "#&", \
                         ConfigChannel.use_halfops ? "(ohv)@%+" : "(ov)@+", \
                         ConfigChannel.use_except ? "e" : "", \
+                        ConfigChannel.use_denies ? "d" : "", \
                         ConfigChannel.use_invex ? "I" : "", \
+                        ConfigChannel.use_subst ? "w" : "", \
                         "b,k,l,imnpst", \
                         ConfigChannel.use_anonops ? "a" : "", \
+                        "crzCMRS", \
                         ServerInfo.network_name, CASEMAP
+#endif
 
 /*
  * - from mirc's versions.txt
diff -uPr ircd-hybrid-7.0.3/messages/ayb.po ircd-hybrid-7.0.3-ssl/messages/ayb.po
--- ircd-hybrid-7.0.3/messages/ayb.po	Sat Dec 15 13:35:12 2001
+++ ircd-hybrid-7.0.3-ssl/messages/ayb.po	Sun Aug 29 17:53:54 2004
@@ -287,6 +287,11 @@
 msgid   ":%s 282 %s :End of /ACCEPT list."
 msgstr  ""
 
+#: ../src/messages.tab:324
+#, c-format
+msgid   ":%s 297 %s %s :is connected via SSL (secure link)"
+msgstr  ":%s 297 %s %s :cannot be sniffed by feds (uses SSL)"
+
 #: ../src/messages.tab:328
 #, c-format
 msgid	":%s 301 %s %s :%s"
@@ -378,6 +383,11 @@
 msgid	":%s 324 %s %s %s %s"
 msgstr	""
 
+#: ../src/messages.tab:354
+#, c-format
+msgid	":%s 327 %s %s :logged on %s from %s"
+msgstr	":%s 327 %s %s :wastes bandwidth on %s from %s"
+
 #: ../src/messages.tab:356
 #, c-format
 msgid	":%s 329 %s %s %lu"
@@ -770,6 +780,11 @@
 msgid	":%s 479 %s %s :Illegal channel name"
 msgstr	""
 
+#: ../src/messages.tab:509
+#, c-format
+msgid	":%s 480 %s %s :Cannot join channel (+S)"
+msgstr	":%s 480 %s %s :You ain't on SSL connection bro... and we are"
+
 #: ../src/messages.tab:511
 #, fuzzy, c-format
 msgid	":%s 481 %s :Permission Denied - You're not an IRC operator"
@@ -804,6 +819,21 @@
 	"zone"
 msgstr	":%s 491 %s :Sorry, you just don't have what it takes to be an IRC "
 	"Operator here."
+
+#: ../src/messages.tab:525
+#, c-format
+msgid	":%s 494 %s %s :Cannot join channel (+d)"
+msgstr	":%s 494 %s %s :Can't join, your on a wrong chan babe, or got bad ircname (+d)"
+
+#: ../src/messages.tab:529
+#, c-format
+msgid   ":%s 498 %s %s :Accepts messages from SSL clients only"
+msgstr  ":%s 498 %s %s :They sniff on you dude, get a SSL client and then msg me"
+
+#: ../src/messages.tab:531
+#, c-format
+msgid	":%s 500 %s %s :Maximum size for WATCH-list is 128 entries"
+msgstr	""
 
 #: ../src/messages.tab:532
 #, c-format
diff -uPr ircd-hybrid-7.0.3/modules/core/m_message.c ircd-hybrid-7.0.3-ssl/modules/core/m_message.c
--- ircd-hybrid-7.0.3/modules/core/m_message.c	Tue Jun 15 21:56:02 2004
+++ ircd-hybrid-7.0.3-ssl/modules/core/m_message.c	Sun Aug 29 18:13:16 2004
@@ -599,6 +599,22 @@
      * and its not a notice */
     if ((p_or_n != NOTICE) && (source_p != target_p) && source_p->user)
       source_p->user->last = CurrentTime;
+      
+    if (IsSetSSLaccept(target_p)) {
+#ifdef HAVE_LIBCRYPTO
+  		int fd = source_p->localClient->fd;
+  		fde_t *F = (fd > -1)? &fd_table[fd] : NULL;
+  	
+  		if (F && !F->ssl) {
+#endif
+  			sendto_one(source_p, form_str(ERR_SSLACCEPTONLY),
+  				me.name, source_p->name, target_p->name);
+  			return;
+  			
+#ifdef HAVE_LIBCRYPTO
+		}
+#endif
+	}
   }
 
   if (MyConnect(source_p) && (p_or_n != NOTICE) &&
@@ -611,12 +627,13 @@
     if (!IsServer(source_p) && IsSetCallerId(target_p))
     {
       /* Here is the anti-flood bot/spambot code -db */
-      if (accept_message(source_p, target_p))
+      if (accept_message(source_p, target_p) || (source_p == target_p))
       {
         sendto_one(target_p, ":%s!%s@%s %s %s :%s",
                    source_p->name,
                    source_p->username,
-                   source_p->host, command, target_p->name, text);
+                   source_p->host, 
+                   command, target_p->name, text);
       }
       else
       {
diff -uPr ircd-hybrid-7.0.3/modules/core/m_sjoin.c ircd-hybrid-7.0.3-ssl/modules/core/m_sjoin.c
--- ircd-hybrid-7.0.3/modules/core/m_sjoin.c	Tue Jun 15 21:56:03 2004
+++ ircd-hybrid-7.0.3-ssl/modules/core/m_sjoin.c	Sun Aug 29 17:54:45 2004
@@ -185,6 +185,9 @@
           mode.mode |= MODE_HIDEOPS;
         break;
 #endif
+      case 'S':
+        mode.mode |= MODE_SSLONLY;
+        break;
       case 'k':
         strlcpy(mode.key, parv[4 + args], KEYLEN);
         args++;
@@ -743,6 +746,7 @@
 #ifdef ANONOPS
   { MODE_HIDEOPS,    'a' },
 #endif
+  { MODE_SSLONLY,    'S' },
   { 0, 0 }
 };
 
diff -uPr ircd-hybrid-7.0.3/modules/m_whois.c ircd-hybrid-7.0.3-ssl/modules/m_whois.c
--- ircd-hybrid-7.0.3/modules/m_whois.c	Tue Jun 15 21:55:55 2004
+++ ircd-hybrid-7.0.3-ssl/modules/m_whois.c	Sun Aug 29 16:37:48 2004
@@ -23,6 +23,7 @@
  */
 
 #include "stdinc.h"
+#include "fdlist.h"
 #include "tools.h"
 #include "common.h"  
 #include "handlers.h"
@@ -34,7 +35,7 @@
 #include "hash.h"
 #include "ircd.h"
 #include "numeric.h"
-#include "s_conf.h"
+#include "s_misc.h"
 #include "s_serv.h"
 #include "send.h"
 #include "list.h"
@@ -442,6 +443,7 @@
   if (reply_to_send)
     sendto_one(source_p, "%s", buf);
           
+ rplserver:          
   if ((IsOper(source_p) || !ConfigServerHide.hide_servers) || target_p == source_p)
     sendto_one(source_p, form_str(RPL_WHOISSERVER),
 	       me.name, source_p->name, target_p->name, server_name,
@@ -457,22 +459,34 @@
 	       source_p->name, target_p->name, target_p->user->away);
 
   if (IsOper(target_p))
-    sendto_one(source_p, form_str(RPL_WHOISOPERATOR),
+  	{
+    	sendto_one(source_p, form_str(RPL_WHOISOPERATOR),
+	    	me.name, source_p->name, target_p->name);
+
+      	if (IsAdmin(target_p))
+        	sendto_one(source_p, form_str(RPL_WHOISADMIN),
 	       me.name, source_p->name, target_p->name);
+	}
 
-  if (MyConnect(target_p)) /* Can't do any of this if not local! db */
+#ifdef HAVE_LIBCRYPTO
+  if (MyClient(target_p)) {
+  	int fd = target_p->localClient->fd;
+  	fde_t *F = (fd > -1)? &fd_table[fd] : NULL;
+  	
+  	if (F && F->ssl)
+  		sendto_one(source_p, form_str(RPL_WHOISSSL),
+  			me.name, source_p->name, target_p->name);	
+  }
+#endif
+
+  if (glob || (MyConnect(target_p) && (IsOper(source_p) ||
+      !ConfigServerHide.hide_servers)) || (target_p == source_p) )
   {
-    if ( (glob) ||
-         ( MyClient(source_p) && (IsOper(source_p) ||
-                                  !ConfigServerHide.hide_servers) ) ||
-         (source_p == target_p) )
-    {
-      sendto_one(source_p, form_str(RPL_WHOISIDLE),
+    sendto_one(source_p, form_str(RPL_WHOISIDLE),
 	         me.name, source_p->name, target_p->name,
 	         CurrentTime - target_p->user->last,
 	         target_p->firsttime);
     }
-  }
 
   hd.client_p = target_p;
   hd.source_p = source_p;
diff -uPr ircd-hybrid-7.0.3/src/channel.c ircd-hybrid-7.0.3-ssl/src/channel.c
--- ircd-hybrid-7.0.3/src/channel.c	Sat Oct 25 19:08:20 2003
+++ ircd-hybrid-7.0.3-ssl/src/channel.c	Sun Aug 29 17:56:16 2004
@@ -44,7 +44,7 @@
 #include "memory.h"
 #include "balloc.h"
 #include "resv.h"
-
+#include "fdlist.h"
 
 #include "s_log.h"
 
@@ -1128,6 +1128,21 @@
 
   if (chptr->mode.limit && chptr->users >= chptr->mode.limit)
     return (ERR_CHANNELISFULL);
+
+  if (SSLonlyChannel(chptr)) 
+  {
+#ifdef HAVE_LIBCRYPTO
+  	if (MyClient(source_p)) {
+  		int fd = source_p->localClient->fd;
+  		fde_t *F = (fd > -1)? &fd_table[fd] : NULL;
+  	
+  		if (F && !F->ssl)
+  			return (ERR_SSLONLYCHAN);
+  	}
+#else
+	return (ERR_SSLONLYCHAN);	/* deny everyone on a non SSL-enabled server */
+#endif  
+  }
 
   return 0;
 }
diff -uPr ircd-hybrid-7.0.3/src/channel_mode.c ircd-hybrid-7.0.3-ssl/src/channel_mode.c
--- ircd-hybrid-7.0.3/src/channel_mode.c	Mon Jun 14 08:27:28 2004
+++ ircd-hybrid-7.0.3-ssl/src/channel_mode.c	Sun Aug 29 18:14:48 2004
@@ -499,6 +499,9 @@
   if (chptr->mode.mode & MODE_HIDEOPS)
     *mbuf++ = 'a';
 #endif
+  if (chptr->mode.mode & MODE_SSLONLY)
+    *mbuf++ = 'S';
+
   if (chptr->mode.limit)
   {
     *mbuf++ = 'l';
@@ -1855,7 +1858,7 @@
   {chm_nosuch, NULL},                             /* P */
   {chm_nosuch, NULL},                             /* Q */
   {chm_nosuch, NULL},                             /* R */
-  {chm_nosuch, NULL},                             /* S */
+  {chm_simple, (void *) MODE_SSLONLY},            /* S */
   {chm_nosuch, NULL},                             /* T */
   {chm_nosuch, NULL},                             /* U */
   {chm_nosuch, NULL},                             /* V */
diff -uPr ircd-hybrid-7.0.3/src/fdlist.c ircd-hybrid-7.0.3-ssl/src/fdlist.c
--- ircd-hybrid-7.0.3/src/fdlist.c	Sat Jun 15 00:19:56 2002
+++ ircd-hybrid-7.0.3-ssl/src/fdlist.c	Sun Aug 29 16:24:09 2004
@@ -81,7 +81,7 @@
 
 /* Called to open a given filedescriptor */
 void
-fd_open(int fd, unsigned int type, const char *desc)
+fd_open(int fd, unsigned int type, const char *desc, void *ssl)
 {
   fde_t *F = &fd_table[fd];
   assert(fd >= 0);
@@ -111,6 +111,9 @@
   if (desc)
     strncpy(F->desc, desc, FD_DESC_SZ);
   number_fd++;
+#ifdef HAVE_LIBCRYPTO
+  F->ssl = (SSL *)ssl;
+#endif
 }
 
 
@@ -139,6 +142,17 @@
   number_fd--;
   memset(F, '\0', sizeof(fde_t));
   F->timeout = 0;
+  
+#ifdef HAVE_LIBCRYPTO
+  F->flags.accept_read = 0;
+  F->flags.accept_write = 0;
+  F->accept_failures = 0;
+  if (F->ssl) {
+  	SSL_shutdown(F->ssl);
+  	SSL_free(F->ssl);
+  	F->ssl = NULL;
+  }
+#endif
   /* Unlike squid, we're actually closing the FD here! -- adrian */
   close(fd);
 }
diff -uPr ircd-hybrid-7.0.3/src/fileio.c ircd-hybrid-7.0.3-ssl/src/fileio.c
--- ircd-hybrid-7.0.3/src/fileio.c	Wed May 28 22:13:26 2003
+++ ircd-hybrid-7.0.3-ssl/src/fileio.c	Sun Aug 29 16:46:30 2004
@@ -46,11 +46,11 @@
     int fd;
     fd = open(filename, mode, fmode);
     if (fd == MASTER_MAX) {
-        close(fd); /* Too many FDs! */
+        fd_close(fd); /* Too many FDs! */
         errno = ENFILE;
         fd = -1;
     } else if (fd >= 0)
-        fd_open(fd, FD_FILE, filename);
+        fd_open(fd, FD_FILE, filename, NULL);
     
     return fd;
 }
diff -uPr ircd-hybrid-7.0.3/src/ircd.c ircd-hybrid-7.0.3-ssl/src/ircd.c
--- ircd-hybrid-7.0.3/src/ircd.c	Sat Oct 25 19:08:22 2003
+++ ircd-hybrid-7.0.3-ssl/src/ircd.c	Sun Aug 29 16:24:09 2004
@@ -674,6 +674,18 @@
   init_auth();                  /* Initialise the auth code */
   init_resolver();      /* Needs to be setup before the io loop */
 #ifdef HAVE_LIBCRYPTO
+  SSL_load_error_strings();
+  SSLeay_add_ssl_algorithms();
+  ServerInfo.meth = SSLv23_server_method();
+  ServerInfo.ctx = SSL_CTX_new(ServerInfo.meth);
+  if (!ServerInfo.ctx) {
+  	fprintf(stderr, "Could not initialize the SSL context -- %s\n",
+  		ERR_error_string(ERR_get_error(), NULL));
+  }
+  SSL_CTX_set_options(ServerInfo.ctx, SSL_OP_NO_SSLv2);
+  SSL_CTX_set_options(ServerInfo.ctx, SSL_OP_TLS_ROLLBACK_BUG|SSL_OP_ALL);
+  /*SSL_CTX_set_verify(ServerInfo.ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, NULL);*/
+  SSL_CTX_set_verify(ServerInfo.ctx, SSL_VERIFY_NONE, NULL);
   bio_spare_fd=save_spare_fd("SSL private key validation");
 #endif /* HAVE_LIBCRYPTO */
   read_conf_files(YES);         /* cold start init conf files */
diff -uPr ircd-hybrid-7.0.3/src/ircd_lexer.l ircd-hybrid-7.0.3-ssl/src/ircd_lexer.l
--- ircd-hybrid-7.0.3/src/ircd_lexer.l	Sat Oct 25 19:08:22 2003
+++ ircd-hybrid-7.0.3-ssl/src/ircd_lexer.l	Sun Aug 29 17:59:43 2004
@@ -234,6 +234,7 @@
 ping_cookie	{ return PING_COOKIE; }
 ping_time	{ return PING_TIME; }
 port		{ return PORT; }
+sslport		{ return SSLPORT; }
 quiet_on_ban    { return QUIET_ON_BAN; }
 reason		{ return REASON; }
 redirport       { return REDIRPORT; }
@@ -245,6 +246,7 @@
 resv		{ return RESV; }
 rsa_private_key_file		{ return RSA_PRIVATE_KEY_FILE; }
 rsa_public_key_file		{ return RSA_PUBLIC_KEY_FILE; }
+ssl_certificate_file	{ return SSL_CERTIFICATE_FILE; }
 send_password	{ return SEND_PASSWORD; }
 sendq		{ return SENDQ; }
 serverhide	{ return SERVERHIDE; }
diff -uPr ircd-hybrid-7.0.3/src/ircd_parser.y ircd-hybrid-7.0.3-ssl/src/ircd_parser.y
--- ircd-hybrid-7.0.3/src/ircd_parser.y	Sat Oct 25 19:08:23 2003
+++ ircd-hybrid-7.0.3-ssl/src/ircd_parser.y	Sun Aug 29 18:00:05 2004
@@ -47,12 +47,6 @@
 #include "listener.h"
 #include "resv.h"
 
-#ifdef HAVE_LIBCRYPTO
-#include <openssl/rsa.h>
-#include <openssl/bio.h>
-#include <openssl/pem.h>
-#endif
-
 extern char *ip_string;
 
 int yyparse();
@@ -204,6 +198,7 @@
 %token  PING_COOKIE
 %token  PING_TIME
 %token  PORT
+%token  SSLPORT
 %token  QSTRING
 %token  QUIET_ON_BAN
 %token  REASON
@@ -214,6 +209,7 @@
 %token  RESTRICTED
 %token  RSA_PRIVATE_KEY_FILE
 %token  RSA_PUBLIC_KEY_FILE
+%token  SSL_CERTIFICATE_FILE
 %token	RESV
 %token  SECONDS MINUTES HOURS DAYS WEEKS MONTHS YEARS DECADES CENTURIES MILLENNIA
 %token  SENDQ
@@ -411,6 +407,7 @@
                         serverinfo_network_name | serverinfo_network_desc |
                         serverinfo_max_clients | 
                         serverinfo_rsa_private_key_file | serverinfo_vhost6 |
+                        serverinfo_ssl_certificate_file |
                         serverinfo_max_buffer | 
 			error;
 
@@ -472,6 +469,50 @@
 #endif
   };
 
+serverinfo_ssl_certificate_file: SSL_CERTIFICATE_FILE '=' QSTRING ';'
+  {
+#ifdef HAVE_LIBCRYPTO
+	if (ServerInfo.ctx) {
+	
+  		if (ServerInfo.ssl_certificate_file)
+  		{
+    		MyFree(ServerInfo.ssl_certificate_file);
+    		ServerInfo.ssl_certificate_file = NULL;
+  		}
+
+  		DupString(ServerInfo.ssl_certificate_file, yylval.string);
+
+		if (!ServerInfo.rsa_private_key_file) {
+			sendto_realops_flags(FLAGS_ALL, L_ALL,
+				"Ignoring config file entry ssl_certificate -- no rsa_private_key");
+			break;
+		}
+		
+		if (SSL_CTX_use_certificate_file(ServerInfo.ctx, 
+			ServerInfo.ssl_certificate_file, SSL_FILETYPE_PEM) <= 0) {
+			sendto_realops_flags(FLAGS_ALL, L_ALL,
+				"Error using config file entry ssl_certificate -- %s",
+				ERR_error_string(ERR_get_error(), NULL));
+			break;
+		}
+
+		if (SSL_CTX_use_PrivateKey_file(ServerInfo.ctx, 
+			ServerInfo.rsa_private_key_file, SSL_FILETYPE_PEM) <= 0) {
+			sendto_realops_flags(FLAGS_ALL, L_ALL,
+				"Error using config file entry rsa_private_key -- %s",
+				ERR_error_string(ERR_get_error(), NULL));
+			break;
+		}
+		
+		if (!SSL_CTX_check_private_key(ServerInfo.ctx)) {
+			sendto_realops_flags(FLAGS_ALL, L_ALL,
+				"RSA private key doesn't match the SSL certificate public key!");
+			break;
+		}
+	}
+#endif
+  };
+  
 serverinfo_name:        NAME '=' QSTRING ';' 
   {
     /* this isn't rehashable */
@@ -983,7 +1024,8 @@
 listen_items:   listen_items listen_item |
                 listen_item;
 
-listen_item:    listen_port | listen_address | listen_host | error;
+listen_item:    listen_port | listen_sslport |
+				listen_address | listen_host | error;
 
 listen_port: PORT '=' port_items ';' ;
 
@@ -991,13 +1033,29 @@
 
 port_item: NUMBER
 {
-  add_listener($1, listener_address);
+  add_listener($1, listener_address, 0);
+} | NUMBER TWODOTS NUMBER
+{
+  int i;
+  for (i = $1; i <= $3; i++)
+	{
+	  add_listener(i, listener_address, 0);
+	}
+};
+
+listen_sslport: SSLPORT '=' sslport_items ';' ;
+
+sslport_items: sslport_items ',' sslport_item | sslport_item;
+
+sslport_item: NUMBER
+{
+  add_listener($1, listener_address, 1);
 } | NUMBER TWODOTS NUMBER
 {
   int i;
   for (i = $1; i <= $3; i++)
 	{
-	  add_listener(i, listener_address);
+	  add_listener(i, listener_address, 1);
 	}
 };
 
diff -uPr ircd-hybrid-7.0.3/src/linebuf.c ircd-hybrid-7.0.3-ssl/src/linebuf.c
--- ircd-hybrid-7.0.3/src/linebuf.c	Wed Oct  9 08:08:32 2002
+++ ircd-hybrid-7.0.3-ssl/src/linebuf.c	Sun Aug 29 16:47:08 2004
@@ -32,6 +32,8 @@
 #include "list.h"
 #include "balloc.h"
 #include "hook.h"
+#include "fdlist.h"
+#include "send.h"
 
 #ifdef STRING_WITH_STRINGS
 # include <string.h>
@@ -634,6 +636,9 @@
 {
   buf_line_t *bufline;
   int retval;
+#ifdef HAVE_LIBCRYPTO
+  fde_t *F = (fd > -1)? &fd_table[fd] : NULL;
+#endif
   
   /* Check we actually have a first buffer */
   if (bufhead->list.head == NULL)
@@ -660,6 +665,86 @@
     }
 
   /* Now, try writing data */
+#ifdef HAVE_LIBCRYPTO
+  if (F && F->ssl) {
+  	/*extern time_t CurrentTime;*/
+  	extern char *get_ssl_error(int);
+  	/*static*/ int alerted = 0;
+  
+  	if (F->flags.accept_write) {
+  		int ret;
+  		/*send(fd, bufline->buf + bufhead->writeofs, bufline->len
+  			- bufhead->writeofs, 0);*/
+  		if ((ret = SSL_accept(F->ssl)) > 0) {
+  			if (!alerted)
+  			sendto_realops_flags(FLAGS_DEBUG, L_ALL, 
+  				"SSL_accept() for %s (socket %d) wanting WRITE succeeded!",
+  				inetntoa((char *)&S_ADDR(F->connect.hostaddr)), F->fd);
+  			F->flags.accept_write = 0;
+  		} else if (F->accept_failures < 4) {
+  			int val = SSL_get_error(F->ssl, ret);  		
+  			sendto_realops_flags(FLAGS_DEBUG, L_ALL, 
+  				"SSL_accept() for %s (socket %d) wanting WRITE error! -- %s",
+  				inetntoa((char *)&S_ADDR(F->connect.hostaddr)), F->fd,
+  				(val == SSL_ERROR_SSL)?
+  				ERR_error_string(ERR_get_error(), NULL) :
+  				get_ssl_error(val));
+  			sendto_realops_flags(FLAGS_DEBUG, L_ALL,
+  				"BIO_sock_should_retry(): %d", BIO_sock_should_retry(ret));
+  		if (val == SSL_ERROR_SYSCALL) {
+  			int err = ERR_get_error();
+  			if (err)
+  				sendto_realops_flags(FLAGS_DEBUG, L_ALL, "ERR_get_error() -- %s",
+  					ERR_error_string(err, NULL));
+  			else
+  				sendto_realops_flags(FLAGS_DEBUG, L_ALL, "more error info -- %s",
+  					(ret == -1)? strerror(errno) : "got EOF, protocol violation");  
+  		}
+  			sendto_realops_flags(FLAGS_DEBUG, L_ALL, "SSL_state_string_long(): %s",
+  				SSL_state_string_long(F->ssl));
+  			F->accept_failures++;
+  		}
+  		retval = -1; errno = EAGAIN;
+  	} else {
+
+#if 0  				
+  	/*if (CurrentTime % 10 == 0)*/
+  	if (!alerted) {
+  	sendto_realops_flags(FLAGS_DEBUG, L_ALL, "SSL_write() for %s (socket %d) in progress...",
+  		inetntoa((char *)&S_ADDR(F->connect.hostaddr)), F->fd);
+  	sendto_realops_flags(FLAGS_DEBUG, L_ALL, "SSL_state_string_long(): %s",
+  		SSL_state_string_long(F->ssl));
+  	}
+#endif
+  		
+  	retval = SSL_write(F->ssl, bufline->buf + bufhead->writeofs, 
+  				bufline->len - bufhead->writeofs);
+  				
+  	if (retval <= 0 && !alerted) {
+  		int val = SSL_get_error(F->ssl, retval);
+  		/*if (CurrentTime % 10 == 0)*/
+  		sendto_realops_flags(FLAGS_DEBUG, L_ALL, 
+  			"SSL_write() for %s (socket %d) ERROR! -- %s",
+  			inetntoa((char *)&S_ADDR(F->connect.hostaddr)), F->fd,
+  			(val == SSL_ERROR_SSL)?
+  			ERR_error_string(ERR_get_error(), NULL) :
+  			get_ssl_error(val));
+  		if (val == SSL_ERROR_SYSCALL) {
+  			int err = ERR_get_error();
+  			if (err)
+  				sendto_realops_flags(FLAGS_DEBUG, L_ALL, "ERR_get_error() -- %s",
+  					ERR_error_string(err, NULL));
+  			else
+  				sendto_realops_flags(FLAGS_DEBUG, L_ALL, "more error info -- %s",
+  					(retval == -1)? strerror(errno) : "got EOF, protocol violation");  
+  		} else {
+  			/*SSL_set_accept_state(F->ssl);*/
+  			errno = EAGAIN;
+  		}
+  	}}
+  	alerted = 1;
+  } else
+#endif
   retval = send(fd, bufline->buf + bufhead->writeofs, bufline->len
 		 - bufhead->writeofs, 0);
    
diff -uPr ircd-hybrid-7.0.3/src/listener.c ircd-hybrid-7.0.3-ssl/src/listener.c
--- ircd-hybrid-7.0.3/src/listener.c	Thu Jan 30 03:28:45 2003
+++ ircd-hybrid-7.0.3-ssl/src/listener.c	Sun Aug 29 16:24:09 2004
@@ -130,7 +130,7 @@
     sendto_one(source_p, form_str(RPL_STATSPLINE),
                me.name,
                source_p->name,
-               'P',
+               listener->is_ssl? 'S' : 'P',
                listener->port,
                IsOperAdmin(source_p) ? listener->name : me.name,
                listener->ref_count,
@@ -271,7 +271,7 @@
  * the format "255.255.255.255"
  */
 void 
-add_listener(int port, const char* vhost_ip)
+add_listener(int port, const char* vhost_ip, int is_ssl)
 {
   struct Listener* listener;
   struct irc_inaddr   vaddr;
@@ -304,6 +304,8 @@
     listener = make_listener(port, &vaddr);
     listener->next = ListenerPollList;
     ListenerPollList = listener;
+    
+    listener->is_ssl = is_ssl;
   }
 
   listener->fd = -1;
@@ -384,15 +386,7 @@
    * be accepted until some old is closed first.
    */
 
-  fd = comm_accept(listener->fd, &sai);
-
-  if (fd < 0)
-  {
-    /* Re-register a new IO request for the next accept .. */
-    comm_setselect(listener->fd, FDLIST_SERVICE, COMM_SELECT_READ,
-                   accept_connection, listener, 0);
-    return;
-  }
+  fd = comm_accept(listener->fd, &sai, listener->is_ssl);
 
   copy_s_addr(IN_ADDR(addr), S_ADDR(sai));
 
@@ -407,6 +401,13 @@
   }
 #endif
 
+  if (fd < 0)
+    {
+      /* Re-register a new IO request for the next accept .. */
+      comm_setselect(listener->fd, FDLIST_SERVICE, COMM_SELECT_READ,
+                     accept_connection, listener, 0);
+      return;
+    }
   /*
    * check for connection limit
    */
diff -uPr ircd-hybrid-7.0.3/src/messages.tab ircd-hybrid-7.0.3-ssl/src/messages.tab
--- ircd-hybrid-7.0.3/src/messages.tab	Sat Oct 25 19:08:24 2003
+++ ircd-hybrid-7.0.3-ssl/src/messages.tab	Sun Aug 29 18:08:21 2004
@@ -321,7 +321,7 @@
 /* 294 */       NULL,
 /* 295 */       NULL,
 /* 296 */       NULL,
-/* 297 */       NULL,
+/* 297 RPL_WHOISSSL, */       	":%s 297 %s %s :is connected via SSL (secure link)",
 /* 298 */       NULL,
 /* 299 */       NULL,
 /* 300 RPL_NONE, */      NULL,
@@ -332,7 +332,7 @@
 /* 305 RPL_UNAWAY, */   ":%s 305 %s :You are no longer marked as being away",
 /* 306 RPL_NOWAWAY, */  ":%s 306 %s :You have been marked as being away",
 /* 307 */       NULL,
-/* 308 */	NULL,
+/* 308 RPL_WHOISADMIN, */ ":%s 308 %s %s :is a Server Administrator",
 /* 309 */       NULL,
 /* 310 */       NULL,
 /* 311 RPL_WHOISUSER, */        ":%s 311 %s %s %s %s * :%s",
@@ -505,7 +505,7 @@
 /* 477 ERR_MODELESS, */         ":%s 477 %s %s :Channel does not support modes",
 /* 478 ERR_BANLISTFULL, */      ":%s 478 %s %s %s :Channel ban list is full",
 /* 479 ERR_BADCHANNAME */       ":%s 479 %s %s :Illegal channel name",
-/* 480 */       NULL,
+/* 480 ERR_SSLONLYCHAN */       ":%s 480 %s %s :Cannot join channel (+S)",
 /* 481 ERR_NOPRIVILEGES, */
                 ":%s 481 %s :Permission Denied - You're not an IRC operator",
 /* 482 ERR_CHANOPRIVSNEEDED, */ ":%s 482 %s %s :You're not channel operator",
@@ -521,13 +521,13 @@
 /* 491 ERR_NOOPERHOST, */       ":%s 491 %s :Only few of mere mortals may try to enter the twilight zone",
 /* 492 */       NULL,
 /* 493 */       NULL,
-/* 494 */       NULL,
+/* 494 ERR_DENIEDFROMCHAN, */	":%s 494 %s %s :Cannot join channel (+d)",
 /* 495 */       NULL,
 /* 496 */       NULL,
 /* 497 */       NULL,
-/* 498 */       NULL,
+/* 498 ERR_SSLACCEPTONLY, */    ":%s 498 %s %s :Accepts messages from SSL clients only",
 /* 499 */       NULL,
-/* 500 */       NULL,
+/* 500 ERR_TOOMANYWATCH */		":%s 500 %s %s :Maximum size for WATCH-list is 128 entries",
 /* 501 ERR_UMODEUNKNOWNFLAG, */ ":%s 501 %s :Unknown MODE flag",
 /* 502 ERR_USERSDONTMATCH, */   ":%s 502 %s :Can't change mode for other users",
 /* 503 ERR_GHOSTEDCLIENT, */    ":%s 503 %s :Message could not be delivered to %s",
diff -uPr ircd-hybrid-7.0.3/src/packet.c ircd-hybrid-7.0.3-ssl/src/packet.c
--- ircd-hybrid-7.0.3/src/packet.c	Sun Feb 16 15:54:37 2003
+++ ircd-hybrid-7.0.3-ssl/src/packet.c	Sun Aug 29 16:24:09 2004
@@ -378,7 +378,11 @@
 #ifndef NDEBUG
   struct hook_io_data hdata;
 #endif
-  if(IsDefunct(client_p))
+#ifdef HAVE_LIBCRYPTO
+  fde_t *F = (lclient_p->fd > -1)? &fd_table[lclient_p->fd] : NULL;
+#endif
+
+  if(IsDead(client_p))
     return;
   
   assert(lclient_p != NULL);
@@ -397,6 +401,84 @@
    * I personally think it makes the code too hairy to make sane.
    *     -- adrian
    */
+#ifdef HAVE_LIBCRYPTO
+  if (F && F->ssl) {
+  	/*extern time_t CurrentTime;*/
+  	extern char *get_ssl_error(int);
+  	/*static*/ int alerted = 0;
+
+  	if (F->flags.accept_read) {
+  		int ret;
+  		/*recv(fd_r, readBuf, READBUF_SIZE, 0);*/
+  		if ((ret = SSL_accept(F->ssl)) > 0) {
+  			if (!alerted)
+  			sendto_realops_flags(FLAGS_DEBUG, L_ALL, 
+  				"SSL_accept() for %s (socket %d) wanting READ succeeded!",
+  				inetntoa((char *)&S_ADDR(F->connect.hostaddr)), F->fd);
+  			F->flags.accept_read = 0;
+  		} else if (F->accept_failures < 4) {
+  			int val = SSL_get_error(F->ssl, ret);
+  			sendto_realops_flags(FLAGS_DEBUG, L_ALL, 
+  				"SSL_accept() for %s (socket %d) wanting READ error! -- %s",
+  				inetntoa((char *)&S_ADDR(F->connect.hostaddr)), F->fd,
+  				(val == SSL_ERROR_SSL)?
+  				ERR_error_string(ERR_get_error(), NULL) :
+  				get_ssl_error(val));
+  			sendto_realops_flags(FLAGS_DEBUG, L_ALL,
+  				"BIO_sock_should_retry(): %d", BIO_sock_should_retry(ret));
+  		if (val == SSL_ERROR_SYSCALL) {
+  			int err = ERR_get_error();
+  			if (err)
+  				sendto_realops_flags(FLAGS_DEBUG, L_ALL, "ERR_get_error() -- %s",
+  					ERR_error_string(err, NULL));
+  			else
+  				sendto_realops_flags(FLAGS_DEBUG, L_ALL, "more error info -- %s",
+  					(ret == -1)? strerror(errno) : "got EOF, protocol violation");  
+  		}
+  			sendto_realops_flags(FLAGS_DEBUG, L_ALL, "SSL_state_string_long(): %s",
+  				SSL_state_string_long(F->ssl));
+  			F->accept_failures++;
+  		}
+  		length = -1; errno = EAGAIN;
+  	} else {
+  	
+#if 0  				
+  	/*if (CurrentTime % 10 == 0)*/
+  	if (!alerted) {
+  	sendto_realops_flags(FLAGS_DEBUG, L_ALL, "SSL_read() for %s (socket %d) in progress...",
+  		inetntoa((char *)&S_ADDR(F->connect.hostaddr)), F->fd);
+  	sendto_realops_flags(FLAGS_DEBUG, L_ALL, "SSL_state_string_long(): %s",
+  		SSL_state_string_long(F->ssl));
+  	}
+#endif
+  		
+  	length = SSL_read(F->ssl, readBuf, READBUF_SIZE); 
+
+  	if (length <= 0 && !alerted) {
+  		int val = SSL_get_error(F->ssl, length);
+  		/*if (CurrentTime % 10 == 0)*/
+  		sendto_realops_flags(FLAGS_DEBUG, L_ALL, 
+  			"SSL_read() for %s (socket %d) ERROR! -- %s",
+  			inetntoa((char *)&S_ADDR(F->connect.hostaddr)), F->fd,
+  			(val == SSL_ERROR_SSL)?
+  			ERR_error_string(ERR_get_error(), NULL) :
+  			get_ssl_error(val));
+  		if (val == SSL_ERROR_SYSCALL) {
+  			int err = ERR_get_error();
+  			if (err)
+  				sendto_realops_flags(FLAGS_DEBUG, L_ALL, "ERR_get_error() -- %s",
+  					ERR_error_string(err, NULL));
+  			else
+  				sendto_realops_flags(FLAGS_DEBUG, L_ALL, "more error info -- %s",
+  					(length == -1)? strerror(errno) : "got EOF, protocol violation");  
+  		} else {
+  			/*SSL_set_accept_state(F->ssl);*/
+  			errno = EAGAIN;
+  		}
+  	}}
+  	alerted = 1;
+  } else
+#endif
   length = recv(fd_r, readBuf, READBUF_SIZE, 0);
 
   if (length <= 0)
diff -uPr ircd-hybrid-7.0.3/src/s_auth.c ircd-hybrid-7.0.3-ssl/src/s_auth.c
--- ircd-hybrid-7.0.3/src/s_auth.c	Wed May 28 22:13:26 2003
+++ ircd-hybrid-7.0.3-ssl/src/s_auth.c	Sun Aug 29 16:24:09 2004
@@ -87,8 +87,25 @@
   REPORT_HOST_TOOLONG
 } ReportType;
 
+#ifdef HAVE_LIBCRYPTO
+   static void sendheader(struct Client *c, int r) {
+   		int fd = c->localClient->fd;
+   		fde_t *F = (fd > -1)? &fd_table[fd] : NULL;
+   
+   		if (F && F->ssl) {
+   			if (F->flags.accept_write)
+   				if (SSL_accept(F->ssl) > 0)
+   					F->flags.accept_write = 0;
+   			if (!F->flags.accept_read)
+   			SSL_write(F->ssl, HeaderMessages[r].message, HeaderMessages[r].length);
+   		} else {
+   			send(fd, HeaderMessages[r].message, HeaderMessages[r].length, 0);
+   		}
+   }
+#else
 #define sendheader(c, r) \
    send((c)->localClient->fd, HeaderMessages[(r)].message, HeaderMessages[(r)].length, 0)
+#endif
 
 /*
  */
diff -uPr ircd-hybrid-7.0.3/src/s_bsd.c ircd-hybrid-7.0.3-ssl/src/s_bsd.c
--- ircd-hybrid-7.0.3/src/s_bsd.c	Sat May 31 00:37:05 2003
+++ ircd-hybrid-7.0.3-ssl/src/s_bsd.c	Sun Aug 29 16:48:43 2004
@@ -790,7 +790,7 @@
     }
 
   /* Next, update things in our fd tracking */
-  fd_open(fd, FD_SOCKET, note);
+  fd_open(fd, FD_SOCKET, note, NULL);
   return fd;
 }
 
@@ -802,10 +802,14 @@
  * comm_open() does.
  */
 int
-comm_accept(int fd, struct irc_sockaddr *pn)
+comm_accept(int fd, struct irc_sockaddr *pn, int is_ssl)
 {
   int newfd;
   socklen_t addrlen = sizeof(struct irc_sockaddr);
+#ifdef HAVE_LIBCRYPTO
+  SSL *ssl = NULL;
+#endif
+
   if (number_fd >= MASTER_MAX)
     {
       errno = ENFILE;
@@ -829,9 +833,115 @@
       return -1;
     }
 
+#ifdef HAVE_LIBCRYPTO
+  if (is_ssl && ServerInfo.ctx) {
+    int retval;
+    extern char *get_ssl_error(int);
+  	fde_t *F = &fd_table[newfd];
+  	
+  	copy_s_addr(F->connect.hostaddr, *pn);
+  
+  	ssl = SSL_new(ServerInfo.ctx);
+  	if (!ssl) {
+  		ilog(L_CRIT, "SSL_new() ERROR! -- %s", ERR_error_string(ERR_get_error(), NULL));
+  		close(newfd);
+  		return -1;
+  	}
+  	SSL_set_fd(ssl, newfd);
+  	
+  	sendto_realops_flags(FLAGS_DEBUG, L_ALL, "SSL_accept() for %s (socket %d) in progress...",
+  		inetntoa((char *)&PS_ADDR(pn)), newfd);
+
+again:
+  	retval = SSL_accept(ssl);
+  	if (retval <= 0) {
+  		switch ((retval = SSL_get_error(ssl, retval))) {
+  		
+	    	case SSL_ERROR_SYSCALL:
+				if (errno==EINTR || errno==EWOULDBLOCK || errno==EAGAIN)
+				
+  			case SSL_ERROR_WANT_READ:
+  			case SSL_ERROR_WANT_WRITE:
+  				sendto_realops_flags(FLAGS_DEBUG, L_ALL,
+  					"SSL_accept() for %s wants read or write (%s), passing through...",
+  					inetntoa((char *)&PS_ADDR(pn)), get_ssl_error(retval));
+  					
+  				/* let it through, SSL_read()/SSL_write() will finish the handshake...*/
+  				/*goto again;*/
+  				
+  				/*SSL_set_accept_state(ssl);*/
+  				if (retval == SSL_ERROR_WANT_READ)
+  					F->flags.accept_read = 1;
+  				else if (retval == SSL_ERROR_WANT_WRITE)
+  					F->flags.accept_write = 1;
+  				else
+  					F->flags.accept_read = 1;
+  				break;
+  				
+  			default:
+  				sendto_realops_flags(FLAGS_DEBUG, L_ALL, "SSL_accept() ERROR! -- %s",
+  					(retval == SSL_ERROR_SSL)?
+  					ERR_error_string(ERR_get_error(), NULL) :
+  					get_ssl_error(retval));
+  				SSL_free(ssl);
+  				close(newfd);
+  				return -1;
+  		}
+  	} else {
+  		char *ssl_get_cipher(SSL *);
+  		/*SSL_set_accept_state(ssl);*/
+  		
+  		sendto_realops_flags(FLAGS_DEBUG, L_ALL, "SSL_accept() for %s succeeded!",
+  			inetntoa((char *)&PS_ADDR(pn)));
+  		sendto_realops_flags(FLAGS_DEBUG, L_ALL, "SSL protocol/cipher: %s",
+  			ssl_get_cipher(ssl));
+  		sendto_realops_flags(FLAGS_DEBUG, L_ALL, "SSL_state_string_long(): %s",
+  			SSL_state_string_long(ssl));
+  	}
+  }
+#endif
+
   /* Next, tag the FD as an incoming connection */
-  fd_open(newfd, FD_SOCKET, "Incoming connection");
+#ifdef HAVE_LIBCRYPTO
+  if (is_ssl && ServerInfo.ctx)
+  	fd_open(newfd, FD_SOCKET, "Incoming SSL connection", ssl);
+  else
+  	fd_open(newfd, FD_SOCKET, "Incoming connection", ssl);
+#else
+  fd_open(newfd, FD_SOCKET, "Incoming connection", NULL);
+#endif
 
   /* .. and return */
   return newfd;
 }
+
+#ifdef HAVE_LIBCRYPTO
+char *ssl_get_cipher(SSL *ssl)
+{
+	static char buf[400];
+	char bots[10];
+	int bits;
+	SSL_CIPHER *c; 
+	
+	buf[0] = '\0';
+	switch(ssl->session->ssl_version)
+	{
+		case SSL2_VERSION:
+			strcat(buf, "SSLv2"); break;
+		case SSL3_VERSION:
+			strcat(buf, "SSLv3"); break;
+		case TLS1_VERSION:
+			strcat(buf, "TLSv1"); break;
+		default:
+			strcat(buf, "UNKNOWN");
+	}
+	strcat(buf, "-");
+	strcat(buf, SSL_get_cipher(ssl));
+	c = SSL_get_current_cipher(ssl);
+	SSL_CIPHER_get_bits(c, &bits);
+	sprintf(bots, "-%d", bits);
+	strcat(buf, bots);
+	strcat(buf, "bits");
+	return (buf);
+}
+#endif
diff -uPr ircd-hybrid-7.0.3/src/s_misc.c ircd-hybrid-7.0.3-ssl/src/s_misc.c
--- ircd-hybrid-7.0.3/src/s_misc.c	Fri May 24 16:34:51 2002
+++ ircd-hybrid-7.0.3-ssl/src/s_misc.c	Sun Aug 29 18:10:13 2004
@@ -122,3 +122,34 @@
   return timebuffer;
 }
 
+#define PLUGPARAMS 16
+
+
+#ifdef HAVE_LIBCRYPTO
+static struct {
+	int err;
+	char *str;
+} errtab[] = {
+	{SSL_ERROR_NONE, "SSL_ERROR_NONE"},
+	{SSL_ERROR_ZERO_RETURN, "SSL_ERROR_ZERO_RETURN"},
+	{SSL_ERROR_WANT_READ, "SSL_ERROR_WANT_READ"},
+	{SSL_ERROR_WANT_WRITE, "SSL_ERROR_WANT_WRITE"},
+	{SSL_ERROR_WANT_CONNECT, "SSL_ERROR_WANT_CONNECT"},
+	/*{SSL_ERROR_WANT_ACCEPT, "SSL_ERROR_WANT_ACCEPT"},*/
+	{SSL_ERROR_WANT_X509_LOOKUP, "SSL_ERROR_WANT_X509_LOOKUP"},
+	{SSL_ERROR_SYSCALL, "SSL_ERROR_SYSCALL"},
+	{SSL_ERROR_SSL, "SSL_ERROR_SSL"},
+	{-1, NULL}
+};
+
+char *get_ssl_error(int sslerr) 
+{
+	int i;
+	
+	for (i=0; errtab[i].err != -1; i++)
+		if (errtab[i].err == sslerr)
+			return errtab[i].str;
+			
+	return "<NULL>";
+}
+#endif
diff -uPr ircd-hybrid-7.0.3/src/s_serv.c ircd-hybrid-7.0.3-ssl/src/s_serv.c
--- ircd-hybrid-7.0.3/src/s_serv.c	Mon Feb  9 21:28:39 2004
+++ ircd-hybrid-7.0.3-ssl/src/s_serv.c	Sun Aug 29 16:52:10 2004
@@ -1458,15 +1458,17 @@
     }
 #endif
 
-#ifdef HAVE_SOCKETPAIR
-    fd_open(server->localClient->ctrlfd, FD_SOCKET, NULL);
-    fd_open(server->localClient->fd, FD_SOCKET, NULL);
-#else
-    fd_open(server->localClient->ctrlfd, FD_PIPE, NULL);
-    fd_open(server->localClient->fd, FD_PIPE, NULL);
-    fd_open(server->localClient->ctrlfd_r, FD_PIPE, NULL);
-    fd_open(server->localClient->fd_r, FD_PIPE, NULL);
-#endif
+ #ifdef HAVE_SOCKETPAIR
+    fd_open(server->localClient->ctrlfd, FD_SOCKET, NULL, NULL);
+    fd_open(server->localClient->fd, FD_SOCKET, NULL, NULL);
+ #else
+    fd_open(server->localClient->ctrlfd, FD_PIPE, NULL, NULL);
+    fd_open(server->localClient->fd, FD_PIPE, NULL, NULL);
+    fd_open(server->localClient->ctrlfd_r, FD_PIPE, NULL, NULL);
+    fd_open(server->localClient->fd_r, FD_PIPE, NULL, NULL);
+ #endif
+ 
+    read_ctrl_packet(slink_fds[0][1][0], server);
 
    read_ctrl_packet(slink_fds[0][1][0], server);
    read_packet(slink_fds[1][1][0], server);	
diff -uPr ircd-hybrid-7.0.3/src/s_user.c ircd-hybrid-7.0.3-ssl/src/s_user.c
--- ircd-hybrid-7.0.3/src/s_user.c	Sat Oct 25 19:08:25 2003
+++ ircd-hybrid-7.0.3-ssl/src/s_user.c	Sun Aug 29 18:10:44 2004
@@ -91,6 +91,7 @@
   {FLAGS_EXTERNAL, 'x'},
   {FLAGS_SPY, 'y'},
   {FLAGS_OPERWALL, 'z'},
+  {FLAGS_SSLACCEPT, 'S'},
   {0, 0}
 };
 
@@ -120,14 +121,11 @@
   0,            /* O */
   0,            /* P */
   0,            /* Q */
-  0,            /* R */
-  0,            /* S */
-  0,            /* T */
+  FLAGS_SSLACCEPT,/* S */
   0,            /* U */
   0,            /* V */
   0,            /* W */
   0,            /* X */
-  0,            /* Y */
   0,            /* Z 0x5A */
   0, 0, 0, 0, 0, /* 0x5F */ 
   /* 0x60 */       0,
@@ -1209,19 +1207,24 @@
   sendto_one(source_p, form_str(RPL_YOURHOST), me.name, source_p->name,
 	     get_listener_name(source_p->localClient->listener), ircd_version);
   
-#if 0
   /*
   ** Don't mess with this one - IRCII needs it! -Avalon
   */
-  /* No one has needed this in years, but I remember when IRCII did!
-   * It sure confused me why my IRCII client hung at start up
-   * when I was writing my first ircd from scratch. ;-)
-   * - Dianora
-   */
   sendto_one(source_p,
 	     "NOTICE %s :*** Your host is %s, running version %s",
 	     source_p->name, get_listener_name(source_p->localClient->listener),
 	     ircd_version);
+	     
+#ifdef HAVE_LIBCRYPTO
+  {
+  	int fd = source_p->localClient->fd;
+  	fde_t *F = (fd > -1)? &fd_table[fd] : NULL;
+  	extern char *ssl_get_cipher(SSL *);
+  	
+  	if (F && F->ssl)
+  		sendto_one(source_p, "NOTICE %s :*** Connected securely via %s",
+  		source_p->name, ssl_get_cipher(F->ssl));
+  }
 #endif
   
   sendto_one(source_p, form_str(RPL_CREATED),me.name,source_p->name,creation);
diff -uPr ircd-hybrid-7.0.3/src/tools.c ircd-hybrid-7.0.3-ssl/src/tools.c
--- ircd-hybrid-7.0.3/src/tools.c	Thu Feb  6 01:45:58 2003
+++ ircd-hybrid-7.0.3-ssl/src/tools.c	Sun Aug 29 17:02:44 2004
@@ -186,8 +186,37 @@
 {
   dlink_node *m;
 
-  m = dlinkFind(list, data);
-  if (m)
-    dlinkDelete(m, list);
-  return(m);
+  DLINK_FOREACH(m, list->head)
+  {
+    if(m->data != data)
+      continue;
+
+    if (m->next != NULL)
+      m->next->prev = m->prev;
+    else
+      list->tail = m->prev;
+
+    m->next = m->prev = NULL;
+    list->length--;
+    return m;
+  }
+  return(NULL);
 }
+
+#ifdef HAVE_LIBCRYPTO
+static struct {
+	int err;
+	char *str;
+} errtab[] = {
+	{SSL_ERROR_NONE, "SSL_ERROR_NONE"},
+	{SSL_ERROR_ZERO_RETURN, "SSL_ERROR_ZERO_RETURN"},
+	{SSL_ERROR_WANT_READ, "SSL_ERROR_WANT_READ"},
+	{SSL_ERROR_WANT_WRITE, "SSL_ERROR_WANT_WRITE"},
+	{SSL_ERROR_WANT_CONNECT, "SSL_ERROR_WANT_CONNECT"},
+	/*{SSL_ERROR_WANT_ACCEPT, "SSL_ERROR_WANT_ACCEPT"},*/
+	{SSL_ERROR_WANT_X509_LOOKUP, "SSL_ERROR_WANT_X509_LOOKUP"},
+	{SSL_ERROR_SYSCALL, "SSL_ERROR_SYSCALL"},
+	{SSL_ERROR_SSL, "SSL_ERROR_SSL"},
+	{-1, NULL}
+};
+#endif
