diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/doc/example.conf ircd-ratbox-stable+ssl/doc/example.conf
--- ircd-ratbox-stable/doc/example.conf	Wed Mar 24 18:03:44 2004
+++ ircd-ratbox-stable+ssl/doc/example.conf	Tue Mar 30 13:28:38 2004
@@ -84,6 +84,21 @@
 	 *	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 -x509 -days 730 -key rsa.key -out cert.pem
+     */
+    #ssl_certificate_file = "/usr/local/ircd/etc/cert.pem";
+
+    /* Certification Authority certificate file, used to sign
+     * ssl_certificate_file. Shouldn't be used if certificate
+     * is self-signed
+     */
+    #ssl_ca_certificate_file = "/usr/local/ircd/etc/ca.pem";
 };
 
 /* admin {}: contains admin information about the server. (OLD A:) */
@@ -195,14 +210,19 @@
 	/* port: listen on all available IPs, ports 5000 and 6665 to 6669 */
 	port = 5000, 6665 .. 6669;
 
+	/* sslport: listen for SSL connections on all available IPs, ports 7000 to 7005 */
+	sslport = 7000 .. 7005;
+
 	/* host: set a specific IP/host the ports after the line will listen 
 	 * on.  This may be ipv4 or ipv6.
 	 */
 	host = "1.2.3.4";
 	port = 7000, 7001;
+	sslport = 7099;
 
 	host = "3ffe:1234:a:b:c::d";
-        port = 7002;
+    port = 7002;
+	sslport = 7199;
 };
 
 /* auth {}: allow users to connect to the ircd (OLD I:) */
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/include/client.h ircd-ratbox-stable+ssl/include/client.h
--- ircd-ratbox-stable/include/client.h	Wed Mar 24 18:03:44 2004
+++ ircd-ratbox-stable+ssl/include/client.h	Tue Mar 30 12:34:38 2004
@@ -127,6 +127,10 @@
 	unsigned char handler;	/* Handler index */
 	unsigned long serial;	/* used to enforce 1 send per nick */
 
+#ifdef HAVE_LIBCRYPTO
+	SSL *ssl;
+#endif
+
 	/* client->name is the unique name for a client nick or host */
 	char name[HOSTLEN + 1];
 
@@ -159,6 +163,7 @@
 	dlink_list on_allow_list;	/* clients that have =me= on their allow list */
 
 	struct LocalUser *localClient;
+
 };
 
 struct LocalUser
@@ -409,6 +414,7 @@
 #define FLAGS2_FLOODDONE        0x800000
 #define FLAGS2_EXEMPTSPAMBOT	0x1000000
 #define OPER_HIDDENOPER			0x2000000
+#define FLAGS2_SSL		0x4000000
 
 #define OPER_FLAGS      (OPER_GLOBAL_KILL | OPER_REMOTE | OPER_UNKLINE |\
                          OPER_GLINE | OPER_N | OPER_K | OPER_DIE |\
@@ -540,6 +546,9 @@
 
 #define IsFloodDone(x)          ((x)->flags2 & FLAGS2_FLOODDONE)
 #define SetFloodDone(x)         ((x)->flags2 |= FLAGS2_FLOODDONE)
+
+#define SetSSL(x)               ((x)->flags2 |= FLAGS2_SSL)
+#define IsSSL(x)                (((x)->flags2 & FLAGS2_SSL) && (x)->ssl)
 
 /*
  * definitions for get_client_name
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/include/db.h ircd-ratbox-stable+ssl/include/db.h
--- ircd-ratbox-stable/include/db.h	Wed Dec 31 17:00:00 1969
+++ ircd-ratbox-stable+ssl/include/db.h	Tue Mar 30 12:33:16 2004
@@ -0,0 +1,69 @@
+/*
+ *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
+ *  dh.h: Diffie-Hellman key exchange header.
+ *
+ *  Copyright (C) 2003 by the past and present ircd coders, and others.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+ *  USA
+ *
+ *  $Id: dh.h,v 1.0 2003/12/03 20:17:11 Sakura Exp $
+ */
+
+#ifndef INCLUDED_dh_h
+#define INCLUDED_dh_h
+
+#include "setup.h"
+
+#ifdef HAVE_LIBCRYPTO
+#include "client.h"
+
+#define KEY_BITS 512
+
+#define RAND_BITS KEY_BITS
+#define RAND_BYTES (RAND_BITS / 8)
+#define RAND_BYTES_HEX ((RAND_BYTES * 2) + 1)
+
+#define PRIME_BITS 1024
+#define PRIME_BYTES (PRIME_BITS / 8)
+#define PRIME_BYTES_HEX ((PRIME_BYTES * 2) + 1)
+
+struct dh_session {
+   DH *dh;
+   char *session_shared;
+   int session_shared_length;
+};
+
+void dh_init(void);
+extern int dh_generate_shared(struct dh_session *, char *);
+extern int dh_get_s_shared(char *, int *, struct dh_session *);
+extern int dh_hexstr_to_raw(char *, unsigned char *, int *);
+extern void dh_end_session(struct dh_session *);
+extern struct dh_session *dh_start_session(void);
+extern char *dh_get_s_secret(char *, int, struct dh_session *);
+extern char *dh_get_s_public(char *, int, struct dh_session *);
+
+extern int safe_SSL_read(struct Client *, void *, int);
+extern int safe_SSL_write(struct Client *, const void *, int);
+extern int safe_SSL_accept(struct Client *, int);
+extern int SSL_smart_shutdown(SSL *);
+extern int initssl(void);
+extern SSL_CTX *ircdssl_ctx;
+
+#endif
+
+extern void ircd_init_ssl(void);
+
+#endif  /* INCLUDED_dh_h */
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/include/ircd.h ircd-ratbox-stable+ssl/include/ircd.h
--- ircd-ratbox-stable/include/ircd.h	Mon Mar 15 11:19:44 2004
+++ ircd-ratbox-stable+ssl/include/ircd.h	Tue Mar 30 12:41:18 2004
@@ -121,5 +121,6 @@
 extern void set_time(void);
 
 extern int testing_conf;
