diff -urN ircd-hybrid-6.0.2/README.challengeresponse ircd-hybrid-6.0.2+cr/README.challengeresponse --- ircd-hybrid-6.0.2/README.challengeresponse Thu Jan 1 01:00:00 1970 +++ ircd-hybrid-6.0.2+cr/README.challengeresponse Wed Apr 11 00:32:27 2001 @@ -0,0 +1,24 @@ +ircd-hybrid-6 Challenge/Response link patch. + +This patch modifies hybrid 6 to authenticate server links using challenge- +response rather than simple PASS. It will, when linking, generate a random +8 byte challenge, and expect a MD5 hash of this challenge and the link +password passed back. It will allow fallback to standard PASS authentication +if this is defined in config.h. + +To enable the patch, add + #define CHALLENGERESPONSE +in config.h + +To allow fallback to PASS, add + #define CHALLENGERESPONSE_FALLBACK + #define CHALLENGERESPONSE_EXPIRY 30 +also in config.h + +The CHALLENGERESPONSE_EXPIRY is the number of seconds from a connecting server +sends CHALL until it gives up waiting for the other end and reverts to PASS. + +Idea and logics by ievil & einride +Implemented by einride +Verified by ??? + diff -urN ircd-hybrid-6.0.2/include/client.h ircd-hybrid-6.0.2+cr/include/client.h --- ircd-hybrid-6.0.2/include/client.h Fri Dec 1 07:28:46 2000 +++ ircd-hybrid-6.0.2+cr/include/client.h Wed Apr 11 00:32:27 2001 @@ -314,6 +314,11 @@ #define FLAGS_SENDQEX 0x0800 /* Sendq exceeded */ #define FLAGS_IPHASH 0x1000 /* iphashed this client */ +#ifdef CHALLENGERESPONSE +#define FLAGS_CHALLENGED 0x2000 /* sent a CHALL, accept RESP from this one */ +#define FLAGS_RESPONDED 0x4000 /* sent a RESP */ +#endif + /* umodes, settable flags */ #define FLAGS_SERVNOTICE 0x0001 /* server notices such as kill */ #define FLAGS_CCONN 0x0002 /* Client Connections */ @@ -404,6 +409,13 @@ #define ClearAccess(x) ((x)->flags &= ~FLAGS_CHKACCESS) #define MyConnect(x) ((x)->local_flag != 0) #define MyClient(x) (MyConnect(x) && IsClient(x)) + +#ifdef CHALLENGERESPONSE +#define Challenged(x) ((x)->flags & FLAGS_CHALLENGED) +#define SetChallenged(x) ((x)->flags |= FLAGS_CHALLENGED) +#define Responded(x) ((x)->flags & FLAGS_RESPONDED) +#define SetResponded(x) ((x)->flags |= FLAGS_RESPONDED) +#endif /* oper flags */ #define MyOper(x) (MyConnect(x) && IsOper(x)) diff -urN ircd-hybrid-6.0.2/include/config.h ircd-hybrid-6.0.2+cr/include/config.h --- ircd-hybrid-6.0.2/include/config.h Mon Feb 19 05:47:00 2001 +++ ircd-hybrid-6.0.2+cr/include/config.h Wed Apr 11 00:32:27 2001 @@ -39,6 +39,29 @@ * */ + +/* Challenge/Response patch v1 + * + * Challenge & Response makes the server link authentication use an + * md5 based hash to securly auhtenticate with the remote server. + * + * The C/N lines passwords are used to generate the hashes used and it + * is adviceable to use a diffrent pass for C and N. + * + * To allow fallback to PASS, add + * #define CHALLENGERESPONSE_FALLBACK + * #define CHALLENGERESPONSE_EXPIRY 30 + * + * CHALLENGERESPONSE_EXPIRY is defined in seconds. + * + */ + +#define CHALLENGERESPONSE +#undef CHALLENGERESPONSE_FALLBACK +#define CHALLENGERESPONSE_EXPIRY 15 + + + /***************** MAKE SURE THIS IS CORRECT!!!!!!!!! **************/ /* ONLY EDIT "HARD_FDLIMIT_" and "INIT_MAXCLIENTS" */ diff -urN ircd-hybrid-6.0.2/include/m_commands.h ircd-hybrid-6.0.2+cr/include/m_commands.h --- ircd-hybrid-6.0.2/include/m_commands.h Sat Jul 31 04:44:44 1999 +++ ircd-hybrid-6.0.2+cr/include/m_commands.h Wed Apr 11 00:32:27 2001 @@ -98,4 +98,8 @@ extern int m_htm(struct Client *,struct Client *,int,char **); extern int m_set(struct Client *,struct Client *,int,char **); +#ifdef CHALLENGERESPONSE +extern int m_chall(struct Client *,struct Client *,int,char **); +extern int m_resp(struct Client *,struct Client *,int,char **); +#endif #endif /* INCLUDED_m_commands_h */ diff -urN ircd-hybrid-6.0.2/include/md5.h ircd-hybrid-6.0.2+cr/include/md5.h --- ircd-hybrid-6.0.2/include/md5.h Thu Jan 1 01:00:00 1970 +++ ircd-hybrid-6.0.2+cr/include/md5.h Wed Apr 11 00:32:27 2001 @@ -0,0 +1,48 @@ +/* + * md5.h + * header file for md5c.c + */ +/* + * Copyright (C) 1991, 1992 RSA Data Security, Inc. + * Created 1991. + * All rights reserved. + * + * License to copy and use this software is granted provided that it + * is identified as the "RSA Data Security, Inc. MD5 Message-Digest + * Algorithm" in all material mentioning or referencing this software + * or this function. + * + * License is also granted to make and use derivative works provided + * that such works are identified as "derived from the RSA Data + * Security, Inc. MD5 Message-Digest Algorithm" in all material + * mentioning or referencing the derived work. + * + * RSA Data Security, Inc. makes no representations concerning either + * the merchantability of this software or the suitability of this + * software for any particular purpose. It is provided "as is" + * without express or implied warranty of any kind. + * + * These notices must be retained in any copies of any part of this + * documentation and/or software. + */ + +#ifndef INCLUDED_md5_h +#define INCLUDED_md5_h + +typedef unsigned int u_32bit_t; +typedef unsigned char *POINTER; +typedef u_32bit_t UINT4; + +/* MD5 context. */ +typedef struct { + UINT4 state[4]; /* state (ABCD) */ + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD5_CTX; + + +void MD5Init (MD5_CTX * context); +void MD5Update (MD5_CTX * context, unsigned char * input, unsigned int inputLen); +void MD5Final (unsigned char * digest, MD5_CTX * context); + +#endif diff -urN ircd-hybrid-6.0.2/include/msg.h ircd-hybrid-6.0.2+cr/include/msg.h --- ircd-hybrid-6.0.2/include/msg.h Thu Nov 9 04:46:52 2000 +++ ircd-hybrid-6.0.2+cr/include/msg.h Wed Apr 11 00:32:27 2001 @@ -120,6 +120,10 @@ #define MSG_GLINE "GLINE" /* GLINE */ +#ifdef CHALLENGERESPONSE +#define MSG_CHALL "CHALL" /* CHALL */ +#define MSG_RESP "RESP" /* RESP */ +#endif #define MSG_LOCOPS "LOCOPS" /* LOCOPS */ #ifdef LWALLOPS @@ -217,6 +221,10 @@ #ifdef LTRACE { MSG_LTRACE, m_ltrace, 0, MAXPARA, 1, 0, 0, 0L }, #endif /* LTRACE */ +#ifdef CHALLENGERESPONSE + { MSG_CHALL, m_chall, 0, MAXPARA, 1, 1, 0, 0L }, + { MSG_RESP, m_resp, 0, MAXPARA, 1, 1, 0, 0L }, +#endif { MSG_PASS, m_pass, 0, MAXPARA, 1, 1, 0, 0L }, { MSG_LUSERS, m_lusers, 0, MAXPARA, 1, 0, 0, 0L }, { MSG_TIME, m_time, 0, MAXPARA, 1, 0, 0, 0L }, diff -urN ircd-hybrid-6.0.2/include/msg.h~ ircd-hybrid-6.0.2+cr/include/msg.h~ --- ircd-hybrid-6.0.2/include/msg.h~ Thu Jan 1 01:00:00 1970 +++ ircd-hybrid-6.0.2+cr/include/msg.h~ Wed Apr 11 00:32:27 2001 @@ -0,0 +1,261 @@ +/************************************************************************ + * IRC - Internet Relay Chat, include/msg.h + * Copyright (C) 1990 Jarkko Oikarinen and + * University of Oulu, Computing Center + * + * 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. + * + * $Id: msg.h,v 1.14 2000/11/09 03:46:52 lusky Exp $ + */ +#ifndef INCLUDED_msg_h +#define INCLUDED_msg_h +#ifndef INCLUDED_config_h +#include "config.h" +#endif + +struct Client; + +/* + * Message table structure + */ +struct Message +{ + char *cmd; + int (* func)(); + unsigned int count; /* number of times command used */ + int parameters; + char flags; + /* bit 0 set means that this command is allowed to be used + * only on the average of once per 2 seconds -SRB */ + + /* I could have defined other bit maps to above instead of the next two + flags that I added. so sue me. -Dianora */ + + char allow_unregistered_use; /* flag if this command can be + used if unregistered */ + + char reset_idle; /* flag if this command causes + idle time to be reset */ + unsigned long bytes; +}; + +struct MessageTree +{ + char* final; + struct Message* msg; + struct MessageTree* pointers[26]; +}; + +typedef struct MessageTree MESSAGE_TREE; + + +#define MSG_PRIVATE "PRIVMSG" /* PRIV */ +#define MSG_WHO "WHO" /* WHO -> WHOC */ +#define MSG_WHOIS "WHOIS" /* WHOI */ +#define MSG_WHOWAS "WHOWAS" /* WHOW */ +#define MSG_USER "USER" /* USER */ +#define MSG_NICK "NICK" /* NICK */ +#define MSG_SERVER "SERVER" /* SERV */ +#define MSG_LIST "LIST" /* LIST */ +#define MSG_TOPIC "TOPIC" /* TOPI */ +#define MSG_INVITE "INVITE" /* INVI */ +#define MSG_VERSION "VERSION" /* VERS */ +#define MSG_QUIT "QUIT" /* QUIT */ +#define MSG_SQUIT "SQUIT" /* SQUI */ +#define MSG_KILL "KILL" /* KILL */ +#define MSG_INFO "INFO" /* INFO */ +#define MSG_LINKS "LINKS" /* LINK */ +#define MSG_STATS "STATS" /* STAT */ +#define MSG_USERS "USERS" /* USER -> USRS */ +#define MSG_HELP "HELP" /* HELP */ +#define MSG_ERROR "ERROR" /* ERRO */ +#define MSG_AWAY "AWAY" /* AWAY */ +#define MSG_CONNECT "CONNECT" /* CONN */ +#define MSG_PING "PING" /* PING */ +#define MSG_PONG "PONG" /* PONG */ +#define MSG_OPER "OPER" /* OPER */ +#define MSG_PASS "PASS" /* PASS */ +#define MSG_WALLOPS "WALLOPS" /* WALL */ +#define MSG_TIME "TIME" /* TIME */ +#define MSG_NAMES "NAMES" /* NAME */ +#define MSG_ADMIN "ADMIN" /* ADMI */ +#define MSG_TRACE "TRACE" /* TRAC */ +#define MSG_LTRACE "LTRACE" /* LTRA */ +#define MSG_NOTICE "NOTICE" /* NOTI */ +#define MSG_JOIN "JOIN" /* JOIN */ +#define MSG_PART "PART" /* PART */ +#define MSG_LUSERS "LUSERS" /* LUSE */ +#define MSG_MOTD "MOTD" /* MOTD */ +#define MSG_MODE "MODE" /* MODE */ +#define MSG_KICK "KICK" /* KICK */ +#define MSG_USERHOST "USERHOST" /* USER -> USRH */ +#define MSG_ISON "ISON" /* ISON */ +#define MSG_REHASH "REHASH" /* REHA */ +#define MSG_RESTART "RESTART" /* REST */ +#define MSG_CLOSE "CLOSE" /* CLOS */ +#define MSG_SVINFO "SVINFO" /* SVINFO */ +#define MSG_SJOIN "SJOIN" /* SJOIN */ +#define MSG_CAPAB "CAPAB" /* CAPAB */ +#define MSG_DIE "DIE" /* DIE */ +#define MSG_HASH "HASH" /* HASH */ +#define MSG_DNS "DNS" /* DNS -> DNSS */ +#define MSG_OPERWALL "OPERWALL" /* OPERWALL */ +#define MSG_KLINE "KLINE" /* KLINE */ +#define MSG_UNKLINE "UNKLINE" /* UNKLINE */ +#define MSG_DLINE "DLINE" /* DLINE */ +#define MSG_HTM "HTM" /* HTM */ +#define MSG_SET "SET" /* SET */ + +#define MSG_GLINE "GLINE" /* GLINE */ + + +#define MSG_LOCOPS "LOCOPS" /* LOCOPS */ +#ifdef LWALLOPS +#define MSG_LWALLOPS "LWALLOPS" /* Same as LOCOPS */ +#endif /* LWALLOPS */ +#define MSG_KNOCK "KNOCK" /* KNOCK */ + +#define MAXPARA 15 + +#define MSG_TESTLINE "TESTLINE" + +#ifdef MSGTAB +#ifndef INCLUDED_m_commands_h +#include "m_commands.h" /* m_xxx */ +#endif +struct Message msgtab[] = { +#ifdef IDLE_FROM_MSG /* reset idle time only if privmsg used */ +#ifdef IDLE_CHECK /* reset idle time only if valid target for privmsg + and target is not source */ + + /* |-- allow use even when unreg. + v yes/no */ + { MSG_PRIVATE, m_private, 0, MAXPARA, 1, 0, 0, 0L }, +#else + { MSG_PRIVATE, m_private, 0, MAXPARA, 1, 0, 1, 0L }, +#endif + + /* ^ + |__ reset idle time when 1 */ +#else /* IDLE_FROM_MSG */ +#ifdef IDLE_CHECK /* reset idle time on anything but privmsg */ + { MSG_PRIVATE, m_private, 0, MAXPARA, 1, 0, 1, 0L }, +#else + { MSG_PRIVATE, m_private, 0, MAXPARA, 1, 0, 0, 0L }, + /* ^ + |__ reset idle time when 0 */ +#endif /* IDLE_CHECK */ +#endif /* IDLE_FROM_MSG */ + + { MSG_NICK, m_nick, 0, MAXPARA, 1, 1, 0, 0L }, + { MSG_NOTICE, m_notice, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_JOIN, m_join, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_MODE, m_mode, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_QUIT, m_quit, 0, MAXPARA, 1, 1, 0, 0L }, + { MSG_PART, m_part, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_KNOCK, m_knock, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_TOPIC, m_topic, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_INVITE, m_invite, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_KICK, m_kick, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_WALLOPS, m_wallops, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_LOCOPS, m_locops, 0, MAXPARA, 1, 0, 0, 0L }, +#ifdef LWALLOPS + { MSG_LWALLOPS,m_locops, 0, MAXPARA, 1, 0, 0, 0L }, +#endif /* LWALLOPS */ + +#ifdef IDLE_FROM_MSG + + /* Only m_private has reset idle flag set */ + { MSG_PONG, m_pong, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_PING, m_ping, 0, MAXPARA, 1, 0, 0, 0L }, + +#else + + /* else for IDLE_FROM_MSG */ + /* reset idle flag sense is reversed, only reset idle time + * when its 0, for IDLE_FROM_MSG ping/pong do not reset idle time + */ + + { MSG_PONG, m_pong, 0, MAXPARA, 1, 0, 1, 0L }, + { MSG_PING, m_ping, 0, MAXPARA, 1, 0, 1, 0L }, + +#endif /* IDLE_FROM_MSG */ + + { MSG_ERROR, m_error, 0, MAXPARA, 1, 1, 0, 0L }, + { MSG_KILL, m_kill, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_USER, m_user, 0, MAXPARA, 1, 1, 0, 0L }, + { MSG_AWAY, m_away, 0, MAXPARA, 1, 0, 0, 0L }, +#ifdef IDLE_FROM_MSG + { MSG_ISON, m_ison, 0, 1, 1, 0, 0, 0L }, +#else + /* ISON should not reset idle time ever + * remember idle flag sense is reversed when IDLE_FROM_MSG is undefined + */ + { MSG_ISON, m_ison, 0, 1, 1, 0, 1, 0L }, +#endif /* !IDLE_FROM_MSG */ + { MSG_SERVER, m_server, 0, MAXPARA, 1, 1, 0, 0L }, + { MSG_SQUIT, m_squit, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_WHOIS, m_whois, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_WHO, m_who, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_WHOWAS, m_whowas, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_LIST, m_list, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_NAMES, m_names, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_USERHOST,m_userhost, 0, 1, 1, 0, 0, 0L }, + { MSG_TRACE, m_trace, 0, MAXPARA, 1, 0, 0, 0L }, +#ifdef LTRACE + { MSG_LTRACE, m_ltrace, 0, MAXPARA, 1, 0, 0, 0L }, +#endif /* LTRACE */ + { MSG_PASS, m_pass, 0, MAXPARA, 1, 1, 0, 0L }, + { MSG_LUSERS, m_lusers, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_TIME, m_time, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_OPER, m_oper, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_CONNECT, m_connect, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_VERSION, m_version, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_STATS, m_stats, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_LINKS, m_links, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_ADMIN, m_admin, 0, MAXPARA, 1, 1, 0, 0L }, + { MSG_USERS, m_users, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_HELP, m_help, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_INFO, m_info, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_MOTD, m_motd, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_SVINFO, m_svinfo, 0, MAXPARA, 1, 1, 0, 0L }, + { MSG_SJOIN, m_sjoin, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_CAPAB, m_capab, 0, MAXPARA, 1, 1, 0, 0L }, + { MSG_OPERWALL, m_operwall,0, MAXPARA, 1, 0, 0, 0L }, + { MSG_CLOSE, m_close, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_KLINE, m_kline, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_UNKLINE, m_unkline, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_DLINE, m_dline, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_GLINE, m_gline, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_HASH, m_hash, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_DNS, m_dns, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_REHASH, m_rehash, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_RESTART, m_restart, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_DIE, m_die, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_HTM, m_htm, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_SET, m_set, 0, MAXPARA, 1, 0, 0, 0L }, + { MSG_TESTLINE, m_testline, 0, MAXPARA, 1, 0, 0, 0L }, + { (char *) 0, (int (*)()) 0 , 0, 0, 0, 0, 0, 0L } +}; + +struct MessageTree* msg_tree_root; + +#else +extern struct Message msgtab[]; +extern struct MessageTree* msg_tree_root; +#endif + +#endif /* INCLUDED_msg_h */ + diff -urN ircd-hybrid-6.0.2/include/s_cr.h ircd-hybrid-6.0.2+cr/include/s_cr.h --- ircd-hybrid-6.0.2/include/s_cr.h Thu Jan 1 01:00:00 1970 +++ ircd-hybrid-6.0.2+cr/include/s_cr.h Wed Apr 11 00:32:27 2001 @@ -0,0 +1,25 @@ +/************************************************************************ + * IRC - Internet Relay Chat, include/s_cr.h + * April 7. 2001 - einride + */ + +#ifndef INCLUDED_s_cr_h +#define INCLUDED_s_cr_h + +#include "client.h" +#include "common.h" + + +#ifdef CHALLENGERESPONSE + +#ifdef CHALLENGERESPONSE_FALLBACK +void cr_checkfallback(); +#endif + +void cr_sendchallenge(struct Client * cptr, struct ConfItem * n_conf); +void cr_sendresponse(struct Client * cptr, struct ConfItem * c_conf, char * chall); +void cr_gotresponse(struct Client * cptr, char * resp); + +#endif + +#endif diff -urN ircd-hybrid-6.0.2/include/setup.h ircd-hybrid-6.0.2+cr/include/setup.h --- ircd-hybrid-6.0.2/include/setup.h Thu Jan 1 01:00:00 1970 +++ ircd-hybrid-6.0.2+cr/include/setup.h Wed Apr 11 00:32:27 2001 @@ -0,0 +1,73 @@ +/* include/setup.h. Generated automatically by configure. */ +/* include/setup.h.in. Generated automatically from configure.in by autoheader. + * + * $Id: setup.h.in,v 1.6 2000/10/06 03:00:57 lusky Exp $ + */ + +/* Define if you need to in order for stat and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define only one of POSIX, BSD, or SYSV signals. */ +/* Define if your system has reliable POSIX signals. */ +/* #undef POSIX_SIGNALS */ + +/* Define if your system has reliable BSD signals. */ +#define BSD_RELIABLE_SIGNALS 1 + +/* Define if your system has unreliable SYSV signals. */ +/* #undef SYSV_UNRELIABLE_SIGNALS */ + +/* Define if you have the poll() system call. */ +#define USE_POLL 1 + +/* Chose only one of NBLOCK_POSIX, NBLOCK_BSD, and NBLOCK_SYSV */ +/* Define if you have posix non-blocking sockets (O_NONBLOCK) */ +#define NBLOCK_POSIX 1 + +/* Define if you have BSD non-blocking sockets (O_NDELAY) */ +/* #undef NBLOCK_BSD */ + +/* Define if you have SYSV non-blocking sockets (FIONBIO) */ +/* #undef NBLOCK_SYSV */ + +/* Define if you have the mmap() function. */ +/* #undef USE_MMAP */ + +/* Define if you are running SOLARIS2. */ +/* #undef OS_SOLARIS2 */ + +/* Define if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +#define HAVE_GETOPT_H 1 + +/* Define if you have the descrypt library (-ldescrypt). */ +/* #undef HAVE_LIBDESCRYPT */ + +/* Define if you have the nsl library (-lnsl). */ +#define HAVE_LIBNSL 1 + +/* Define if you have the resolv library (-lresolv). */ +#define HAVE_LIBRESOLV 1 + +/* Define if you have the socket library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ diff -urN ircd-hybrid-6.0.2/src/Makefile.in ircd-hybrid-6.0.2+cr/src/Makefile.in --- ircd-hybrid-6.0.2/src/Makefile.in Thu Jun 22 07:40:55 2000 +++ ircd-hybrid-6.0.2+cr/src/Makefile.in Wed Apr 11 00:32:27 2001 @@ -36,6 +36,7 @@ m_admin.c \ m_away.c \ m_capab.c \ + m_chall.c \ m_close.c \ m_connect.c \ m_die.c \ @@ -61,6 +62,7 @@ m_pong.c \ m_quit.c \ m_rehash.c \ + m_resp.c \ m_restart.c \ m_server.c \ m_set.c \ @@ -77,6 +79,7 @@ m_who.c \ m_whois.c \ match.c \ + md5.c \ motd.c \ mtrie_conf.c \ oratime.c \ @@ -87,6 +90,7 @@ restart.c \ s_auth.c \ s_bsd.c \ + s_cr.c \ s_conf.c \ s_debug.c \ s_log.c \ diff -urN ircd-hybrid-6.0.2/src/ircd.c ircd-hybrid-6.0.2+cr/src/ircd.c --- ircd-hybrid-6.0.2/src/ircd.c Sun Dec 31 01:12:00 2000 +++ ircd-hybrid-6.0.2+cr/src/ircd.c Wed Apr 11 00:32:27 2001 @@ -40,6 +40,7 @@ #include "restart.h" #include "s_auth.h" #include "s_bsd.h" +#include "s_cr.h" #include "s_conf.h" #include "s_debug.h" #include "s_log.h" @@ -154,6 +155,10 @@ time_t nextconnect = 1; /* time for next try_connections call */ time_t nextping = 1; /* same as above for check_pings() */ +#ifdef CHALLENGERESPONSE +time_t cr_challengeexpirytime = 0; +#endif + /* code added by mika nystrom (mnystrom@mit.edu) */ /* this flag is used to signal globally that the server is heavily loaded, something which can be taken into account when processing e.g. user commands @@ -526,7 +531,13 @@ nextping = check_pings(CurrentTime); timeout_auth_queries(CurrentTime); } - +#ifdef CHALLENGERESPONSE +#ifdef CHALLENGERESPONSE_FALLBACK + if (cr_challengeexpirytime && (CurrentTime >= cr_challengeexpirytime)) { + cr_checkfallback(); + } +#endif +#endif if (dorehash && !LIFESUX) { rehash(&me, &me, 1); diff -urN ircd-hybrid-6.0.2/src/m_chall.c ircd-hybrid-6.0.2+cr/src/m_chall.c --- ircd-hybrid-6.0.2/src/m_chall.c Thu Jan 1 01:00:00 1970 +++ ircd-hybrid-6.0.2+cr/src/m_chall.c Wed Apr 11 00:32:27 2001 @@ -0,0 +1,123 @@ + +/************************************************************************ + * IRC - Internet Relay Chat, src/m_chall.c + * April 6. 2001, einride. + */ +#include "m_commands.h" /* m_pass prototype */ +#include "client.h" /* client struct */ +#include "irc_string.h" /* strncpy_irc */ +#include "send.h" /* sendto_one */ +#include "numeric.h" /* ERR_xxx */ +#include "ircd.h" /* me */ +#include "s_conf.h" /* find_conf* */ +#include "s_log.h" +#include "s_cr.h" + +#ifdef CHALLENGERESPONSE + +/* + * m_functions execute protocol messages on this server: + * + * cptr is always NON-NULL, pointing to a *LOCAL* client + * structure (with an open socket connected!). This + * identifies the physical socket where the message + * originated (or which caused the m_function to be + * executed--some m_functions may call others...). + * + * sptr is the source of the message, defined by the + * prefix part of the message if present. If not + * or prefix not found, then sptr==cptr. + * + * (!IsServer(cptr)) => (cptr == sptr), because + * prefixes are taken *only* from servers... + * + * (IsServer(cptr)) + * (sptr == cptr) => the message didn't + * have the prefix. + * + * (sptr != cptr && IsServer(sptr) means + * the prefix specified servername. (?) + * + * (sptr != cptr && !IsServer(sptr) means + * that message originated from a remote + * user (not local). + * + * combining + * + * (!IsServer(sptr)) means that, sptr can safely + * taken as defining the target structure of the + * message in this server. + * + * *Always* true (if 'parse' and others are working correct): + * + * 1) sptr->from == cptr (note: cptr->from == cptr) + * + * 2) MyConnect(sptr) <=> sptr == cptr (e.g. sptr + * *cannot* be a local connection, unless it's + * actually cptr!). [MyConnect(x) should probably + * be defined as (x == x->from) --msa ] + * + * parc number of variable parameter strings (if zero, + * parv is allowed to be NULL) + * + * parv a NULL terminated list of parameter pointers, + * + * parv[0], sender (prefix string), if not present + * this points to an empty string. + * parv[1]...parv[parc-1] + * pointers to additional parameters + * parv[parc] == NULL, *always* + * + * note: it is guaranteed that parv[0]..parv[parc-1] are all + * non-NULL pointers. + */ + +int m_chall(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) +{ + char* chall = parc > 2 ? parv[2] : ""; + char* host = parc > 1 ? parv[1] : ""; + struct ConfItem *n_conf, *c_conf; + + /* If we know this, we shouldn't be getting a chall */ + if (IsPerson(cptr) || IsServer(cptr)) + return 0; + + /* See if we got c and n lines. */ + if (!(n_conf = find_conf_by_name(host, CONF_NOCONNECT_SERVER))) { + sendto_ops("Challenge rejected. No N line for server %s", host); + log(L_NOTICE, "Challenge rejected. No N line for server %s", host); + sendto_one(cptr, "ERROR :Access denied. No N line"); + return exit_client(cptr, cptr, cptr, "Access denied. No N line"); + } + + if (!(c_conf = find_conf_by_name(host, CONF_CONNECT_SERVER))) { + sendto_ops("Challenge rejected. No C line for server %s", host); + log(L_NOTICE, "Challenge rejected. No C line for server %s", host); + sendto_one(cptr, "ERROR :Access denied. No C line"); + return exit_client(cptr, cptr, cptr, "Access denied. No C line"); + } + + /* Check if the ip matches the c/n IPs */ + if ( (cptr->ip.s_addr != c_conf->ipnum.s_addr) || (cptr->ip.s_addr != n_conf->ipnum.s_addr)) { + sendto_ops("Challenge rejected. C/N line IP doesn't match connection"); + log(L_NOTICE, "Challenge rejected. C/N line IP doesn't match connection"); + sendto_one(cptr, "ERROR :Access denied. C/N line don't match you"); + return exit_client(cptr, cptr, cptr, "Access denied. C/N line don't match"); + } + + /* Ok, it got c/n lines and correct ip, lets challenge it back */ + if (!Challenged(cptr)) + cr_sendchallenge(cptr, n_conf); + + /* And send a response. */ + cr_sendresponse(cptr, c_conf, chall); + + /* check for TS as in m_pass */ + if (parc > 3) + { + if (0 == irccmp(parv[3], "TS")) + cptr->tsinfo = TS_DOESTS; + } + return 0; +} +#endif diff -urN ircd-hybrid-6.0.2/src/m_resp.c ircd-hybrid-6.0.2+cr/src/m_resp.c --- ircd-hybrid-6.0.2/src/m_resp.c Thu Jan 1 01:00:00 1970 +++ ircd-hybrid-6.0.2+cr/src/m_resp.c Wed Apr 11 00:32:27 2001 @@ -0,0 +1,106 @@ + +/************************************************************************ + * IRC - Internet Relay Chat, src/m_resp.c + * April 6. 2001, einride. + */ +#include "m_commands.h" /* m_pass prototype */ +#include "client.h" /* client struct */ +#include "irc_string.h" /* strncpy_irc */ +#include "send.h" /* sendto_one */ +#include "numeric.h" /* ERR_xxx */ +#include "ircd.h" /* me */ +#include "s_conf.h" /* find_conf* */ +#include "s_log.h" +#include "s_cr.h" +#include "s_serv.h" + +#ifdef CHALLENGERESPONSE +/* + * m_functions execute protocol messages on this server: + * + * cptr is always NON-NULL, pointing to a *LOCAL* client + * structure (with an open socket connected!). This + * identifies the physical socket where the message + * originated (or which caused the m_function to be + * executed--some m_functions may call others...). + * + * sptr is the source of the message, defined by the + * prefix part of the message if present. If not + * or prefix not found, then sptr==cptr. + * + * (!IsServer(cptr)) => (cptr == sptr), because + * prefixes are taken *only* from servers... + * + * (IsServer(cptr)) + * (sptr == cptr) => the message didn't + * have the prefix. + * + * (sptr != cptr && IsServer(sptr) means + * the prefix specified servername. (?) + * + * (sptr != cptr && !IsServer(sptr) means + * that message originated from a remote + * user (not local). + * + * combining + * + * (!IsServer(sptr)) means that, sptr can safely + * taken as defining the target structure of the + * message in this server. + * + * *Always* true (if 'parse' and others are working correct): + * + * 1) sptr->from == cptr (note: cptr->from == cptr) + * + * 2) MyConnect(sptr) <=> sptr == cptr (e.g. sptr + * *cannot* be a local connection, unless it's + * actually cptr!). [MyConnect(x) should probably + * be defined as (x == x->from) --msa ] + * + * parc number of variable parameter strings (if zero, + * parv is allowed to be NULL) + * + * parv a NULL terminated list of parameter pointers, + * + * parv[0], sender (prefix string), if not present + * this points to an empty string. + * parv[1]...parv[parc-1] + * pointers to additional parameters + * parv[parc] == NULL, *always* + * + * note: it is guaranteed that parv[0]..parv[parc-1] are all + * non-NULL pointers. + */ + +int m_resp(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) +{ + char * resp = parc > 1 ? parv[1] : NULL; + struct ConfItem *c_conf, *n_conf; + + /* If we didn't challenge, a user most likely sent a RESP. */ + if (!Challenged(cptr)) { + log(L_NOTICE, "Got a RESP but never sent a CHALL? Something's fishy."); + return exit_client(cptr, cptr, cptr, "I didn't challenge you!"); + } + + /* Ok we challenged. Handle the resp */ + cr_gotresponse(cptr, resp); + + if (!IsUnknown(cptr)) { + /* If we're the connecting party, send CAPAB/SERVER now. + If not, we're in the state we would be after a single PASS line + received, and we just wait for m_server to trigger */ + + c_conf = find_conf_name(cptr->confs, cptr->name, CONF_CONNECT_SERVER); + n_conf = find_conf_name(cptr->confs, cptr->name, CONF_NOCONNECT_SERVER); + if (c_conf && n_conf) + { + send_capabilities(cptr, (c_conf->flags & CONF_FLAGS_ZIP_LINK)); + sendto_one(cptr, "SERVER %s 1 :%s", + my_name_for_link(me.name, n_conf), me.info); + } + } + return 0; +} + +#endif diff -urN ircd-hybrid-6.0.2/src/md5.c ircd-hybrid-6.0.2+cr/src/md5.c --- ircd-hybrid-6.0.2/src/md5.c Thu Jan 1 01:00:00 1970 +++ ircd-hybrid-6.0.2+cr/src/md5.c Wed Apr 11 00:32:27 2001 @@ -0,0 +1,301 @@ +/* + * md5c.c + * RSA Data Security, Inc., MD5 message-digest algorithm + */ +/* + * Copyright (C) 1991, 1992 RSA Data Security, Inc. + * Created 1991. + * All rights reserved. + * + * License to copy and use this software is granted provided that it + * is identified as the "RSA Data Security, Inc. MD5 Message-Digest + * Algorithm" in all material mentioning or referencing this software + * or this function. + * + * License is also granted to make and use derivative works provided + * that such works are identified as "derived from the RSA Data + * Security, Inc. MD5 Message-Digest Algorithm" in all material + * mentioning or referencing the derived work. + * + * RSA Data Security, Inc. makes no representations concerning either + * the merchantability of this software or the suitability of this + * software for any particular purpose. It is provided "as is" + * without express or implied warranty of any kind. + * + * These notices must be retained in any copies of any part of this + * documentation and/or software. + */ + +#include +#include +#include "md5.h" + +static void MD5Transform (UINT4 state[4], unsigned char block[64]); +static void Decode (UINT4 * output, unsigned char * input, unsigned int len); +static void Encode (unsigned char * output, UINT4 * input, unsigned int len); + +/* + * Constants for MD5Transform routine. + */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + + +static unsigned char PADDING[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * F, G, H and I are basic MD5 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* + * ROTATE_LEFT rotates x left n bits. + */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* + * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. + * Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +/* + * MD5 initialization. + * Begins an MD5 operation, writing a new context. + */ +void MD5Init (MD5_CTX * context) +{ + context->count[0] = context->count[1] = 0; + /* Load magic initialization constants. */ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* + * MD5 block update operation. + * Continues an MD5 message-digest operation, + * processing another message block and updating the context. + */ +void MD5Update (MD5_CTX * context, unsigned char * input, unsigned int inputLen) +{ + unsigned int i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (unsigned int)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((UINT4)inputLen << 3)) + < ((UINT4)inputLen << 3)) + context->count[1]++; + context->count[1] += ((UINT4)inputLen >> 29); + + partLen = 64 - index; + + /* Transform as many times as possible. */ + if (inputLen >= partLen) { + memcpy + ((POINTER)&context->buffer[index], (POINTER)input, partLen); + MD5Transform (context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD5Transform (context->state, &input[i]); + + index = 0; + } + else + i = 0; + + /* Buffer remaining input */ + memcpy + ((POINTER)&context->buffer[index], (POINTER)&input[i], + inputLen-i); +} + +/* + * MD5 finalization. + * Ends an MD5 message-digest operation, + * writing the the message digest and zeroizing the context. + */ +void MD5Final (unsigned char * digest, MD5_CTX * context) +{ + unsigned char bits[8]; + unsigned int index, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64. */ + index = (unsigned int)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + MD5Update (context, PADDING, padLen); + + /* Append length (before padding) */ + MD5Update (context, bits, 8); + /* Store state in digest */ + Encode (digest, context->state, 16); + + /* Zeroize sensitive information. */ + memset ((POINTER)context, 0, sizeof (*context)); +} + +/* + * MD5 basic transformation. + * Transforms state based on block. + */ +static void MD5Transform (UINT4 state[4], unsigned char block[64]) +{ + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. */ + memset ((POINTER)x, 0, sizeof (x)); +} + +/* + * Encodes input (UINT4) into output (unsigned char). + * Assumes len is a multiple of 4. + */ +static void Encode (unsigned char * output, UINT4 * input, unsigned int len) +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } +} + +/* + * Decodes input (unsigned char) into output (UINT4). + * Assumes len is a multiple of 4. + */ +static void Decode (UINT4 * output, unsigned char * input, unsigned int len) +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | + (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); +} diff -urN ircd-hybrid-6.0.2/src/s_bsd.c ircd-hybrid-6.0.2+cr/src/s_bsd.c --- ircd-hybrid-6.0.2/src/s_bsd.c Sun Dec 31 01:12:01 2000 +++ ircd-hybrid-6.0.2+cr/src/s_bsd.c Wed Apr 11 00:32:27 2001 @@ -35,6 +35,7 @@ #include "restart.h" #include "s_auth.h" #include "s_conf.h" +#include "s_cr.h" #include "s_log.h" #include "s_serv.h" #include "s_stats.h" @@ -374,6 +375,9 @@ SetHandshake(cptr); +#ifdef CHALLENGERESPONSE + cr_sendchallenge(cptr, n_conf); +#else if (!EmptyString(c_conf->passwd)) sendto_one(cptr, "PASS %s :TS", c_conf->passwd); @@ -381,7 +385,7 @@ sendto_one(cptr, "SERVER %s 1 :%s", my_name_for_link(me.name, n_conf), me.info); - +#endif return (IsDead(cptr)) ? 0 : 1; } diff -urN ircd-hybrid-6.0.2/src/s_cr.c ircd-hybrid-6.0.2+cr/src/s_cr.c --- ircd-hybrid-6.0.2/src/s_cr.c Thu Jan 1 01:00:00 1970 +++ ircd-hybrid-6.0.2+cr/src/s_cr.c Wed Apr 11 00:32:27 2001 @@ -0,0 +1,125 @@ +#include "client.h" +#include "common.h" +#include "s_log.h" +#include "irc_string.h" +#include "s_bsd.h" +#include "ircd.h" +#include "send.h" +#include "md5.h" +#include "s_conf.h" +#include "s_serv.h" +#include +#include +#include + +#ifdef CHALLENGERESPONSE +#ifdef CHALLENGERESPONSE_FALLBACK +extern time_t cr_challengeexpirytime; +void cr_checkfallback() { + /* The cr_challengeexpirytime was reached. So, let's look through + or list for servers we are connecting to which we haven't got + a password for (aka no RESP received), and the connect happened + more than CHALLENGERESPONSE_EXPIRY seconds ago. If we find one, + we revert to PASS. By lagging servers it'd be possible to provoke + a fallback to PASS, so this could be exploited. + - einride. + */ + time_t nextexpiry = 0; + struct Client * cptr; + struct ConfItem *c_conf, *n_conf; + for (cptr=GlobalClientList; cptr; cptr = cptr->next_local_client) { + if (Challenged(cptr) && !Responded(cptr)) { + if (cptr->firsttime < (CurrentTime - CHALLENGERESPONSE_EXPIRY)) { + /* Revert to PASS */ + log(L_NOTICE, "CR expiry time reached for %s - fallback", cptr->name ? cptr->name : ""); + c_conf = find_conf_by_name(cptr->name, CONF_CONNECT_SERVER); + n_conf = find_conf_by_name(cptr->name, CONF_NOCONNECT_SERVER); + if (c_conf && n_conf) { + sendto_ops("Trying PASS to authenticate with %s", cptr->name); + if (!EmptyString(c_conf->passwd)) + sendto_one(cptr, "PASS %s :TS", c_conf->passwd); + send_capabilities(cptr, (c_conf->flags & CONF_FLAGS_ZIP_LINK)); + sendto_one(cptr, "SERVER %s 1 :%s", + my_name_for_link(me.name, n_conf), me.info); + } else { + sendto_ops("Can't find C/N lines on CR expiry - dropping %s", cptr->name); + log(L_NOTICE, "Can't find C/N lines on CR expiry - dropping %s", cptr->name); + exit_client(cptr, cptr, cptr, "No C/N lines"); + } + } else { + if (!nextexpiry || nextexpiry > (cptr->firsttime + CHALLENGERESPONSE_EXPIRY)) + nextexpiry = (cptr->firsttime + CHALLENGERESPONSE_EXPIRY); + } + } + } + cr_challengeexpirytime=nextexpiry; +} +#endif + +void cr_sendchallenge(struct Client * cptr, struct ConfItem * n_conf) { + /* Create a challenge using random data and sending it as a hex value. + Store this hex value in cptr->passwd, don't want more fields in cptr. + As this is sent before anything else, we pass the server name too so + the receiving end can look up our C/N lines. + */ + char chall[17]=""; + unsigned int c; + int i; + srandom(time(0)); + for (i=0; i<16; i++) { + c = (unsigned int) (16.0 * (random() / (RAND_MAX + 1.0))); + chall[i] = (c>=10) ? (c - 10 + 'A' ) : (c + '0'); + } + chall[16]=0; + sendto_one(cptr, "CHALL %s %s :TS", me.name, chall); + strncpy_irc(cptr->name, n_conf->name, HOSTLEN); + strcpy(cptr->passwd, chall); + SetChallenged(cptr); + sendto_ops("Sent password challenge to %s", cptr->name); +#ifdef CHALLENGERESPONSE_FALLBACK + if (!cr_challengeexpirytime) + cr_challengeexpirytime = CurrentTime + CHALLENGERESPONSE_EXPIRY; +#endif +} + +void cr_hashstring(char * src, char * trg) { + unsigned char md[16]; + int i; + MD5_CTX ctx; + MD5Init(&ctx); + MD5Update(&ctx, src, strlen(src)); + MD5Final(md, &ctx); + ircsprintf(trg, "%08x", * (unsigned int *) &md[0]); + ircsprintf(trg + 8, "%08x", * (unsigned int *) &md[4]); + ircsprintf(trg + 16, "%08x", * (unsigned int *) &md[8]); + ircsprintf(trg + 24, "%08x", * (unsigned int *) &md[12]); +} + +void cr_sendresponse(struct Client * cptr, struct ConfItem * c_conf, char * chall) { + char work[PASSWDLEN*2], hash[36]; + strncpy_irc(work, chall, PASSWDLEN); + strncpy_irc(work + strlen(work), c_conf->passwd ? c_conf->passwd : "", PASSWDLEN); + cr_hashstring(work, hash); + sendto_one(cptr, "RESP %s", hash); + SetResponded(cptr); + sendto_ops("Sent password response to %s", cptr->name); +} + +void cr_gotresponse(struct Client * cptr, char * resp) { + struct ConfItem * n_conf; + char work[PASSWDLEN*2], hash[36]; + n_conf = find_conf_by_name(cptr->name, CONF_NOCONNECT_SERVER); + if (n_conf && cptr->passwd[0]) { + strncpy_irc(work, cptr->passwd, PASSWDLEN); + strncpy_irc(work + strlen(work), n_conf->passwd ? n_conf->passwd : "", PASSWDLEN); + cr_hashstring(work, hash); + if (!strcmp(resp, hash)) { + strncpy_irc(cptr->passwd, n_conf->passwd, PASSWDLEN); + sendto_ops("Got a good password response from %s", cptr->name); + } else { + sendto_ops("Failed password response from %s", cptr->name); + } + } +} + +#endif diff -urN ircd-hybrid-6.0.2/src/s_serv.c ircd-hybrid-6.0.2+cr/src/s_serv.c --- ircd-hybrid-6.0.2/src/s_serv.c Tue Nov 21 07:49:32 2000 +++ ircd-hybrid-6.0.2+cr/src/s_serv.c Wed Apr 11 00:32:27 2001 @@ -567,6 +567,14 @@ #else encr = cptr->passwd; #endif /* CRYPT_LINK_PASSWORD */ +#ifdef CHALLENGERESPONSE +#ifndef CHALLENGERESPONSE_FALLBACK + if (!Responded(cptr)) { + sendto_realops("Access denied (plaintext password) %s", inpath); + return exit_client(cptr, cptr, cptr, "Non CR server"); + } +#endif +#endif if (*n_conf->passwd && 0 != strcmp(n_conf->passwd, encr)) { ServerStats->is_ref++; @@ -596,8 +604,21 @@ #endif if (IsUnknown(cptr)) { +#ifdef CHALLENGERESPONSE +#ifdef CHALLENGERESPONSE_FALLBACK + /* If we haven't sent a response by the time we get here, + the other end sent a valid PASS and not a CHALL/RESP + - einride. + */ + if (!Responded(cptr) && (c_conf->passwd[0])) { + log(L_NOTICE, "Fallback to PASS authentication for %s", host); + sendto_one(cptr,"PASS %s :TS", c_conf->passwd); + } +#endif +#else if (c_conf->passwd[0]) sendto_one(cptr,"PASS %s :TS", c_conf->passwd); +#endif /* ** Pass my info to the new server */