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
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
*
*/
-/* $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
*
* 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 */
{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}
};
*
*/
-/* $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"
void print_list_memory(aClient *);
#include "find.h"
+
+#ifdef USE_SSL
+#include "ssl.h"
+#endif
*
*/
-/* $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
--- /dev/null
+#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
*
*/
-/* $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"
#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 */
#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
#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 */
#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)
#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)
char *allow;
char *address;
int port;
+ char *type;
aListener *lstn;
int legal;
aPort *next;
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
+
};
* 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 {
#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) */
/* internal defines for cptr->sockerr */
#define IRCERR_BUFALLOC -11
#define IRCERR_ZIP -12
+#define IRCERR_SSL -13
+
#endif /* __struct_include__ */
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@
INSTALL=@INSTALL@
INSTALL_BIN=@INSTALL_PROGRAM@
INSTALL_DIR=@INSTALL_DIR@
-CFLAGS=@CFLAGS@
+CFLAGS=@CFLAGS@
RES_SRC =
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
../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
* 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"
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
* 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"
*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';
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
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)))
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
#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);
#ifdef USE_CHANMODE_L
SJ_MODEMINUS('L', MODE_LISTED);
#endif
+#ifdef USE_SSL
+ SJ_MODEMINUS('S', MODE_SSL);
+#endif
}
* 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"
char tmp[PATH_MAX];
FILE *mcsfp;
char *conferr;
+#ifdef USE_SSL
+ extern int ssl_capable;
+#endif
if ((timeofday = time(NULL)) == -1)
{
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;
* 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"
}
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),
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));
* 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"
#include "fdlist.h"
#include "fds.h"
+
+
extern void engine_init();
extern fdlist default_fdlist;
extern int forked;
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;
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);
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;
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;
}
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);
length = recv(cptr->fd, readbuf, sizeof(readbuf), 0);
#endif
+#endif
+
cptr->lasttime = timeofday;
if (cptr->lasttime > cptr->since)
cptr->since = cptr->lasttime;
* - 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)
{
* 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"
void
free_port(aPort *ptr)
{
+#ifdef USE_SSL
+ MyFree(ptr->type);
+#endif
MyFree(ptr->allow);
MyFree(ptr->address);
MyFree(ptr);
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))
{
/* 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,
"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",
* 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"
}
}
#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)",
* 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"
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
{
* 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"
UMODE_x, 'x',
UMODE_X, 'X',
UMODE_j, 'j',
+#ifdef USE_SSL
+ UMODE_S, 'S',
+#endif
UMODE_K, 'K',
UMODE_I, 'I',
0, 0
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);
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))
#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
--- /dev/null
+/************************************************************************
+ * 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