+extern int ssl_ok;
 
 #endif
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/include/linebuf.h ircd-ratbox-stable+ssl/include/linebuf.h
--- ircd-ratbox-stable/include/linebuf.h	Mon Mar 15 11:19:45 2004
+++ ircd-ratbox-stable+ssl/include/linebuf.h	Tue Mar 30 12:33:16 2004
@@ -80,7 +80,7 @@
 extern int linebuf_parse(buf_head_t *, char *, int, int);
 extern int linebuf_get(buf_head_t *, char *, int, int, int);
 extern void linebuf_putmsg(buf_head_t *, const char *, va_list *, const char *, ...);
-extern int linebuf_flush(int, buf_head_t *);
+extern int linebuf_flush(struct Client *, int, buf_head_t *);
 extern void linebuf_attach(buf_head_t *, buf_head_t *);
 extern void count_linebuf_memory(int *, u_long *);
 #endif
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/include/listener.h ircd-ratbox-stable+ssl/include/listener.h
--- ircd-ratbox-stable/include/listener.h	Mon Mar 15 11:19:45 2004
+++ ircd-ratbox-stable+ssl/include/listener.h	Tue Mar 30 12:33:16 2004
@@ -48,9 +48,11 @@
 	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 --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/include/numeric.h ircd-ratbox-stable+ssl/include/numeric.h
--- ircd-ratbox-stable/include/numeric.h	Mon Mar 15 11:19:45 2004
+++ ircd-ratbox-stable+ssl/include/numeric.h	Tue Mar 30 12:33:16 2004
@@ -117,6 +117,8 @@
 #define RPL_LOCALUSERS       265
 #define RPL_GLOBALUSERS      266
 
+#define RPL_USINGSSL	     275
+
 #define RPL_ACCEPTLIST	     281
 #define RPL_ENDOFACCEPT      282
 
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/include/s_conf.h ircd-ratbox-stable+ssl/include/s_conf.h
--- ircd-ratbox-stable/include/s_conf.h	Wed Mar 24 18:03:44 2004
+++ ircd-ratbox-stable+ssl/include/s_conf.h	Tue Mar 30 12:33:16 2004
@@ -32,6 +32,7 @@
 
 #ifdef HAVE_LIBCRYPTO
 #include <openssl/rsa.h>
+#include <openssl/ssl.h>
 #endif
 
 #include "config.h"		/* defines */
@@ -84,6 +85,10 @@
 	char *rsa_public_key_file;
 	RSA *rsa_public_key;
 	struct EncCapability *cipher_preference;
+	char *ssl_certificate_file;
+	char *ssl_ca_certificate_file;
+	SSL_CTX *ctx;
+	SSL_METHOD *meth;
 #endif
 };
 
@@ -306,6 +311,10 @@
 #ifdef HAVE_LIBCRYPTO
 	char *rsa_private_key_file;
 	RSA *rsa_private_key;
+  char *ssl_certificate_file;
+  char *ssl_ca_certificate_file;
+  SSL_CTX *ctx;
+  SSL_METHOD *meth;
 #endif
 	int hub;
 	struct irc_inaddr ip;
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/include/stdinc.h ircd-ratbox-stable+ssl/include/stdinc.h
--- ircd-ratbox-stable/include/stdinc.h	Wed Oct 15 09:33:59 2003
+++ ircd-ratbox-stable+ssl/include/stdinc.h	Tue Mar 30 12:33:17 2004
@@ -48,6 +48,17 @@
 #include <stddef.h>
 #endif
 
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/rsa.h> 
+#include <openssl/crypto.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+#endif
+
 
 
 #include <stdio.h>
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/include/supported.h ircd-ratbox-stable+ssl/include/supported.h
--- ircd-ratbox-stable/include/supported.h	Mon Mar 15 11:19:45 2004
+++ ircd-ratbox-stable+ssl/include/supported.h	Tue Mar 30 12:33:17 2004
@@ -63,7 +63,7 @@
 		  " CHARSET=ascii" \
 		  " CALLERID" \
 		  " ETRACE" \
-		  " WALLCHOPS"
+		  " SSL WALLCHOPS"
 
 #define FEATURES2VALUES ConfigServerHide.disable_local_channels ? "#" : "#&", \
                         ConfigChannel.use_except ? "e" : "", \
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/include/tools.h ircd-ratbox-stable+ssl/include/tools.h
--- ircd-ratbox-stable/include/tools.h	Mon Mar 15 11:19:45 2004
+++ ircd-ratbox-stable+ssl/include/tools.h	Tue Mar 30 12:33:17 2004
@@ -63,6 +63,7 @@
 void dlinkAddTail(void *data, dlink_node * m, dlink_list * list);
 
 void dlinkDelete(dlink_node * m, dlink_list * list);
