+2002-11-11 hikari <shadow@undernet.org>
+ * ircd/ircd.c: added call to irc_crypt_init() - someone hurry up and
+ modularise :P
+
+ * ircd/ircd_xopen.c: removed, superseded by new crypto system.
+
+ * ircd/ircd_crypt.c: wrote scary ircd_crypt() interface function,
+ wrote ircd_crypt_mech_register() function, various other bits
+ designed to create a near-pluggable crypto system for ircu. currently
+ this code also loads the various mechanisms i've written code for.
+
+ * ircd/ircd_crypt_smd5.c: imported the crypt_md5 function from
+ elsewhere, manipulated to suit ircu, returns a salted MD5 password.
+
+ * ircd/ircd_crypt_native.c: replaces the old ircd_xopen.c file,
+ generate a crypted password using the systems native crypt() function.
+
+ * ircd/ircd_crypt_plain.c: plain text crypt mechanism, should really
+ only be used for testing purposes.
+
+ * ircd/ircd_md5.c: main gubbins of the MD5 hashing code, lifted from
+ elsewhere, ircuified.
+
+ * ircd/umkpasswd.c: mkpasswd program for ircu.
+
+ * include/ircd_xopen.h: removed, superseded by new crypto system.
+
+ * include/ircd_crypt.h: external definitions for the new ircd_crypt()
+ function and definition of the ircd_crypt_mech structure for containing
+ crypto mechanism data.
+
+ * include/ircd_crypt_smd5.h: sundary definitions for the salted MD5
+ mechanism.
+
+ * include/ircd_crypt_native.h: sundary definitions for the native
+ crypt() mechanism.
+
+ * include/ircd_crypt_plain.h: sundary definitions for the plain text
+ mechanism.
+
+ * include/umkpasswd.h: fluff for umkpasswd.
+
2003-03-11 Landon Fuller (landonf) <landonf@sf.net>
* configure.in: allow ircu to build on OS X.
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, include/ircd_crypt.h
+ * Copyright (C) 2002 hikari
+ *
+ * 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$
+ */
+#ifndef INCLUDED_ircd_crypt_h
+#define INCLUDED_ircd_crypt_h
+
+/* forward planning for modularisation */
+struct crypt_mech_s {
+ char* mechname; /* name of the mechanism */
+ char* shortname; /* short name of the module */
+ char* description; /* description of the mechanism */
+
+ const char* (*crypt_function)(const char *, const char *);
+ /* pointer to the crypt function */
+
+ char* crypt_token; /* what identifies a password string
+ as belonging to this mechanism */
+
+ int crypt_token_size; /* how long is the token */
+};
+
+typedef struct crypt_mech_s crypt_mech_t;
+
+struct crypt_mechs_s;
+typedef struct crypt_mechs_s crypt_mechs_t;
+
+struct crypt_mechs_s {
+ crypt_mech_t* mech;
+ crypt_mechs_t* next;
+ crypt_mechs_t* prev;
+};
+
+/* access macros */
+#define MechName(x) x->mechname
+#define ShortName(x) x->shortname
+#define Description(x) x->description
+#define CryptFunc(x) x->crypt_function
+#define CryptTok(x) x->crypt_token
+#define CryptTokSize(x) x->crypt_token_size
+
+/* exported functions */
+extern void ircd_crypt_init(void);
+extern const char* ircd_crypt(const char* key, const char* salt);
+extern int ircd_crypt_register_mech(crypt_mech_t* mechanism);
+extern int ircd_crypt_unregister_mech(crypt_mech_t* mechanism);
+
+/* exported variables */
+extern crypt_mechs_t* crypt_mechs_root;
+
+#endif /* INCLUDED_ircd_crypt_h */
+
--- /dev/null
+/*
+ * $Id$
+ */
+#ifndef INCLUDED_ircd_crypt_native_h
+#define INCLUDED_ircd_crypt_native_h
+
+extern const char* ircd_crypt_native(const char* key, const char* salt);
+extern void ircd_register_crypt_native(void);
+
+#endif /* INCLUDED_ircd_crypt_native_h */
+
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, include/ircd_crypt_plain.h
+ * Copyright (C) 2002 hikari
+ *
+ * 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$
+ */
+#ifndef INCLUDED_ircd_crypt_plain_h
+#define INCLUDED_ircd_crypt_plain_h
+
+extern const char* ircd_crypt_plain(const char* key, const char* salt);
+extern void ircd_register_crypt_plain(void);
+
+
+#endif /* INCLUDED_ircd_crypt_plain_h */
+
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, include/ircd_crypt_smd5.h
+ * Copyright (C) 2002 hikari
+ *
+ * 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$
+ */
+#ifndef INCLUDED_ircd_crypt_smd5_h
+#define INCLUDED_ircd_crypt_smd5_h
+
+extern void ircd_register_crypt_smd5(void);
+
+#endif /* INCLUDED_ircd_crypt_smd5_h */
+
FEAT_HIS_LINKS,
FEAT_HIS_TRACE,
FEAT_HIS_STATS_l,
+ FEAT_HIS_STATS_L,
FEAT_HIS_STATS_c,
FEAT_HIS_STATS_g,
FEAT_HIS_STATS_h,
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, include/ircd_md5.h
+ *
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * ircuified 2002 by hikari
+ *
+ * $Id$
+*/
+#ifndef ircd_md5_h
+#define ircd_md5_h
+
+#define MD5Name(x) Good##x
+
+typedef unsigned int uint32;
+
+struct MD5Context {
+ uint32 buf[4];
+ uint32 bits[2];
+ unsigned char in[64];
+};
+
+void GoodMD5Init(struct MD5Context *);
+void GoodMD5Update(struct MD5Context *, unsigned const char *, unsigned);
+void GoodMD5Final(unsigned char digest[16], struct MD5Context *);
+void GoodMD5Transform(uint32 buf[4], uint32 const in[16]);
+void BrokenMD5Init(struct MD5Context *);
+void BrokenMD5Update(struct MD5Context *, unsigned const char *, unsigned);
+void BrokenMD5Final(unsigned char digest[16], struct MD5Context *);
+void BrokenMD5Transform(uint32 buf[4], uint32 const in[16]);
+
+char *Goodcrypt_md5(const char *pw, const char *salt);
+char *Brokencrypt_md5(const char *pw, const char *salt);
+
+/*
+ * This is needed to make RSAREF happy on some MS-DOS compilers.
+ */
+
+typedef struct MD5Context MD5_CTX;
+
+#endif /* ircd_md5_h */
/* RPL_STATSIAUTH 239 IRCnet extension */
/* RPL_STATSVLINE 240 IRCnet extension */
/* RPL_STATSXLINE 240 austnet */
-#define RPL_STATSLLINE 241
+#define RPL_STATSLLINE 241 /* Undernet dynamicly loaded modules */
#define RPL_STATSUPTIME 242
#define RPL_STATSOLINE 243
#define RPL_STATSHLINE 244
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, include/umkpasswd.h
+ * Copyright (C) 2002 hikari
+ *
+ * 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$
+ */
+#ifndef INCLUDED_umkpasswd_h
+#define INCLUDED_umkpasswd_h
+
+struct umkpasswd_conf_s {
+ int debuglevel; /* you really need me to comment this? */
+ char* mech; /* mechanism we want to use */
+ char* conf; /* conf file, otherwise DPATH/CPATH */
+ int flags; /* to add or not to add (or maybe to update) */
+ char* user; /* username */
+ int operclass; /* connection class to use */
+};
+
+typedef struct umkpasswd_conf_s umkpasswd_conf_t;
+
+/* values for flags */
+#define ACT_ADDOPER 0x1
+#define ACT_UPDOPER 0x2
+#define ACT_ADDSERV 0x4 /* not implemented yet */
+#define ACT_UPDSRRV 0x8 /* not implemented yet */
+
+const char* default_salts = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
+
+#endif /* INCLUDED_umkpasswd_h */
+
res_adns.c \
res_libresolv.c
+CRYPTO_SRC = \
+ ircd_md5.c \
+ ircd_crypt_plain.c \
+ ircd_crypt_smd5.c \
+ ircd_crypt_native.c
+
+UMKPASSWD_SRC = ${CRYPTO_SRC} \
+ ircd_alloc.c \
+ ircd_string.c \
+ umkpasswd.c
+
IRCD_SRC = \
IPcheck.c \
channel.c \
hash.c \
ircd.c \
ircd_alloc.c \
+ ircd_crypt.c \
ircd_events.c \
ircd_features.c \
ircd_log.c \
ircd_signal.c \
ircd_snprintf.c \
ircd_string.c \
- ircd_xopen.c \
jupe.c \
lex.yy.c \
list.c \
whowas.c \
y.tab.c
-
-SRC = ${IRCD_SRC} ${OSDEP_C} ${ENGINE_C} ${RES_C}
+SRC = ${IRCD_SRC} ${OSDEP_C} ${ENGINE_C} ${RES_C} ${CRYPTO_SRC}
OBJS = ${SRC:%.c=%.o}
-DEP_SRC = ${IRCD_SRC} ${OSDEP_SRC} ${ENGINE_SRC}
+UMKPASSWD_OBJS = ${UMKPASSWD_SRC:%.c=%.o}
+
+DEP_SRC = ${IRCD_SRC} ${OSDEP_SRC} ${ENGINE_SRC} ${CRYPTO_SRC}
all:
( cd ..; make -f Makefile )
# must be a better solution...perhaps sum all of the .c files and include
# only that one sum?
#
-version.c: version.c.SH s_serv.c s_user.c channel.c s_bsd.c s_misc.c ircd.c \
- ../include/version.h ../include/patchlevel.h ../include/patchlist.h
- ${SHELL} ${srcdir}/version.c.SH ${srcdir}
+version.c: version.c.SH umkpasswd
+ ${SHELL} ${srcdir}/version.c.SH ${top_srcdir}
../include/patchlist.h:
(cd ${top_srcdir} ; ./ircd-patch update)
y.tab.c y.tab.h: ircd_parser.y
${YACC} -d ${srcdir}/ircd_parser.y
+umkpasswd: ${UMKPASSWD_OBJS}
+ ${CC} ${LDFLAGS} ${UMKPASSWD_OBJS} ${LIBS} -o $@
+
mkbindir:
@test -d ${BINDIR} || mkdir ${BINDIR}
${LN_S} ircd.`cat /tmp/ircd.tag` ${SYMLINK}; )
@${RM} /tmp/ircd.tag
# ${INSTALL} -s -m 700 -o ${IRCDOWN} -g ${IRCDGRP} chkconf ${BINDIR}
+ ${INSTALL} -s -m 700 -o ${IRCDOWN} -g ${IRCDGRP} umkpasswd ${BINDIR}
${INSTALL} -m 600 -o ${IRCDOWN} -g ${IRCDGRP} ${top_srcdir}/doc/example.conf ${DPATH}
# ( cd ${DPATH}; \
# ${TOUCH} ${MPATH}; \
@echo "Please remove the contents of ${DPATH} manually"
clean:
- ${RM} -f *.o *.bak ircd version.c chkconf ircd_osdep.c chattr.tab.c table_gen y.tab.* lex.yy.*
+ ${RM} -f *.o *.bak ircd version.c chkconf umkpasswd ircd_osdep.c chattr.tab.c table_gen y.tab.* lex.yy.*
distclean: clean
${RM} -f Makefile stamp-m
../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \
../include/s_misc.h ../include/s_stats.h ../include/send.h \
../include/sys.h ../include/uping.h ../include/userload.h \
- ../include/version.h ../include/whowas.h
+ ../include/version.h ../include/whowas.h ../include/ircd_crypt.h
ircd_alloc.o: ircd_alloc.c ../config.h ../include/ircd_alloc.h \
../include/ircd_string.h ../include/ircd_chattr.h ../include/s_debug.h \
../include/ircd_defs.h
ircd_string.o: ircd_string.c ../config.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/ircd_defs.h ../include/ircd_log.h \
chattr.tab.c
-ircd_xopen.o: ircd_xopen.c ../config.h ../include/ircd_xopen.h
+ircd_md5.o: ircd_md5.c ../config.h ../include/ircd_md5.h
+ircd_crypt.o: ircd_crypt.c ../config.h ../include/ircd_crypt.h \
+ ../include/ircd_alloc.h ../include/s_debug.h
+ircd_crypt_native.o: ircd_crypt_native.c ../config.h \
+ ../include/ircd_crypt_native.h ../include/ircd_crypt.h \
+ ../include/s_debug.h
+ircd_crypt_plain.o: ircd_crypt_plain.c ../config.h ../include/ircd_crypt.h \
+ ../include/ircd_crypt_plain.h ../include/s_debug.h
+ircd_crypt_smd5.o: ircd_crypt_smd5.c ../config.h ../include/ircd_crypt.h \
+ ../include/s_debug.h ../include/ircd_crypt_smd5.h
jupe.o: jupe.c ../config.h ../include/jupe.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \
../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \
../include/ircd_handler.h ../include/hash.h ../include/ircd.h \
../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \
../include/ircd_reply.h ../include/ircd_string.h \
- ../include/ircd_chattr.h ../include/ircd_xopen.h ../include/msg.h \
+ ../include/ircd_chattr.h ../include/ircd_crypt.h ../include/msg.h \
../include/numeric.h ../include/numnicks.h ../include/querycmds.h \
../include/s_conf.h ../include/s_debug.h ../include/s_user.h \
../include/s_misc.h ../include/send.h ../include/support.h
../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \
../include/ircd_reply.h ../include/ircd_string.h \
../include/ircd_chattr.h ../include/ircd_snprintf.h \
- ../include/ircd_xopen.h ../include/jupe.h ../include/list.h \
+ ../include/ircd_crypt.h ../include/jupe.h ../include/list.h \
../include/match.h ../include/msg.h ../include/numeric.h \
../include/numnicks.h ../include/parse.h ../include/querycmds.h \
../include/ircd_features.h ../include/s_bsd.h ../include/s_conf.h \
#include "ircd_reply.h"
#include "ircd_signal.h"
#include "ircd_string.h"
+#include "ircd_crypt.h"
#include "jupe.h"
#include "list.h"
#include "match.h"
init_resolver();
+ /* we need this for now, when we're modular this
+ should be removed -- hikari */
+ ircd_crypt_init();
+
motd_init();
if (!init_conf()) {
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, ircd/ircd_crypt.c
+ * Copyright (C) 2002 hikari
+ *
+ * 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$
+ */
+
+/*
+ * This is a new look crypto API for ircu, it can handle different
+ * password formats by the grace of the standard magic tokens at the
+ * begining of the password e.g. $1 for MD5, $2 for Blowfish, etc.
+ *
+ * Currently crypt routines are implemented for: the native crypt()
+ * function, Salted MD5 and a plain text mechanism which should only
+ * be used for testing. I intend to add Blowish, 3DES and possibly
+ * SHA1 support as well at some point, but I'll need to check the
+ * possible problems that'll cause with stupid crypto laws.
+ *
+ * It's also designed to be "ready" for the modularisation of ircu, so
+ * someone get round to doing it, because I'm not doing it ;)
+ *
+ * The plan for Stage B is to semi-modularise the authentication
+ * mechanism to allow authentication against some other sources than
+ * the conf file (whatever takes someones fancy, kerberos, ldap, sql, etc).
+ *
+ * -- blessed be, hikari.
+ */
+
+#include "config.h"
+#include "ircd_crypt.h"
+#include "ircd_alloc.h"
+#include "ircd_features.h"
+#include "ircd_string.h"
+#include "s_debug.h"
+
+/* while we're not modular, we need their init functions */
+#include "ircd_crypt_native.h"
+#include "ircd_crypt_plain.h"
+#include "ircd_crypt_smd5.h"
+
+#include <assert.h>
+#include <unistd.h>
+#include <string.h>
+
+/* evil global */
+crypt_mechs_t* crypt_mechs_root;
+
+/*
+ * add a crypt mechanism to the list
+*/
+int ircd_crypt_register_mech(crypt_mech_t* mechanism)
+{
+crypt_mechs_t* crypt_mech;
+
+ Debug((DEBUG_INFO, "ircd_crypt_register_mech: resistering mechanism: %s", mechanism->shortname));
+
+ /* try to allocate some memory for the new mechanism */
+ if ((crypt_mech = (crypt_mechs_t*)MyMalloc(sizeof(crypt_mechs_t))) == NULL)
+ {
+ /* aww poot, we couldn't get any memory, scream a little then back out */
+ Debug((DEBUG_MALLOC, "ircd_crypt_register_mech: could not allocate memory for %s", mechanism->shortname));
+ return -1;
+ }
+
+ /* ok, we have memory, initialise it */
+ memset(crypt_mech, 0, sizeof(crypt_mechs_t));
+
+ /* assign the data */
+ crypt_mech->mech = mechanism;
+ crypt_mech->next = crypt_mech->prev = NULL;
+
+ /* first of all, is there anything there already? */
+ if(crypt_mechs_root->next == NULL)
+ {
+ /* nope, just add ourself */
+ crypt_mechs_root->next = crypt_mechs_root->prev = crypt_mech;
+ } else {
+ /* nice and simple, put ourself at the end */
+ crypt_mech->prev = crypt_mechs_root->prev;
+ crypt_mech->next = NULL;
+ crypt_mechs_root->prev = crypt_mech->prev->next = crypt_mech;
+ }
+
+ /* we're done */
+ Debug((DEBUG_INFO, "ircd_crypt_register_mech: resistered mechanism: %s, crypt_function is at 0x%X.", crypt_mech->mech->shortname, &crypt_mech->mech->crypt_function));
+ Debug((DEBUG_INFO, "ircd_crypt_register_mech: %s: %s", crypt_mech->mech->shortname, crypt_mech->mech->description));
+ return 0;
+}
+
+/*
+ * remove a crypt mechanism from the list
+*/
+int ircd_crypt_unregister_mech(crypt_mech_t* mechanism)
+{
+
+return 0;
+}
+
+/*
+ * this is now a wrapper function which attempts to establish the password
+ * format and funnel it off to the correct handler function.
+*/
+const char* ircd_crypt(const char* key, const char* salt)
+{
+char *hashed_pass = NULL;
+const char *temp_hashed_pass, *mysalt;
+crypt_mechs_t* crypt_mech;
+
+ assert(NULL != key);
+ assert(NULL != salt);
+
+ Debug((DEBUG_DEBUG, "ircd_crypt: key is %s", key));
+ Debug((DEBUG_DEBUG, "ircd_crypt: salt is %s", salt));
+
+ crypt_mech = crypt_mechs_root->next;
+
+ /* by examining the first n characters of a password string we
+ * can discover what kind of password it is. hopefully. */
+ for (;crypt_mech;)
+ {
+ if (strlen(salt) < crypt_mech->mech->crypt_token_size)
+ {
+ /* try the next mechanism instead */
+ Debug((DEBUG_DEBUG, "ircd_crypt: salt is too short, will try next mech at 0x%X", crypt_mech->next));
+ crypt_mech = crypt_mech->next;
+ continue;
+ }
+
+ Debug((DEBUG_DEBUG, "ircd_crypt: comparing %s with %s",
+ salt, crypt_mech->mech->crypt_token));
+
+ if(0 == ircd_strncmp(crypt_mech->mech->crypt_token, salt, crypt_mech->mech->crypt_token_size))
+ {
+ Debug((DEBUG_DEBUG, "ircd_crypt: type is %s",
+ crypt_mech->mech->shortname));
+
+ /* before we send this all off to the crypt_function, we need to remove
+ the tag from it */
+
+ /* make sure we won't end up with a password comprised entirely of
+ a single \0 */
+ if(strlen(salt) < crypt_mech->mech->crypt_token_size + 1)
+ return NULL;
+
+ mysalt = salt + crypt_mech->mech->crypt_token_size;
+
+ if(NULL == (temp_hashed_pass = crypt_mech->mech->crypt_function(key, mysalt)))
+ return NULL;
+
+ Debug((DEBUG_DEBUG, "ircd_crypt: untagged pass is %s", temp_hashed_pass));
+
+ /* ok, now we need to prefix the password we just got back
+ with the right tag */
+ if(NULL == (hashed_pass = (char *)MyMalloc(sizeof(char)*strlen(temp_hashed_pass) + crypt_mech->mech->crypt_token_size + 1)))
+ {
+ Debug((DEBUG_MALLOC, "ircd_crypt: unable to allocate memory for temp_hashed_pass"));
+ return NULL;
+ }
+ memset(hashed_pass, 0, sizeof(char)*strlen(temp_hashed_pass)
+ +crypt_mech->mech->crypt_token_size + 1);
+ ircd_strncpy(hashed_pass, crypt_mech->mech->crypt_token,
+ crypt_mech->mech->crypt_token_size);
+ ircd_strncpy(hashed_pass + crypt_mech->mech->crypt_token_size, temp_hashed_pass, strlen(temp_hashed_pass));
+ Debug((DEBUG_DEBUG, "ircd_crypt: tagged pass is %s", hashed_pass));
+ } else {
+ Debug((DEBUG_DEBUG, "ircd_crypt: will try next mechansim at 0x%X",
+ crypt_mech->next));
+ crypt_mech = crypt_mech->next;
+ continue;
+ }
+ return hashed_pass;
+ }
+
+ /* try to use native crypt for an old-style (untagged) password */
+ if (strlen(salt) > 2)
+ {
+ temp_hashed_pass = (char*)ircd_crypt_native(key, salt);
+ if (!ircd_strcmp(temp_hashed_pass, salt))
+ return strdup(temp_hashed_pass);
+ }
+
+ return NULL;
+}
+
+/*
+ * some basic init, when we're modular this will be our entry
+ * function.
+*/
+void ircd_crypt_init(void)
+{
+
+ if((crypt_mechs_root = MyMalloc(sizeof(crypt_mechs_t))) == NULL)
+ {
+ /* awooga - can't allocate memory for the root structure */
+ Debug((DEBUG_MALLOC, "init_crypt: Could not allocate memory for crypt_mechs_root"));
+ return;
+ }
+
+ crypt_mechs_root->mech = NULL;
+ crypt_mechs_root->next = crypt_mechs_root->prev = NULL;
+
+/* temporary kludge until we're modular. manualy call the
+ register funtions for crypt mechanisms */
+ ircd_register_crypt_smd5();
+ ircd_register_crypt_plain();
+ ircd_register_crypt_native();
+
+return;
+}
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, ircd/ircd_xopen.c
+ * Copyright (C) 1990, 1991 Armin Gruner
+ *
+ * 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$
+ */
+#include "config.h"
+#include "ircd_crypt.h"
+#include "ircd_crypt_native.h"
+#include "s_debug.h"
+#include "ircd_alloc.h"
+
+#define _XOPEN_SOURCE
+#define _XOPEN_VERSION 4
+
+#include <assert.h>
+#include <unistd.h>
+
+/* well this bit is (kinda) intact :) -- hikari */
+const char* ircd_crypt_native(const char* key, const char* salt)
+{
+ assert(NULL != key);
+ assert(NULL != salt);
+
+ Debug((DEBUG_DEBUG, "ircd_crypt_native: key is %s", key));
+ Debug((DEBUG_DEBUG, "ircd_crypt_native: salt is %s", salt));
+
+ return (const char*)crypt(key, salt);
+}
+
+/* register ourself with the list of crypt mechanisms -- hikari */
+void ircd_register_crypt_native(void)
+{
+crypt_mech_t* crypt_mech;
+
+ if ((crypt_mech = (crypt_mech_t*)MyMalloc(sizeof(crypt_mech_t))) == NULL)
+ {
+ Debug((DEBUG_MALLOC, "Could not allocate space for crypt_native"));
+ return;
+ }
+
+ crypt_mech->mechname = "native";
+ crypt_mech->shortname = "crypt_native";
+ crypt_mech->description = "System native crypt() function mechanism.";
+ crypt_mech->crypt_function = &ircd_crypt_native;
+ crypt_mech->crypt_token = "$CRYPT$";
+ crypt_mech->crypt_token_size = 7;
+
+ ircd_crypt_register_mech(crypt_mech);
+
+return;
+}
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, ircd/ircd_crypt_plain.c
+ * Copyright (C) 2002 hikari
+ *
+ * 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$
+ */
+#include "config.h"
+#include "ircd_crypt.h"
+#include "ircd_crypt_plain.h"
+#include "s_debug.h"
+#include "ircd_alloc.h"
+
+#include <assert.h>
+#include <unistd.h>
+
+/* yes I know it's an oxymoron, but still, it's handy for testing */
+const char* ircd_crypt_plain(const char* key, const char* salt)
+{
+ assert(NULL != salt);
+ assert(NULL != key);
+
+ Debug((DEBUG_DEBUG, "ircd_crypt_plain: key is %s", key));
+ Debug((DEBUG_DEBUG, "ircd_crypt_plain: salt is %s", salt));
+
+ /* yes, that's it. we just send key back out again,
+ pointless I know */
+ return key;
+}
+
+/* register ourself with the list of crypt mechanisms -- hikari */
+void ircd_register_crypt_plain(void)
+{
+crypt_mech_t* crypt_mech;
+
+ if ((crypt_mech = (crypt_mech_t*)MyMalloc(sizeof(crypt_mech_t))) == NULL)
+ {
+ Debug((DEBUG_MALLOC, "Could not allocate space for crypt_plain"));
+ return;
+ }
+
+ crypt_mech->mechname = "plain";
+ crypt_mech->shortname = "crypt_plain";
+ crypt_mech->description = "Plain text \"crypt\" mechanism.";
+ crypt_mech->crypt_function = &ircd_crypt_plain;
+ crypt_mech->crypt_token = "$PLAIN$";
+ crypt_mech->crypt_token_size = 7;
+
+ ircd_crypt_register_mech(crypt_mech);
+
+return;
+}
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, ircd/ircd_crypt_smd5.c
+ * Copyright (C) 2002 hikari
+ *
+ * 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$
+ */
+#include "config.h"
+#include "ircd_crypt.h"
+#include "ircd_crypt_smd5.h"
+#include "ircd_md5.h"
+#include "s_debug.h"
+#include "ircd_alloc.h"
+
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * ircd_crypt_smd5 is largely taken from md5_crypt.c from the Linux PAM
+ * source code. it's been modified to fit in with ircu and some of the
+ * undeeded code has been removed. the source file md5_crypt.c has the
+ * following licence, so if any of our opers or admins are in Denmark
+ * they better go buy them a drink ;) -- hikari
+ *
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ */
+
+static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static void to64(char *s, unsigned long v, int n)
+{
+ while (--n >= 0) {
+ *s++ = itoa64[v & 0x3f];
+ v >>= 6;
+ }
+}
+
+const char* ircd_crypt_smd5(const char* key, const char* salt)
+{
+const char *magic = "$1$";
+char *passwd, *p;
+const char *sp, *ep;
+unsigned char final[16];
+int sl, pl, i, j;
+MD5_CTX ctx, ctx1;
+unsigned long l;
+
+ assert(NULL != key);
+ assert(NULL != salt);
+
+ Debug((DEBUG_DEBUG, "ircd_crypt_smd5: key = %s", key));
+ Debug((DEBUG_DEBUG, "ircd_crypt_smd5: salt = %s", salt));
+
+ /* Refine the Salt first */
+ ep = sp = salt;
+
+ if(NULL == (passwd = (char *)MyMalloc(120)))
+ return NULL;
+
+ memset(passwd, 0, 120);
+
+ for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++)
+ continue;
+
+ /* get the length of the true salt */
+ sl = ep - sp;
+
+ MD5Name(MD5Init)(&ctx);
+
+ /* The password first, since that is what is most unknown */
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)key,strlen(key));
+
+ /* Then our magic string */
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)magic,strlen(magic));
+
+ /* Then the raw salt */
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)sp,sl);
+
+ /* Then just as many characters of the MD5(key,salt,key) */
+ MD5Name(MD5Init)(&ctx1);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)key,strlen(key));
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)key,strlen(key));
+ MD5Name(MD5Final)(final,&ctx1);
+ for (pl = strlen(key); pl > 0; pl -= 16)
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)final,pl>16 ? 16 : pl);
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final, 0, sizeof final);
+
+ /* Then something really weird... */
+ for (j = 0, i = strlen(key); i; i >>= 1)
+ if (i & 1)
+ MD5Name(MD5Update)(&ctx, (unsigned const char *)final+j, 1);
+ else
+ MD5Name(MD5Update)(&ctx, (unsigned const char *)key+j, 1);
+
+ /* Now make the output string */
+// strcpy(passwd, magic);
+// strncat(passwd, sp, sl);
+ strncpy(passwd, sp, sl);
+ strcat(passwd, "$");
+
+ MD5Name(MD5Final)(final,&ctx);
+
+ /*
+ * and now, just to make sure things don't run too fast
+ * On a 60 Mhz Pentium this takes 34 msec, so you would
+ * need 30 seconds to build a 1000 entry dictionary...
+ */
+ for (i = 0; i < 1000; i++) {
+ MD5Name(MD5Init)(&ctx1);
+
+ if (i & 1)
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)key,strlen(key));
+ else
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16);
+
+ if (i % 3)
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl);
+
+ if (i % 7)
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)key,strlen(key));
+
+ if (i & 1)
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16);
+ else
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)key,strlen(key));
+
+ MD5Name(MD5Final)(final,&ctx1);
+ }
+
+ p = passwd + strlen(passwd);
+
+ Debug((DEBUG_DEBUG, "passwd = %s", passwd));
+
+ l = (final[0] << 16) | (final[6] << 8) | final[12];
+ to64(p, l, 4);
+ p += 4;
+ l = (final[1] << 16) | (final[7] << 8) | final[13];
+ to64(p, l, 4);
+ p += 4;
+ l = (final[2] << 16) | (final[8] << 8) | final[14];
+ to64(p, l, 4);
+ p += 4;
+ l = (final[3] << 16) | (final[9] << 8) | final[15];
+ to64(p, l, 4);
+ p += 4;
+ l = (final[4] << 16) | (final[10] << 8) | final[5];
+ to64(p, l, 4);
+ p += 4;
+ l = final[11];
+ to64(p, l, 2);
+ p += 2;
+ *p = '\0';
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final, 0, sizeof final);
+
+return passwd;
+}
+
+/* end borrowed code */
+
+/* register ourself with the list of crypt mechanisms */
+void ircd_register_crypt_smd5(void)
+{
+crypt_mech_t* crypt_mech;
+
+ if ((crypt_mech = (crypt_mech_t*)MyMalloc(sizeof(crypt_mech_t))) == NULL)
+ {
+ Debug((DEBUG_MALLOC, "Could not allocate space for crypt_smd5"));
+ return;
+ }
+
+ crypt_mech->mechname = "smd5";
+ crypt_mech->shortname = "crypt_smd5";
+ crypt_mech->description = "Salted MD5 password hash mechanism.";
+ crypt_mech->crypt_function = &ircd_crypt_smd5;
+ crypt_mech->crypt_token = "$SMD5$";
+ crypt_mech->crypt_token_size = 6 ;
+
+ ircd_crypt_register_mech(crypt_mech);
+
+return;
+}
F_B(HIS_LINKS, 0, 1, 0),
F_B(HIS_TRACE, 0, 1, 0),
F_B(HIS_STATS_l, 0, 1, 0),
+ F_B(HIS_STATS_L, 0, 1, 0),
F_B(HIS_STATS_c, 0, 1, 0),
F_B(HIS_STATS_g, 0, 1, 0),
F_B(HIS_STATS_h, 0, 1, 0),
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, ircd/ircd_md5.h
+ *
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ *
+ * ircuified 2002 by hikari
+ *
+ * $Id$
+*/
+
+#include <string.h>
+#include "ircd_md5.h"
+
+#ifndef HIGHFIRST
+#define byteReverse(buf, len) /* Nothing */
+#else
+static void byteReverse(unsigned char *buf, unsigned longs);
+
+#ifndef ASM_MD5
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+static void byteReverse(unsigned char *buf, unsigned longs)
+{
+ uint32 t;
+ do {
+ t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+ ((unsigned) buf[1] << 8 | buf[0]);
+ *(uint32 *) buf = t;
+ buf += 4;
+ } while (--longs);
+}
+#endif
+#endif
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Name(MD5Init)(struct MD5Context *ctx)
+{
+ ctx->buf[0] = 0x67452301U;
+ ctx->buf[1] = 0xefcdab89U;
+ ctx->buf[2] = 0x98badcfeU;
+ ctx->buf[3] = 0x10325476U;
+
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
+{
+ uint32 t;
+
+ /* Update bitcount */
+
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
+ ctx->bits[1]++; /* Carry from low to high */
+ ctx->bits[1] += len >> 29;
+
+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
+
+ /* Handle any leading odd-sized chunks */
+
+ if (t) {
+ unsigned char *p = (unsigned char *) ctx->in + t;
+
+ t = 64 - t;
+ if (len < t) {
+ memcpy(p, buf, len);
+ return;
+ }
+ memcpy(p, buf, t);
+ byteReverse(ctx->in, 16);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
+ buf += t;
+ len -= t;
+ }
+ /* Process data in 64-byte chunks */
+
+ while (len >= 64) {
+ memcpy(ctx->in, buf, 64);
+ byteReverse(ctx->in, 16);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+
+ memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx)
+{
+ unsigned count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset(p, 0, count);
+ byteReverse(ctx->in, 16);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
+
+ /* Now fill the next block with 56 bytes */
+ memset(ctx->in, 0, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ memset(p, 0, count - 8);
+ }
+ byteReverse(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ((uint32 *) ctx->in)[14] = ctx->bits[0];
+ ((uint32 *) ctx->in)[15] = ctx->bits[1];
+
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
+ byteReverse((unsigned char *) ctx->buf, 4);
+ memcpy(digest, ctx->buf, 16);
+ memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
+}
+
+#ifndef ASM_MD5
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void MD5Name(MD5Transform)(uint32 buf[4], uint32 const in[16])
+{
+ register uint32 a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478U, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756U, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070dbU, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceeeU, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0fafU, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62aU, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613U, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501U, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8U, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7afU, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1U, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7beU, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122U, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193U, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438eU, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821U, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562U, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340U, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51U, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aaU, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105dU, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453U, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681U, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8U, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6U, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6U, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87U, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14edU, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905U, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8U, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9U, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8aU, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942U, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681U, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122U, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380cU, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44U, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9U, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60U, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70U, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6U, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127faU, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085U, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05U, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039U, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5U, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8U, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665U, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244U, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97U, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7U, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039U, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3U, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92U, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47dU, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1U, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4fU, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0U, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314U, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1U, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82U, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235U, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bbU, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391U, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+#endif
send_reply(sptr, RPL_INFO, *text);
text++;
}
- if (IsOper(sptr))
+ if (IsOper(sptr) && (NULL != parv[1]))
{
while (*text)
send_reply(sptr, RPL_INFO, *text++);
#include "ircd_log.h"
#include "ircd_reply.h"
#include "ircd_string.h"
-#include "ircd_xopen.h"
+#include "ircd_crypt.h"
#include "msg.h"
#include "numeric.h"
#include "numnicks.h"
if (!to_match || !passwd)
return 0;
- if (feature_bool(FEAT_CRYPT_OPER_PASSWORD))
- to_match = ircd_crypt(to_match, passwd);
+ /* we no longer do a CRYPT_OPER_PASSWORD check because a clear
+ text passwords just handled by a fallback mechanism called
+ crypt_clear if it's enabled -- hikari */
+ to_match = ircd_crypt(to_match, passwd);
- return (0 == strcmp(to_match, passwd));
+ if (to_match == NULL)
+ return 0;
+ else
+ return (0 == strcmp(to_match, passwd));
}
/*
#include "ircd_reply.h"
#include "ircd_string.h"
#include "ircd_snprintf.h"
-#include "ircd_xopen.h"
+#include "ircd_crypt.h"
#include "jupe.h"
#include "list.h"
#include "match.h"
#include "ircd_chattr.h"
#include "ircd_events.h"
#include "ircd_features.h"
+#include "ircd_crypt.h"
#include "ircd_log.h"
#include "ircd_reply.h"
#include "ircd_string.h"
}
}
+/* hopefuly this will be where we'll spit out info about loaded modules */
+static void
+stats_modules(struct Client* to, struct StatDesc* sd, int stat, char* param)
+{
+crypt_mechs_t* mechs;
+
+ send_reply(to, SND_EXPLICIT | RPL_STATSLLINE,
+ "Module Description Entry Point");
+
+ /* atm the only "modules" we have are the crypto mechanisms,
+ eventualy they'll be part of a global dl module list, for now
+ i'll just output data about them -- hikari */
+
+ if(crypt_mechs_root == NULL)
+ return;
+
+ mechs = crypt_mechs_root->next;
+
+ for(;;)
+ {
+ if(mechs == NULL)
+ return;
+
+ send_reply(to, SND_EXPLICIT | RPL_STATSLLINE,
+ "%s %s 0x%X",
+ mechs->mech->shortname, mechs->mech->description,
+ mechs->mech->crypt_function);
+
+ mechs = mechs->next;
+ }
+
+}
+
static void
stats_commands(struct Client* to, struct StatDesc* sd, int stat, char* param)
{
{ 'k', (STAT_FLAG_OPERFEAT | STAT_FLAG_VARPARAM), FEAT_HIS_STATS_k,
stats_klines, 0,
"Local bans (K-Lines)." },
- { 'l', (STAT_FLAG_OPERFEAT | STAT_FLAG_VARPARAM), FEAT_HIS_STATS_l,
+ { 'l', (STAT_FLAG_OPERFEAT | STAT_FLAG_VARPARAM | STAT_FLAG_CASESENS),
+ FEAT_HIS_STATS_l,
stats_links, 0,
"Current connections information." },
+ { 'L', (STAT_FLAG_OPERFEAT | STAT_FLAG_VARPARAM | STAT_FLAG_CASESENS),
+ FEAT_HIS_STATS_L,
+ stats_modules, 0,
+ "Dynamicly loaded modules." },
#if 0
{ 'M', (STAT_FLAG_OPERFEAT | STAT_FLAG_CASESENS), FEAT_HIS_STATS_M,
stats_memtotal, 0,
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, ircd/umkpasswd.c
+ * Copyright (C) 2002 hikari
+ *
+ * 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$
+*/
+#include "config.h"
+#include <unistd.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <assert.h>
+#include <libgen.h>
+
+/* ircu headers */
+#include "ircd_alloc.h"
+#include "ircd_string.h"
+#include "umkpasswd.h"
+#include "s_debug.h"
+#include "ircd_md5.h"
+
+/* crypto mech headers */
+#include "ircd_crypt.h"
+#include "ircd_crypt_smd5.h"
+#include "ircd_crypt_native.h"
+#include "ircd_crypt_plain.h"
+
+/* bleah, evil globals */
+umkpasswd_conf_t* umkpasswd_conf;
+crypt_mechs_t* crypt_mechs_root;
+
+void copyright(void)
+{
+ fprintf(stderr, "umkpasswd - Copyright (c) 2002 hikari\n");
+return;
+}
+
+void show_help(void)
+{
+#ifdef DEBUGMODE
+ char *debughelp = "[-d <level>] ";
+#else
+ char *debughelp = "";
+#endif
+
+ copyright();
+ /*fprintf(stderr, "umkpasswd [-l] [[[-a]||[-u]] <username>] [-y <class>] %s[-c <file>] -m <mech> [password]\n\n", debughelp);*/
+ fprintf(stderr, "umkpasswd [-l] %s-m <mech> [password]\n\n", debughelp);
+ fprintf(stderr, " -l List mechanisms available.\n");
+#if 0
+ fprintf(stderr, " -a <user> Add user to conf file.\n");
+ fprintf(stderr, " -u <user> Update user's password field.\n");
+ fprintf(stderr, " -y <class> Class to place oper in.\n");
+#endif
+ fprintf(stderr, " -m <mech> Mechanism to use [MANDATORY].\n");
+#ifdef DEBUGMODE
+ fprintf(stderr, " -d <level> Debug level to run at.\n");
+#endif
+/*
+ fprintf(stderr, " -c <file> Conf file to use, default is DPATH/CPATH.\n\n");
+*/
+return;
+}
+
+/* our implementation of debug() */
+void debug(int level, const char *form, ...)
+{
+va_list vl;
+int err = errno;
+
+ if (level <= (umkpasswd_conf->debuglevel))
+ {
+ va_start(vl, form);
+ vfprintf(stderr, form, vl);
+ fprintf(stderr, "\n");
+ va_end(vl);
+ }
+ errno = err;
+}
+
+/* quick and dirty salt generator */
+char *make_salt(const char *salts)
+{
+char *tmp = NULL;
+long int n = 0;
+
+ /* try and get around them running this time after time in quick sucession */
+ sleep(1);
+ srandom((unsigned int)time(NULL));
+
+ if((tmp = calloc(3, sizeof(char))) != NULL)
+ {
+ /* can't optimize this much more than just doing it twice */
+ n = ((float)(strlen(salts))*random()/(RAND_MAX+1.0));
+ memcpy(tmp, (salts+n), 1);
+ sleep(2);
+ n = ((float)(strlen(salts))*random()/(RAND_MAX+1.0));
+ memcpy((tmp+1), (salts+n), 1);
+
+ Debug((DEBUG_DEBUG, "salts = %s", salts));
+ Debug((DEBUG_DEBUG, "strlen(salts) = %d", strlen(salts)));
+ }
+
+return tmp;
+}
+
+/* our implemenation of ircd_crypt_register_mech() */
+int ircd_crypt_register_mech(crypt_mech_t* mechanism)
+{
+crypt_mechs_t* crypt_mech;
+
+ Debug((DEBUG_INFO, "ircd_crypt_register_mech: resistering mechanism: %s", mechanism->shortname));
+
+ /* try to allocate some memory for the new mechanism */
+ if ((crypt_mech = (crypt_mechs_t*)MyMalloc(sizeof(crypt_mechs_t))) == NULL)
+ {
+ /* aww poot, we couldn't get any memory, scream a little then back out */
+ Debug((DEBUG_MALLOC, "ircd_crypt_register_mech: could not allocate memory for %s", mechanism->shortname));
+ return -1;
+ }
+
+ /* ok, we have memory, initialise it */
+ memset(crypt_mech, 0, sizeof(crypt_mechs_t));
+
+ /* assign the data */
+ crypt_mech->mech = mechanism;
+ crypt_mech->next = crypt_mech->prev = NULL;
+
+ /* first of all, is there anything there already? */
+ if(crypt_mechs_root->next == NULL)
+ {
+ /* nope, just add ourself */
+ crypt_mechs_root->next = crypt_mechs_root->prev = crypt_mech;
+ } else {
+ /* nice and simple, put ourself at the end */
+ crypt_mech->prev = crypt_mechs_root->prev;
+ crypt_mech->next = NULL;
+ crypt_mechs_root->prev = crypt_mech->prev->next = crypt_mech;
+ }
+
+ /* we're done */
+ Debug((DEBUG_INFO, "ircd_crypt_register_mech: resistered mechanism: %s, crypt_function is at 0x%X.", crypt_mech->mech->shortname, &crypt_mech->mech->crypt_function));
+ Debug((DEBUG_INFO, "ircd_crypt_register_mech: %s: %s", crypt_mech->mech->shortname, crypt_mech->mech->description));
+
+return 0;
+}
+
+void sum(char* tmp)
+{
+FILE* file;
+MD5_CTX context;
+int len;
+unsigned char buffer[1024], digest[16];
+
+ if (NULL == (file = fopen(tmp, "r")))
+ exit(0);
+ MD5Name(MD5Init)(&context);
+ while (len = fread (buffer, 1, 1024, file))
+ MD5Name(MD5Update)(&context, buffer, len);
+ MD5Name(MD5Final)(digest, &context);
+ fclose(file);
+
+ printf("%s: ", basename(tmp));
+ for (len = 0; len < 16; len++)
+ printf ("%02x", digest[len]);
+ printf("\n");
+ exit(0);
+}
+
+/* dump the loaded mechs list */
+void show_mechs(void)
+{
+crypt_mechs_t* mechs;
+
+ copyright();
+ printf("\nAvailable mechanisms:\n");
+
+ if(crypt_mechs_root == NULL)
+ return;
+
+ mechs = crypt_mechs_root->next;
+
+ for(;;)
+ {
+ if(mechs == NULL)
+ return;
+
+ printf(" %s\t\t%s\n", mechs->mech->mechname, mechs->mech->description);
+
+ mechs = mechs->next;
+ }
+}
+
+/* load in the mech "modules" */
+void load_mechs(void)
+{
+ /* we need these loaded by hand for now */
+
+ ircd_register_crypt_native();
+ ircd_register_crypt_smd5();
+ ircd_register_crypt_plain(); /* yes I know it's slightly pointless */
+
+return;
+}
+
+crypt_mechs_t* hunt_mech(const char* mechname)
+{
+crypt_mechs_t* mech;
+
+ assert(NULL != mechname);
+
+ if(crypt_mechs_root == NULL)
+ return NULL;
+
+ mech = crypt_mechs_root->next;
+
+ for(;;)
+ {
+ if(mech == NULL)
+ return NULL;
+
+ if(0 == (ircd_strcmp(mech->mech->mechname, mechname)))
+ return mech;
+
+ mech = mech->next;
+ }
+}
+
+char* crypt_pass(const char* pw, const char* mech)
+{
+crypt_mechs_t* crypt_mech;
+char* salt, *untagged, *tagged;
+
+ assert(NULL != pw);
+ assert(NULL != mech);
+
+ Debug((DEBUG_DEBUG, "pw = %s\n", pw));
+ Debug((DEBUG_DEBUG, "mech = %s\n", mech));
+
+ if (NULL == (crypt_mech = hunt_mech(mech)))
+ {
+ printf("Unable to find mechanism %s\n", mech);
+ return NULL;
+ }
+
+ salt = make_salt(default_salts);
+
+ untagged = (char *)CryptFunc(crypt_mech->mech)(pw, salt);
+ tagged = (char *)MyMalloc(strlen(salt)+CryptTokSize(crypt_mech->mech)+1);
+ memset(tagged, 0, strlen(untagged)+CryptTokSize(crypt_mech->mech)+1);
+ strncpy(tagged, CryptTok(crypt_mech->mech), CryptTokSize(crypt_mech->mech));
+ strncpy(tagged+CryptTokSize(crypt_mech->mech), untagged, strlen(untagged));
+
+return tagged;
+}
+
+char* parse_arguments(int argc, char **argv)
+{
+int len = 0, c = 0;
+const char* options = "a:d:lm:u:y:5:";
+
+ umkpasswd_conf = (umkpasswd_conf_t*)MyMalloc(sizeof(umkpasswd_conf_t));
+
+ umkpasswd_conf->flags = 0;
+ umkpasswd_conf->debuglevel = 0;
+ umkpasswd_conf->operclass = 0;
+ umkpasswd_conf->user = NULL;
+ umkpasswd_conf->mech = NULL;
+
+
+ len = strlen(DPATH) + strlen(CPATH) + 2;
+ umkpasswd_conf->conf = (char *)MyMalloc(len*sizeof(char));
+ memset(umkpasswd_conf->conf, 0, len*sizeof(char));
+ ircd_strncpy(umkpasswd_conf->conf, DPATH, strlen(DPATH));
+ *((umkpasswd_conf->conf) + strlen(DPATH)) = '/';
+ ircd_strncpy((umkpasswd_conf->conf) + strlen(DPATH) + 1, CPATH, strlen(CPATH));
+
+ len = 0;
+
+ while ((EOF != (c = getopt(argc, argv, options))) && !len)
+ {
+ switch (c)
+ {
+ case '5':
+ sum(optarg);
+ break;
+
+ case 'y':
+ umkpasswd_conf->operclass = atoi(optarg);
+ if (umkpasswd_conf->operclass < 0)
+ umkpasswd_conf->operclass = 0;
+ break;
+
+ case 'u':
+ if(umkpasswd_conf->flags && ACT_UPDOPER)
+ {
+ fprintf(stderr, "-a and -u are mutually exclussive. Use either or neither.\n");
+ abort(); /* b0rk b0rk b0rk */
+ }
+
+ umkpasswd_conf->flags |= ACT_UPDOPER;
+ umkpasswd_conf->user = optarg;
+ break;
+
+ case 'm':
+ umkpasswd_conf->mech = optarg;
+ break;
+
+ case 'l':
+ load_mechs();
+ show_mechs();
+ exit(0);
+ break;
+
+ case 'd':
+ umkpasswd_conf->debuglevel = atoi(optarg);
+ if (umkpasswd_conf->debuglevel < 0)
+ umkpasswd_conf->debuglevel = 0;
+ break;
+
+ case 'c':
+ umkpasswd_conf->conf = optarg;
+ break;
+
+ case 'a':
+ if(umkpasswd_conf->flags && ACT_UPDOPER)
+ {
+ fprintf(stderr, "-a and -u are mutually exclussive. Use either or neither.\n");
+ abort(); /* b0rk b0rk b0rk */
+ }
+
+ umkpasswd_conf->flags |= ACT_ADDOPER;
+ umkpasswd_conf->user = optarg;
+ break;
+
+ default:
+ /* unknown option - spit out syntax and b0rk */
+ show_help();
+ abort();
+ break;
+ }
+ }
+
+ Debug((DEBUG_DEBUG, "flags = %d", umkpasswd_conf->flags));
+ Debug((DEBUG_DEBUG, "operclass = %d", umkpasswd_conf->operclass));
+ Debug((DEBUG_DEBUG, "debug = %d", umkpasswd_conf->debuglevel));
+
+ if (NULL != umkpasswd_conf->mech)
+ Debug((DEBUG_DEBUG, "mech = %s", umkpasswd_conf->mech));
+ else
+ Debug((DEBUG_DEBUG, "mech is unset"));
+
+ if (NULL != umkpasswd_conf->conf)
+ Debug((DEBUG_DEBUG, "conf = %s", umkpasswd_conf->conf));
+ else
+ Debug((DEBUG_DEBUG, "conf is unset"));
+
+ if (NULL != umkpasswd_conf->user)
+ Debug((DEBUG_DEBUG, "user = %s", umkpasswd_conf->user));
+ else
+ Debug((DEBUG_DEBUG, "user is unset"));
+
+/* anything left over should be password */
+return argv[optind];
+}
+
+int main(int argc, char **argv)
+{
+char* pw, *crypted_pw;
+
+ crypt_mechs_root = (crypt_mechs_t*)MyMalloc(sizeof(crypt_mechs_t));
+ crypt_mechs_root->mech = NULL;
+ crypt_mechs_root->next = crypt_mechs_root->prev = NULL;
+
+ if (argc < 2)
+ {
+ show_help();
+ exit(0);
+ }
+
+ pw = parse_arguments(argc, argv);
+ load_mechs();
+
+ if (NULL == umkpasswd_conf->mech)
+ {
+ fprintf(stderr, "No mechanism specified.\n");
+ abort();
+ }
+
+ if (NULL == pw)
+ {
+ pw = getpass("Password: ");
+ }
+ crypted_pw = crypt_pass(pw, umkpasswd_conf->mech);
+
+ printf("Crypted Pass: %s\n", crypted_pw);
+ memset(pw, 0, strlen(pw));
+
+return 0;
+}
+#! /bin/sh
+
echo "Extracting ircd/version.c ..."
srcdir=$1
generation=`expr $generation + 1`
-sum=sum
-if $sum ${srcdir}/s_serv.c 1> /dev/null 2>&1; then
-:
-else
- sum=cksum
-fi
-sumsserv=`$sum ${srcdir}/s_serv.c 2> /dev/null`;
-sumsuser=`$sum ${srcdir}/s_user.c 2> /dev/null`;
-sumchan=`$sum ${srcdir}/channel.c 2> /dev/null`;
-sumsbsd=`$sum ${srcdir}/s_bsd.c 2> /dev/null`;
-sumhash=`$sum ${srcdir}/hash.c 2> /dev/null`;
-sumsmisc=`$sum ${srcdir}/s_misc.c 2> /dev/null`;
-sumircd=`$sum ${srcdir}/ircd.c 2> /dev/null`;
-
creation=`date | \
awk '{if (NF == 6) \
- { print $1 " " $2 " " $3 " " $6 " at " $4 " " $5 } \
+ { print $1 " " $2 " " $3 " " $6 " at " $4 " " $5 } \
else \
- { print $1 " " $2 " " $3 " " $7 " at " $4 " " $5 " " $6 }}'`
-
-# cvsversion=`cat ../.patches | \
-# awk -F. '{ \
-# if ($(NF)~/\+$/) \
-# printf(".0"); \
-# else \
-# printf(".%s", $(NF)); \
-# }'`
+ { print $1 " " $2 " " $3 " " $7 " at " $4 " " $5 " " $6 }}'`
/bin/cat >version.c <<!SUB!THIS!
/*
"This program is free software; see LICENSE in the distribution",
"",
"Based on the original code written by Jarkko Oikarinen, version 2.6:",
- "Wiz Jarkko Oikarinen <jto@tolsun.oulu.fi>",
+ "Wiz Jarkko Oikarinen <jto@tolsun.oulu.fi>",
"",
"The main developer of version u2.9 and u2.10 was:",
- "Run Carlo Wood <carlo@runaway.xs4all.nl>",
+ "Run Carlo Wood <carlo@runaway.xs4all.nl>",
"",
- "The current head developer of the u2.10 source tree is:",
+ "The head developer of the u2.10 source tree was:",
"Bleep Thomas Helvey <tomh@inxpress.net>",
"",
+ "The current maintainors of the u2.10 source tree are:",
+ "Isomer Perry Lorier <perry@coders.net>",
+ "Kev Kevin Mitchell <klmitch@mit.edu>",
+ "",
"Contributors to this release:",
"Kev, Isomer, Gte, Ghostwolf, Bleep",
"Debugging and support:",
"A full listing of all coders can be found in doc/Authors in the",
"source.",
"",
- "[$sumsserv] [$sumchan] [$sumsbsd] [$sumsuser]",
- "[$sumhash] [$sumsmisc] [$sumircd]",
+ "Sources:",
+!SUB!THIS!
+
+for file in ${srcdir}/ircd/*.c ; do
+ echo " \"[" `./umkpasswd -5 $file` " ]\"," >> version.c
+done;
+
+echo " \"\"," >> version.c
+echo " \"Headers:\"," >> version.c
+
+for file in ${srcdir}/include/*.h ; do
+ echo " \"[" `./umkpasswd -5 $file` " ]\"," >> version.c
+done;
+
+/bin/cat >>version.c <<!SUB!THIS!
0,
};
!SUB!THIS!