+extern void dlinkDeleteNode(dlink_node *m, dlink_list *list);
 
 void dlinkMoveList(dlink_list * from, dlink_list * to);
 
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/modules/Makefile.in ircd-ratbox-stable+ssl/modules/Makefile.in
--- ircd-ratbox-stable/modules/Makefile.in	Thu Nov 27 10:31:47 2003
+++ ircd-ratbox-stable+ssl/modules/Makefile.in	Tue Mar 30 13:22:27 2004
@@ -135,25 +135,20 @@
 
 install-mkdirs:
 	-@if test ! -d $(prefix); then \
-                echo "mkdir $(prefix)"; \
                 mkdir $(prefix); \
         fi
 	
 	-@if test -d $(moduledir)-old; then \
-		echo "rm -rf $(moduledir)-old"; \
 		rm -rf $(moduledir)-old; \
 	fi
 	-@if test -d $(moduledir); then \
-		echo "mv $(moduledir) $(moduledir)-old"; \
 		mv $(moduledir) $(moduledir)-old; \
 	fi
 
 	-@if test ! -d $(moduledir); then \
-                echo "mkdir $(moduledir)"; \
                 mkdir $(moduledir); \
         fi
 	-@if test ! -d $(automoduledir); then \
-                echo "mkdir $(automoduledir)"; \
                 mkdir $(automoduledir); \
         fi
 
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/modules/m_whois.c ircd-ratbox-stable+ssl/modules/m_whois.c
--- ircd-ratbox-stable/modules/m_whois.c	Wed Mar 24 18:03:46 2004
+++ ircd-ratbox-stable+ssl/modules/m_whois.c	Tue Mar 30 12:33:17 2004
@@ -341,7 +341,13 @@
 	else
 		sendto_one(source_p, form_str(RPL_WHOISSERVER),
 			   me.name, source_p->name, target_p->name,
-			   ServerInfo.network_name, ServerInfo.network_desc);
+		   ServerInfo.network_name, ServerInfo.network_desc);
+
+#ifdef HAVE_LIBCRYPTO
+    if (target_p->ssl)
+      sendto_one(source_p, form_str(RPL_USINGSSL),
+                 me.name, source_p->name, target_p->name);	
+#endif
 
 	if(target_p->user->away)
 		sendto_one(source_p, form_str(RPL_AWAY), me.name,
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/src/Makefile.in ircd-ratbox-stable+ssl/src/Makefile.in
--- ircd-ratbox-stable/src/Makefile.in	Wed Mar 24 18:03:46 2004
+++ ircd-ratbox-stable+ssl/src/Makefile.in	Tue Mar 30 13:20:39 2004
@@ -61,6 +61,7 @@
   class.c                       \
   client.c                      \
   cluster.c			\
+  dh.c \
   dynlink.c			\
   event.c                       \
   fdlist.c                      \
@@ -106,6 +107,7 @@
   s_user.c                      \
   scache.c                      \
   send.c                        \
+  ssl.c \
   @SNPRINTF_C@			\
   sprintf_irc.c			\
   tools.c                       \
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/src/dh.c ircd-ratbox-stable+ssl/src/dh.c
--- ircd-ratbox-stable/src/dh.c	Wed Dec 31 17:00:00 1969
+++ ircd-ratbox-stable+ssl/src/dh.c	Tue Mar 30 12:33:17 2004
@@ -0,0 +1,247 @@
+/*
+ *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
+ *  dh.c: Diffie-Hellman key exchange.
+ *
+ *  Copyright (C) 2003 by the past and present ircd coders, and others.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+ *  USA
+ *
+ *  $Id: dh.c,v 1.00 2003/12/03 20:33:17 Sakura Exp $
+ */
+
+
+#include "stdinc.h"
+#include "setup.h"
+#include "config.h"
+#include "memory.h"
+
+#ifdef HAVE_LIBCRYPTO
+#include "db.h"
+
+static unsigned int dh_gen_1024;
+static unsigned char dh_prime_1024[];
+static char *hex_to_string[256];
+
+static BIGNUM *ircd_prime;
+static BIGNUM *ircd_generator;
+
+static int verify_is_hex(char *string)
+{
+    int l = strlen(string);
+    char tmp[4] = { '\0', '\0', '\0', '\0' };
+    int tmpidx = 0;
+
+    if (l & 0x01) {		/* check if it's odd length */
+	l++;
+	tmp[tmpidx++] = '0';	/* pad with zero */
+    }
+
+    while (*string) {
+	tmp[tmpidx++] = *string++;
+	if (tmpidx == 2) {
+    char *eptr;
+    unsigned char x;
+
+	    tmpidx = 0;
+
+	    x = strtol(tmp, &eptr, 16);
+	    if (*eptr != '\0') {
+		return 0;
+	    }
+	}
+    }
+    return 1;
+}
+
+static void create_prime()
+{
+char buf[PRIME_BYTES_HEX];
+int i;
+int bufpos = 0;
+
+    for (i = 0; i < PRIME_BYTES; i++) {
+char *x = hex_to_string[dh_prime_1024[i]];
+	while (*x)
+	    buf[bufpos++] = *x++;
+    }
+    buf[bufpos] = '\0';
+
+    ircd_prime = NULL;
+    BN_hex2bn(&ircd_prime, buf);
+    ircd_generator = BN_new();
+    BN_set_word(ircd_generator, dh_gen_1024);
+}
+
+void dh_init(void)
+{
+    ERR_load_crypto_strings();
+
+    printf("Importing prime...\n");
+    create_prime();
+    printf("Prime imported.\n");
+}
+
+int dh_generate_shared(struct dh_session *si, char *public_key)
+{
+    BIGNUM *tmp;
+    int len;
+
+    if (verify_is_hex(public_key) == 0 || !si || si->session_shared)
+	return 0;
+
+    tmp = NULL;
+    BN_hex2bn(&tmp, public_key);
+    if (!tmp)
+	return 0;
+
+    si->session_shared_length = DH_size(si->dh);
+    si->session_shared = (char *) MyMalloc(DH_size(si->dh));
+    len = DH_compute_key(si->session_shared, tmp, si->dh);
+    BN_free(tmp);
+
+    if (len < 0)
+	return 0;
+
+    si->session_shared_length = len;
+
+    return 1;
+}
+
+struct dh_session *dh_start_session(void)
+{
+    struct dh_session *si = (struct dh_session *) MyMalloc(sizeof(struct dh_session));
+    if (!si)
+	abort();
+
+    memset(si, 0, sizeof(struct dh_session));
+
+    si->dh = DH_new();
+    si->dh->p = BN_dup(ircd_prime);
+    si->dh->g = BN_dup(ircd_generator);
+
+    if (!DH_generate_key(si->dh)) {
+	DH_free(si->dh);
+	MyFree(si);
+	return NULL;
+    }
+
+    return (void *) si;
+}
+
+void dh_end_session(struct dh_session *si)
+{
+    if (si->dh) {
+	DH_free(si->dh);
+	si->dh = NULL;
+    }
+
+    if (si->session_shared) {
+	memset(si->session_shared, 0, si->session_shared_length);
+	MyFree(si->session_shared);
+	si->session_shared = NULL;
+    }
+
+    MyFree(si);
+}
+
+char *dh_get_s_public(char *buf, int maxlen, struct dh_session *si)
+{
+    char *tmp;
+
+    if (!si || !si->dh || !si->dh->pub_key)
+	return NULL;
+
+    tmp = BN_bn2hex(si->dh->pub_key);
+    if (!tmp)
+	return NULL;
+
+    if (strlen(tmp) + 1 > maxlen) {
+	OPENSSL_free(tmp);
+	return NULL;
+    }
+    strcpy(buf, tmp);
+    OPENSSL_free(tmp);
+
+    return buf;
+}
+
+int dh_get_s_shared(char *buf, int *maxlen, struct dh_session *si)
+{
+    if (!si || !si->session_shared || *maxlen < si->session_shared_length)
+	return 0;
+
+    *maxlen = si->session_shared_length;
+    memcpy(buf, si->session_shared, *maxlen);
+
+    return 1;
+}
+
+static char *hex_to_string[256] = {
+    "00", "01", "02", "03", "04", "05", "06", "07",
+    "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
+    "10", "11", "12", "13", "14", "15", "16", "17",
+    "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
+    "20", "21", "22", "23", "24", "25", "26", "27",
+    "28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
+    "30", "31", "32", "33", "34", "35", "36", "37",
+    "38", "39", "3a", "3b", "3c", "3d", "3e", "3f",
+    "40", "41", "42", "43", "44", "45", "46", "47",
+    "48", "49", "4a", "4b", "4c", "4d", "4e", "4f",
+    "50", "51", "52", "53", "54", "55", "56", "57",
+    "58", "59", "5a", "5b", "5c", "5d", "5e", "5f",
+    "60", "61", "62", "63", "64", "65", "66", "67",
+    "68", "69", "6a", "6b", "6c", "6d", "6e", "6f",
+    "70", "71", "72", "73", "74", "75", "76", "77",
+    "78", "79", "7a", "7b", "7c", "7d", "7e", "7f",
+    "80", "81", "82", "83", "84", "85", "86", "87",
+    "88", "89", "8a", "8b", "8c", "8d", "8e", "8f",
+    "90", "91", "92", "93", "94", "95", "96", "97",
+    "98", "99", "9a", "9b", "9c", "9d", "9e", "9f",
+    "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
+    "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
+    "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7",
+    "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf",
+    "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7",
+    "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf",
+    "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
+    "d8", "d9", "da", "db", "dc", "dd", "de", "df",
+    "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7",
+    "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef",
+    "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+    "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff"
+};
+
+static unsigned int dh_gen_1024 = 2;
+static unsigned char dh_prime_1024[] = {
+    0xF4, 0x88, 0xFD, 0x58, 0x4E, 0x49, 0xDB, 0xCD,
+    0x20, 0xB4, 0x9D, 0xE4, 0x91, 0x07, 0x36, 0x6B,
+    0x33, 0x6C, 0x38, 0x0D, 0x45, 0x1D, 0x0F, 0x7C,
+    0x88, 0xB3, 0x1C, 0x7C, 0x5B, 0x2D, 0x8E, 0xF6,
+    0xF3, 0xC9, 0x23, 0xC0, 0x43, 0xF0, 0xA5, 0x5B,
+    0x18, 0x8D, 0x8E, 0xBB, 0x55, 0x8C, 0xB8, 0x5D,
+    0x38, 0xD3, 0x34, 0xFD, 0x7C, 0x17, 0x57, 0x43,
+    0xA3, 0x1D, 0x18, 0x6C, 0xDE, 0x33, 0x21, 0x2C,
+    0xB5, 0x2A, 0xFF, 0x3C, 0xE1, 0xB1, 0x29, 0x40,
+    0x18, 0x11, 0x8D, 0x7C, 0x84, 0xA7, 0x0A, 0x72,
+    0xD6, 0x86, 0xC4, 0x03, 0x19, 0xC8, 0x07, 0x29,
+    0x7A, 0xCA, 0x95, 0x0C, 0xD9, 0x96, 0x9F, 0xAB,
+    0xD0, 0x0A, 0x50, 0x9B, 0x02, 0x46, 0xD3, 0x08,
+    0x3D, 0x66, 0xA4, 0x5D, 0x41, 0x9F, 0x9C, 0x7C,
+    0xBD, 0x89, 0x4B, 0x22, 0x19, 0x26, 0xBA, 0xAB,
+    0xA2, 0x5E, 0xC3, 0x55, 0xE9, 0x2F, 0x78, 0xC7
+};
+
+#endif
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/src/ircd.c ircd-ratbox-stable+ssl/src/ircd.c
--- ircd-ratbox-stable/src/ircd.c	Wed Mar 24 18:03:46 2004
+++ ircd-ratbox-stable+ssl/src/ircd.c	Tue Mar 30 12:33:17 2004
@@ -74,7 +74,7 @@
 #include "newconf.h"
 #include "patricia.h"
 #include "reject.h"
-
+#include "db.h"
 
 /*
  * Try and find the correct name to use with getrlimit() for setting the max.
@@ -581,6 +581,22 @@
 		fprintf(stderr, "Unable to chdir to %s: %s\n", ConfigFileEntry.dpath, strerror(errno));
 		exit(EXIT_FAILURE);
 	}
+
+#ifdef HAVE_LIBCRYPTO
+  dh_init();
+  fprintf(stderr, "SSL: Initialize\n");
+
+  SSL_load_error_strings();
+  SSLeay_add_ssl_algorithms();
+  ServerInfo.ctx = SSL_CTX_new(SSLv23_server_method());
+
+  if (!ServerInfo.ctx) {
+       ERR_print_errors_fp(stderr);
+       return 0;
+  }
+
+  fprintf(stderr, "SSL: Client based SSL connections are enabled.\n");
+#endif
 
 	setup_signals();
 
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/src/linebuf.c ircd-ratbox-stable+ssl/src/linebuf.c
--- ircd-ratbox-stable/src/linebuf.c	Mon Mar 15 11:19:55 2004
+++ ircd-ratbox-stable+ssl/src/linebuf.c	Tue Mar 30 12:33:17 2004
@@ -618,7 +618,7 @@
  */
 #undef HAVE_WRITEV
 int
-linebuf_flush(int fd, buf_head_t * bufhead)
+linebuf_flush(struct Client *client_p, int fd, buf_head_t * bufhead)
 {
 	buf_line_t *bufline;
 	int retval;
@@ -721,7 +721,14 @@
 	}
 
 	/* Now, try writing data */
+#ifdef HAVE_LIBCRYPTO
+	if (IsSSL(client_p))
+		retval = safe_SSL_write(client_p, bufline->buf + bufhead->writeofs, bufline->len - bufhead->writeofs);
+	else
+		retval = send(fd, bufline->buf + bufhead->writeofs, bufline->len - bufhead->writeofs, 0);
+#else
 	retval = send(fd, bufline->buf + bufhead->writeofs, bufline->len - bufhead->writeofs, 0);
+#endif
 
 	if(retval <= 0)
 		return retval;
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/src/listener.c ircd-ratbox-stable+ssl/src/listener.c
--- ircd-ratbox-stable/src/listener.c	Mon Mar 15 11:19:55 2004
+++ ircd-ratbox-stable+ssl/src/listener.c	Tue Mar 30 12:42:29 2004
@@ -131,8 +131,7 @@
 		sendto_one(source_p, form_str(RPL_STATSPLINE),
 			   me.name,
 			   source_p->name,
-			   'P',
-			   listener->port,
+			   listener->is_ssl ? 'S' : 'P', listener->port,
 			   IsOperAdmin(source_p) ? listener->name : me.name,
 			   listener->ref_count, (listener->active) ? "active" : "disabled");
 	}
@@ -268,7 +267,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;
@@ -299,8 +298,17 @@
 	else
 	{
 		listener = make_listener(port, &vaddr);
+        listener->is_ssl = is_ssl;
 		listener->next = ListenerPollList;
 		ListenerPollList = listener;
+
+                if (listener->is_ssl && ssl_ok != 0)
+                {
+                    ilog (L_ERROR, "SSL incorrectly setup. Disabling listener [%s/%d]", vhost_ip, port);
+                    close_listener(listener);
+                    return;
+                }
+
 	}
 
 	listener->fd = -1;
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/src/messages.tab ircd-ratbox-stable+ssl/src/messages.tab
--- ircd-ratbox-stable/src/messages.tab	Thu Nov 20 12:44:39 2003
+++ ircd-ratbox-stable+ssl/src/messages.tab	Tue Mar 30 12:33:17 2004
@@ -299,7 +299,7 @@
 /* 272 */       NULL,
 /* 273 */       NULL,
 /* 274 */       NULL,
-/* 275 */       NULL,
+/* 275 RPL_USINGSSL, */			":%s 275 %s %s :connected via SSL (secure link)",
 /* 276 */       NULL,
 /* 277 */       NULL,
 /* 278 */       NULL,
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/src/newconf.c ircd-ratbox-stable+ssl/src/newconf.c
--- ircd-ratbox-stable/src/newconf.c	Wed Mar 24 18:03:47 2004
+++ ircd-ratbox-stable+ssl/src/newconf.c	Tue Mar 30 12:40:38 2004
@@ -32,6 +32,8 @@
 
 #define CF_TYPE(x) ((x) & CF_MTYPE)
 
+int ssl_ok = 1;
+
 struct TopConf *conf_cur_block;
 static char *conf_cur_block_name;
 
@@ -432,6 +434,77 @@
 }
 
 static void
+conf_set_serverinfo_ssl_cert (void *data)
+{
+#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, (char *)data);
+
+		if (!ServerInfo.rsa_private_key_file)
+		{
+			conf_report_error ("Ignoring config file entry ssl_certificate -- no rsa_private_key");
+			ssl_ok = 0;
+			return;
+		}
+
+		if (SSL_CTX_use_certificate_file(ServerInfo.ctx, ServerInfo.ssl_certificate_file, SSL_FILETYPE_PEM) <= 0)
+		{
+			conf_report_error ("Error using config file entry ssl_certificate -- %s", ERR_error_string(ERR_get_error(), NULL));
+			ssl_ok = 0;
+			return;
+		}
+
+		if (SSL_CTX_use_PrivateKey_file(ServerInfo.ctx, ServerInfo.rsa_private_key_file, SSL_FILETYPE_PEM) <= 0)
+		{
+			conf_report_error ("Error using config file entry rsa_private_key -- %s", ERR_error_string(ERR_get_error(), NULL));
+			ssl_ok = 0;
+			return;
+		}
+
+		if (!SSL_CTX_check_private_key(ServerInfo.ctx))
+		{
+			conf_report_error ("RSA private key doesn't match the SSL certificate public key!");
+			ssl_ok = 0;
+			return;
+		}
+	}
+
+#endif
+
+}
+
+static void
+conf_set_serverinfo_ssl_ca_cert (void *data)
+{
+#ifdef HAVE_LIBCRYPTO
+	if (ServerInfo.ctx)
+	{
+		if (ServerInfo.ssl_ca_certificate_file)
+		{
+			MyFree (ServerInfo.ssl_ca_certificate_file);
+			ServerInfo.ssl_ca_certificate_file = NULL;
+		}
+
+		DupString (ServerInfo.ssl_ca_certificate_file, (char *)data);
+
+		if (ServerInfo.ssl_ca_certificate_file != NULL && SSL_CTX_load_verify_locations(ServerInfo.ctx, ServerInfo.ssl_ca_certificate_file, NULL) != 1)
+		{
+			conf_report_error ("Error using config file entry ssl_ca_certificate -- ");
+			ssl_ok = 0;
+			return;
+		}
+	}
+#endif
+}
+
+static void
 conf_set_modules_module(void *data)
 {
 #ifndef STATIC_MODULES
@@ -1094,7 +1167,24 @@
 			continue;
 		}
 
-		add_listener(args->v.number, listener_address);
+		add_listener(args->v.number, listener_address, 0);
+	}
+}
+
+static void
+conf_set_listen_sslport(void *data)
+{
+	conf_parm_t *args = data;
+
+	for (; args; args = args->next)
+	{
+		if((args->type & CF_MTYPE) != CF_INT)
+		{
+			conf_report_error("listener::port argument is not an integer -- ignoring.");
+			continue;
+		}
+
+		add_listener(args->v.number, listener_address, 1);
 	}
 }
 
@@ -2992,6 +3082,8 @@
 	add_conf_item("serverinfo", "vhost", CF_QSTRING, conf_set_serverinfo_vhost);
 	add_conf_item("serverinfo", "vhost6", CF_QSTRING, conf_set_serverinfo_vhost6);
 	add_conf_item("serverinfo", "hub", CF_YESNO, conf_set_serverinfo_hub);
+	add_conf_item("serverinfo", "ssl_certificate_file", CF_QSTRING, conf_set_serverinfo_ssl_cert);
+	add_conf_item("serverinfo", "ssl_ca_certificate_file", CF_QSTRING, conf_set_serverinfo_ssl_ca_cert);
 
 	add_top_conf("admin", NULL, NULL);
 	add_conf_item("admin", "name", CF_QSTRING, conf_set_admin_name);
@@ -3051,6 +3143,7 @@
         
 	add_top_conf("listen", conf_begin_listen, conf_end_listen);
 	add_conf_item("listen", "port", CF_INT | CF_FLIST, conf_set_listen_port);
+	add_conf_item("listen", "sslport", CF_INT | CF_FLIST, conf_set_listen_sslport);
 	add_conf_item("listen", "ip", CF_QSTRING, conf_set_listen_address);
 	add_conf_item("listen", "host", CF_QSTRING, conf_set_listen_address);
 
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/src/packet.c ircd-ratbox-stable+ssl/src/packet.c
--- ircd-ratbox-stable/src/packet.c	Mon Mar 15 11:19:55 2004
+++ ircd-ratbox-stable+ssl/src/packet.c	Tue Mar 30 12:33:17 2004
@@ -38,6 +38,7 @@
 #include "memory.h"
 #include "hook.h"
 #include "send.h"
+#include "db.h"
 
 static char readBuf[READBUF_SIZE];
 static void client_dopacket(struct Client *client_p, char *buffer, size_t length);
@@ -375,6 +376,11 @@
 	 * I personally think it makes the code too hairy to make sane.
 	 *     -- adrian
 	 */
+#ifdef HAVE_LIBCRYPTO
+  if (IsSSL(client_p))
+    length = safe_SSL_read(client_p, readBuf, READBUF_SIZE);
+  else
+#endif
 	length = recv(fd_r, readBuf, READBUF_SIZE, 0);
 
 	if(length <= 0)
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/src/s_auth.c ircd-ratbox-stable+ssl/src/s_auth.c
--- ircd-ratbox-stable/src/s_auth.c	Mon Mar 15 11:19:56 2004
+++ ircd-ratbox-stable+ssl/src/s_auth.c	Tue Mar 30 12:33:17 2004
@@ -54,6 +54,7 @@
 #include "send.h"
 #include "memory.h"
 #include "config.h"
+#include "db.h"
 
 /*
  * a bit different approach
@@ -93,8 +94,18 @@
 }
 ReportType;
 
+#ifdef HAVE_LIBCRYPTO
 #define sendheader(c, r) \
-   send((c)->localClient->fd, HeaderMessages[(r)].message, HeaderMessages[(r)].length, 0)
+   if (IsSSL(c)) \
+     safe_SSL_write(c, HeaderMessages[(r)].message, HeaderMessages[(r)].length); \
+   else \
+     send((c)->localClient->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
+//#define sendheader(c, r) \
+//   send((c)->localClient->fd, HeaderMessages[(r)].message, HeaderMessages[(r)].length, 0)
 
 static dlink_list auth_poll_list;
 static BlockHeap *auth_heap;
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/src/s_bsd.c ircd-ratbox-stable+ssl/src/s_bsd.c
--- ircd-ratbox-stable/src/s_bsd.c	Mon Mar 15 11:19:56 2004
+++ ircd-ratbox-stable+ssl/src/s_bsd.c	Tue Mar 30 12:33:17 2004
@@ -50,6 +50,7 @@
 #include "s_debug.h"
 #include "memory.h"
 #include "reject.h"
+#include "db.h"
 
 #ifndef IN_LOOPBACKNET
 #define IN_LOOPBACKNET        0x7f
@@ -72,6 +73,7 @@
 static PF comm_connect_timeout;
 static void comm_connect_dns_callback(void *vptr, adns_answer * reply);
 static PF comm_connect_tryconnect;
+static void comm_tryssl_callback(int fd, void *data);
 
 /* close_all_connections() can be used *before* the system come up! */
 
@@ -359,6 +361,9 @@
 
 	socklen_t len = sizeof(struct irc_sockaddr);
 	struct irc_sockaddr irn;
+#ifdef HAVE_LIBCRYPTO
+  int new_ssl = 0;
+#endif 
 	s_assert(NULL != listener);
 
 	/* 
@@ -415,13 +420,60 @@
 	new_client->localClient->listener = listener;
 	++listener->ref_count;
 
+#ifdef HAVE_LIBCRYPTO
+  if ((listener->is_ssl) && !(new_client->ssl))
+  {
+    new_ssl = 1;
+
+    /*SSL client init */
+    if((new_client->ssl = SSL_new(ServerInfo.ctx)) == NULL)
+    {
+      dlink_node * m;
+      m = dlinkFind(&unknown_list, new_client);
+      if (m)
+        dlinkDeleteNode(m, &unknown_list);
+      report_error(L_ALL, "Could not create new ssl connection %s :%s",
+          get_listener_name(listener), errno);
+	  sendto_realops_flags (UMODE_DEBUG, L_ALL, "Could not create new ssl connection %s :%s", get_listener_name(listener), errno);
+      ServerStats->is_ref++;
+      free_client(new_client);
+      return;
+    }
+    SetSSL(new_client);
+	sendto_realops_flags (UMODE_DEBUG, L_ALL, "Created new ssl connection %s", get_listener_name(listener));
+  }
+#endif
+
 	if(!set_non_blocking(new_client->localClient->fd))
 		report_error(L_ALL, NONB_ERROR_MSG, get_client_name(new_client, SHOW_IP), errno);
 	if(!disable_sock_options(new_client->localClient->fd))
 		report_error(L_ALL, OPT_ERROR_MSG, get_client_name(new_client, SHOW_IP), errno);
 	if(check_reject(new_client))
 		return;
-	start_auth(new_client);
+	//start_auth(new_client);
+
+#ifdef HAVE_LIBCRYPTO
+  if (IsSSL(new_client) && new_ssl)
+  {
+	sendto_realops_flags (UMODE_DEBUG, L_ALL, "Accepting SSL connection %s", get_listener_name(listener));
+    SSL_set_fd(new_client->ssl, new_client->localClient->fd);
+    if (!safe_SSL_accept(new_client, new_client->localClient->fd))
+    {
+	  dlink_node * m;
+      sendto_realops_flags (UMODE_DEBUG, L_ALL, "Unsafe acception on %s", get_listener_name(listener));
+      m = dlinkFind(&unknown_list, new_client);
+      if (m)
+        dlinkDeleteNode(m, &unknown_list);
+      SSL_set_shutdown(new_client->ssl, SSL_RECEIVED_SHUTDOWN);
+      SSL_smart_shutdown(new_client->ssl);
+      SSL_free(new_client->ssl);
+      ServerStats->is_ref++;
+      free_client(new_client);
+      return;
+    }
+  }
+#endif
+  comm_setselect(fd, FDLIST_SERVER, COMM_SELECT_WRITE, comm_tryssl_callback, new_client, 0);
 }
 
 
@@ -899,4 +951,42 @@
 
 	/* .. and return */
 	return newfd;
+}
+
+static void
+comm_tryssl_callback(int fd, void *data)
+{
+  int doauth = -1;
+  struct Client *new_client = data;
+
+  fdlist_t fdlist = FDLIST_NONE;
+
+  fdlist = FDLIST_SERVER;
+  doauth = 1;
+
+#ifdef HAVE_LIBCRYPTO
+  if (IsSSL(new_client))
+  {
+    if (!SSL_is_init_finished(new_client->ssl))
+    {
+      if (!safe_SSL_accept(new_client, new_client->localClient->fd))
+      {
+        //dead_link_on_read(new_client, errno);
+		sendto_realops_flags (UMODE_DEBUG, L_ALL, "Unsafe acception.");
+        return;
+      }
+      else
+      {
+        comm_setselect(fd, fdlist, COMM_SELECT_WRITE, comm_tryssl_callback, new_client, 0);
+        return;
+      }
+    }
+  }
+#endif
+
+  if (doauth == 1)
+  {
+    sendto_realops_flags (UMODE_DEBUG, L_ALL, "Starting Auth"); 
+    start_auth(new_client);
+  }
 }
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/src/s_conf.c ircd-ratbox-stable+ssl/src/s_conf.c
--- ircd-ratbox-stable/src/s_conf.c	Wed Mar 24 18:03:47 2004
+++ ircd-ratbox-stable+ssl/src/s_conf.c	Tue Mar 30 12:43:14 2004
@@ -1343,6 +1343,8 @@
 #ifdef IPV6
 	ConfigFileEntry.fallback_to_ip6_int = YES;
 #endif
+
+	ssl_ok = 0;
 }
 
 #undef YES
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/src/send.c ircd-ratbox-stable+ssl/src/send.c
--- ircd-ratbox-stable/src/send.c	Fri Mar 19 16:00:13 2004
+++ ircd-ratbox-stable+ssl/src/send.c	Tue Mar 30 12:33:17 2004
@@ -45,6 +45,7 @@
 #include "s_log.h"
 #include "memory.h"
 #include "hook.h"
+#include "db.h"
 
 #define LOG_BUFSIZE 2048
 
@@ -264,7 +265,7 @@
 	if(linebuf_len(&to->localClient->buf_sendq))
 	{
 		while ((retlen =
-			linebuf_flush(to->localClient->fd, &to->localClient->buf_sendq)) > 0)
+			linebuf_flush(to, to->localClient->fd, &to->localClient->buf_sendq)) > 0)
 		{
 			/* We have some data written .. update counters */
 #ifndef NDEBUG
@@ -323,6 +324,7 @@
 	/* Next, lets try to write some data */
 	if(to->localClient->slinkq)
 	{
+
 		retlen = send(to->localClient->ctrlfd,
 			      to->localClient->slinkq + to->localClient->slinkq_ofs,
 			      to->localClient->slinkq_len, 0);
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/src/ssl.c ircd-ratbox-stable+ssl/src/ssl.c
--- ircd-ratbox-stable/src/ssl.c	Wed Dec 31 17:00:00 1969
+++ ircd-ratbox-stable+ssl/src/ssl.c	Tue Mar 30 12:33:17 2004
@@ -0,0 +1,185 @@
+/*
+ *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
+ *  ssl.c: Client ssl connections.
+ *
+ *  Copyright (C) 2003 by the past and present ircd coders, and others.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+ *  USA
+ *
+ * $Id: ssl.c,v 1.0 2003/12/03 21:22:43 Sakura Exp $
+ *
+ */
+
+#include "stdinc.h"
+#include "common.h"
+#include "s_conf.h"
+#include "db.h"
+#include "send.h"
+#include "s_bsd.h"
+
+#define SAFE_SSL_READ  1
+#define SAFE_SSL_WRITE  2
+#define SAFE_SSL_ACCEPT  3
+
+#ifdef HAVE_LIBCRYPTO
+
+static int fatal_ssl_error(int, int, struct Client *);
+
+int safe_SSL_read(struct Client *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 -1;
+        }
+      case SSL_ERROR_SSL:
+        if (errno == EAGAIN)
+          return -1;
+      default:
+        return fatal_ssl_error(ssl_err, SAFE_SSL_READ, acptr);
+    }
+  }
+  return len;
+}
+
+int safe_SSL_write(struct Client *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:
+        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(struct Client *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 0;
+  }
+  return 1;
+}
+
+int SSL_smart_shutdown(SSL * ssl)
+{
+  int 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, struct Client *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]";
+  }
+
+  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?)";
+  }
+
+  /*
+  report_error(L_ADMIN, "%s to %s aborted with%serror (%s). [%s]",
+               ssl_func, get_client_name(sptr, SHOW_IP), (errno > 0) ? " " : " no ", errstr, ssl_errstr);
+  report_error(L_OPER, "%s to %s aborted with%serror (%s). [%s]",
+               ssl_func, get_client_name(sptr, MASK_IP), (errno > 0) ? " " : " no ", errstr, ssl_errstr);
+  */
+
+  errno = errtmp ? errtmp : EIO;  /* Stick a generic I/O error */
+  sptr->flags |= FLAGS_DEADSOCKET;
+  return 0;
+}
+#endif
diff --exclude-from=ratbox-ssl.ignore -uNrd ircd-ratbox-stable/src/tools.c ircd-ratbox-stable+ssl/src/tools.c
--- ircd-ratbox-stable/src/tools.c	Mon Mar 15 11:19:57 2004
+++ ircd-ratbox-stable+ssl/src/tools.c	Tue Mar 30 12:33:17 2004
@@ -256,6 +256,11 @@
 	newlist->length++;
 }
 
+void dlinkDeleteNode(dlink_node *m, dlink_list *list)
+{
+    dlinkDelete(m, list);
+    free_dlink_node(m);
+}
 
 /*
  * init_dlink_nodes
