From 00da630c4597761fd810784d7260cffc3a0870c3 Mon Sep 17 00:00:00 2001 From: joonicks Date: Fri, 9 Mar 2018 03:51:03 +0100 Subject: [PATCH] sha passwords --- TODO | 10 +- VERSIONS | 4 +- config/pw.c | 45 +++++-- config/sha1.h | 1 + config/sha_internal.c | 1 + configure | 93 +++++++++++-- src/auth.c | 39 +++++- src/config.h.in | 13 ++ src/global.h | 4 +- src/sha/sha.c | 27 ++++ src/sha/sha1.c | 296 ++++++++++++++++++++++++++++++++++++++++++ src/sha/sha1.h | 44 +++++++ src/user.c | 9 +- src/vars.c | 26 ++-- 14 files changed, 568 insertions(+), 44 deletions(-) create mode 120000 config/sha1.h create mode 120000 config/sha_internal.c create mode 100644 src/sha/sha.c create mode 100644 src/sha/sha1.c create mode 100644 src/sha/sha1.h diff --git a/TODO b/TODO index e503ff2..0ac15c7 100644 --- a/TODO +++ b/TODO @@ -1,13 +1,17 @@ /* - * EnergyMech TODO (May 17th, 2009) + * EnergyMech TODO (March 9th, 2018) */ + - URL grabber/log + + - SSL support for irc server/botnet + + - IPv6 support + - Script timer - Genuine telnet protocol support for telnet sessions (?) - - SOCKS4/5 support (?) - - Undernet CService support (IMHO, should be channel settings (set=password, tog=enable/disable) /proton) - DalNet Nickserv/Chanserv support (needed? they dont tolerate much bots on that network /proton) diff --git a/VERSIONS b/VERSIONS index c9ad9e9..471808e 100644 --- a/VERSIONS +++ b/VERSIONS @@ -1,5 +1,7 @@ -3.0.99p4 -- WORK IN PROGRESS (~February, 2018) +3.0.99p4 -- WORK IN PROGRESS (~March, 2018) + * Added: Support for SHA password hashes. + * Added: ESAY $cap will display compile time capabilities. * Fixed: Potential memory corruption bug in do_user(). * Fixed: Aliases saves to session file. * Added: CORE & INFO (statistics) can now be output redirected. diff --git a/config/pw.c b/config/pw.c index 05bcd0f..f7f584d 100644 --- a/config/pw.c +++ b/config/pw.c @@ -1,27 +1,48 @@ #include #include #include + +/* + The glibc2 version of this function supports additional encryption algorithms. + + If salt is a character string starting with the characters "$id$" followed by a string terminated by "$": + + $id$salt$encrypted + + then instead of using the DES machine, id identifies the encryption method used and this then determines how the rest of the password string is inter- + preted. The following values of id are supported: + + ID | Method + --------------------------------------------------------- + 1 | MD5 + 2a | Blowfish (not in mainline glibc; added in some + | Linux distributions) + 5 | SHA-256 (since glibc 2.7) + 6 | SHA-512 (since glibc 2.7) + +*/ + char * CRYPT_FUNC (const char *, const char *); + int main(void) { char *enc; - int md5,des; + int md5,sha; + + md5 = sha = 0; + + enc = CRYPT_FUNC ("abc","$6$"); + if (enc && !strcmp(enc,"$6$$K7EQl9xnonG1x970hnNPqFQKlunsvbFHwzYLnbANzfHjxbphBMjLilW7SKO5EQOidBzcHseqkDOBCSPD8a3CR0")) + sha = 1; - des = md5 = 0; enc = CRYPT_FUNC ("password","$1$XX"); if (enc && !strcmp(enc,"$1$XX$HxaXRcnpWZWDaXxMy1Rfn0")) md5 = 1; - enc = CRYPT_FUNC ("password","XX"); - if (enc && !strcmp(enc,"XXq2wKiyI43A2")) - des = 1; - if (md5 && des) - write(1,"DESaMD5\n",8); - else - if (des) - write(1,"DES\n",4); - else + if (sha) + write(1,"SHA",3); if (md5) - write(1,"MD5\n",4); + write(1,"MD5",3); + write(1,"\n",1); return(0); } diff --git a/config/sha1.h b/config/sha1.h new file mode 120000 index 0000000..02a9c1f --- /dev/null +++ b/config/sha1.h @@ -0,0 +1 @@ +../src/sha/sha1.h \ No newline at end of file diff --git a/config/sha_internal.c b/config/sha_internal.c new file mode 120000 index 0000000..301ee92 --- /dev/null +++ b/config/sha_internal.c @@ -0,0 +1 @@ +../src/sha/sha1.c \ No newline at end of file diff --git a/configure b/configure index 3d48983..adc20f4 100755 --- a/configure +++ b/configure @@ -71,6 +71,7 @@ do redirect ) ft_redirect=$yesno ;; seen ) ft_seen=$yesno ;; session ) ft_session=$yesno ;; + sha ) ft_sha=$yesno ;; stats ) ft_stats=$yesno ;; tcl ) ft_tcl=$yesno ;; telnet ) ft_telnet=$yesno ;; @@ -105,7 +106,7 @@ do esac case "$feature" in - debug | botnet | telnet | alias | seen | session | dyncmd | newbie | wingate | md5 \ + debug | botnet | telnet | alias | seen | session | dyncmd | newbie | wingate | md5 | sha \ | ctcp | dccfile | uptime | redirect | greet | perl | profiling | tcl | dynamode | web \ | note | notify | trivia | toybox | bounce | stats | rawdns | ircd_ext | idwrap | chanban | python ) case _"$optarg"_ in @@ -175,6 +176,8 @@ do seen_no ) ft_seen=no ;; session_yes | session_ ) ft_session=yes ;; session_no ) ft_session=no ;; + sha_yes | sha_ ) ft_seen=yes ;; + sha_no ) ft_sha=no ;; stats_yes | stats_ ) ft_stats=yes ;; stats_no ) ft_stats=no ;; tcl_yes | tcl_ ) ft_tcl=yes ;; @@ -220,6 +223,7 @@ do redirect ) ft_redirect=no ;; seen ) ft_seen=no ;; session ) ft_session=no ;; + sha ) ft_sha=yes ;; stats ) ft_stats=no ;; tcl ) ft_tcl=no ;; telnet ) ft_telnet=no ;; @@ -231,6 +235,7 @@ do esac ;; --md5=internal) ft_md5=internal ;; + --sha=internal) ft_sha=internal ;; --use-cpuflags) cc_arch_opt=yes ;; --no-cpuflags) cc_arch_opt=no ;; --use-optimize) cc_optimize_opt=yes ;; @@ -263,6 +268,7 @@ do ft_redirect=yes ft_seen=yes ft_session=yes + ft_sha=yes ft_stats=yes ft_tcl=yes ft_telnet=yes @@ -283,6 +289,7 @@ Features and packages: --with-FEATURE[=ARG] use FEATURE [ARG=yes] --without-FEATURE do not use FEATURE (same as --with-FEATURE=no) --md5=internal Use internal routines for MD5 password hashes instead of system libraries + --sha=internal Use internal routines for SHA password hashes instead of system libraries #md5 | ctcp | dccfile | uptime | redirect | greet | perl | dynamode | web \ #note | notify | trivia | toybox | bounce | stats | rawdns | ircd_ext | idwrap | chanban | python ) --with-alias ALIAS support @@ -578,7 +585,7 @@ esac rm -f $TESTP # -# +# Some processors like Sparc, will cause a bus error (SIGBUS) if you try to access unaligned memory # has_unaligned=no @@ -619,7 +626,7 @@ echo $ac_t "$has_inet_addr" rm -f $TESTP # -# where is inet_addr() ? +# where is inet_aton() ? # has_inet_aton=no @@ -663,13 +670,59 @@ echo $ac_t "$has_socket" rm -f $TESTP # -# check for MD5 capabilities +# check for SHA capabilities in libc/glibc/libcrypt # +has_sha=no has_md5=no -has_des=no -if [ ! "$ft_md5" = no ]; then +if [ ! "$ft_sha" = no ]; then TESTC=config/pw.c - echo $ac_n "checking for crypt() ... "$ac_c + echo $ac_n "checking for SHA in crypt() ... "$ac_c + sha_internal= + crypt_func='-DCRYPT_FUNC=crypt' + CRYPT_FUNCTION='#define CRYPT_FUNC crypt' + if [ "$ft_sha" = internal ]; then + sha_internal=config/sha_internal.c + crypt_func='-DCRYPT_FUNC=sha_crypt' + CRYPT_FUNCTION='#define CRYPT_FUNC sha_crypt' + fi + $CC -o $TESTP $TESTC $sha_internal $crypt_func 1> /dev/null 2> /dev/null + if [ ! -x $TESTP ]; then + libcrypt=-lcrypt + has_sha=yes + $CC -o $TESTP $TESTC $crypt_func $libcrypt 1> /dev/null 2> /dev/null + fi + if [ ! -x $TESTP ]; then + libcrypt=/usr/lib/libcrypt.so + has_sha=yes + $CC -o $TESTP $TESTC $crypt_func $libcrypt 1> /dev/null 2> /dev/null + fi + if [ ! -x $TESTP ]; then + has_sha=no + libcrypt= + fi + if [ -x $TESTP ]; then + pwhash=`$TESTP` + case "$pwhash" in + MD5 ) has_md5=yes ;; + SHAMD5 ) + has_md5=yes + has_sha=yes + ;; + esac + fi + echo $ac_t "$has_sha" + [ "$has_sha" = yes -a "$sha_internal" ] && has_sha=internal + rm -f $TESTP +fi + +# +# check for MD5 capabilities in libc/glibc/libcrypt +# +if [ "$has_md5" = yes ]; then + echo "checking for MD5 in crypt() ... (cached) yes" +elif [ ! "$ft_md5" = no ]; then + TESTC=config/pw.c + echo $ac_n "checking for MD5 in crypt() ... "$ac_c md5_internal= crypt_func='-DCRYPT_FUNC=crypt' CRYPT_FUNCTION='#define CRYPT_FUNC crypt' @@ -697,11 +750,6 @@ if [ ! "$ft_md5" = no ]; then pwhash=`$TESTP` case "$pwhash" in MD5 ) has_md5=yes ;; - DES ) has_des=yes ;; - DESaMD5 ) - has_md5=yes - has_des=yes - ;; esac fi echo $ac_t "$has_md5" @@ -847,6 +895,11 @@ if [ "$ft_md5" = internal ]; then MD5_O=md5/md5.o fi +SHA_O= +if [ "$ft_sha" = internal ]; then + SHA_O=sha/sha.o +fi + echo echo "Do you want ..." echo @@ -960,6 +1013,17 @@ else test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes -o "$ans" = internal && def_md5='#define MD5CRYPT' fi +def_sha='#undef SHACRYPT' +unset ans +echo $ac_n "SHA password support? ...................... [Y/n] "$ac_c +if [ "$has_sha" = no ]; then + echo 'no (unsupported)' +else + test "$ft_sha" && echo "$ft_sha" && ans=$ft_sha + test -z "$ft_sha" && read ans + test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes -o "$ans" = internal && def_sha='#define SHACRYPT' +fi + def_newbie='#undef NEWBIE' unset ans echo $ac_n "Newbie support? ............................ [Y/n] "$ac_c @@ -1106,6 +1170,7 @@ s%@gdbflag@%$cc_g_flag%; /@PYINCLUDE@/ { s,@PYINCLUDE@,$incpython,; }; /@TCLINCLUDE@/ { s,@TCLINCLUDE@,$inctcl,; }; s|@MD5_O@|$MD5_O|; +s|@SHA_O@|$SHA_O|; s%@oc@%$objcomment%; s%@sz@%$sizecomment%; s/[ ]*\$//g; @@ -1113,8 +1178,10 @@ s/[ ]*\$//g; echo "Creating src/config.h" +CRYPT_HAS_SHA='#undef CRYPT_HAS_SHA' CRYPT_HAS_MD5='#undef CRYPT_HAS_MD5' CRYPT_HAS_DES='#undef CRYPT_HAS_DES' +[ "$has_sha" = yes ] && CRYPT_HAS_SHA='#define CRYPT_HAS_SHA' [ "$has_md5" = yes ] && CRYPT_HAS_MD5='#define CRYPT_HAS_MD5' [ "$has_des" = yes ] && CRYPT_HAS_DES='#define CRYPT_HAS_DES' @@ -1133,6 +1200,7 @@ s|@DEF_DYNAMODE@|$def_dynamode|; s|@DEF_IDWRAP@|$def_idwrap|; s|@DEF_IRCD_EXT@|$def_ircd_ext|; s|@DEF_MD5@|$def_md5|; + s|@DEF_SHA@|$def_sha|; s|@DEF_NEWBIE@|$def_newbie|; s|@DEF_NOTE@|$def_note|; s|@DEF_NOTIFY@|$def_notify|; @@ -1152,6 +1220,7 @@ s|@DEF_REDIRECT@|$def_redirect|; s|@DEF_WINGATE@|$def_wingate|; s|@DEF_CRYPT_FUNCTION@|$CRYPT_FUNCTION|; +s|@CRYPT_HAS_SHA@|$CRYPT_HAS_SHA|; s|@CRYPT_HAS_MD5@|$CRYPT_HAS_MD5|; s|@CRYPT_HAS_DES@|$CRYPT_HAS_DES|; s|@IDWRAP_PATH@|$IDWRAP_PATH|; diff --git a/src/auth.c b/src/auth.c index 05c81af..a2a914d 100644 --- a/src/auth.c +++ b/src/auth.c @@ -1,7 +1,7 @@ /* EnergyMech, IRC bot software - Copyright (c) 2001-2004 proton + Copyright (c) 2001-2018 proton 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 @@ -29,6 +29,7 @@ #include "mcmd.h" #ifndef MD5CRYPT +#ifndef SHACRYPT /* * simple password encryption @@ -114,7 +115,39 @@ int passmatch(char *plain, char *encoded) return(!Strcmp(cipher(plain),encoded)); } -#else /* MD5CRYPT */ +#endif /* not SHACRYPT */ +#endif /* not MD5CRYPT */ + +#ifdef SHACRYPT + +/* + * use SHA512 to hash passwords + */ + +char *CRYPT_FUNC(const char *, const char *); + +char *makepass(char *plain) +{ + char salt[8]; + + sprintf(salt,"$6$%04x",(rand() >> 16)); + return(CRYPT_FUNC(plain,salt)); +} + +int passmatch(char *plain, char *encoded) +{ + char *enc; + + if (matches("$6$????$*",encoded)) + return(FALSE); + enc = CRYPT_FUNC(plain,encoded); + return(!Strcmp(enc,encoded)); +} + +#endif /* SHACRYPT */ + +#ifndef SHACRYPT +#ifdef MD5CRYPT /* * use MD5 to hash passwords @@ -141,7 +174,7 @@ int passmatch(char *plain, char *encoded) } #endif /* MD5CRYPT */ - +#endif /* not SHACRYPT */ /* * */ diff --git a/src/config.h.in b/src/config.h.in index 3e1a955..c718f3b 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -70,6 +70,11 @@ */ @DEF_WINGATE@ +/* + * SHACRYPT: support use of SHA to hash passwords + */ +@DEF_SHA@ + /* * MD5CRYPT: support use of MD5 to hash passwords */ @@ -218,6 +223,7 @@ * */ @DEF_CRYPT_FUNCTION@ +@CRYPT_HAS_SHA@ @CRYPT_HAS_MD5@ @CRYPT_HAS_DES@ @@ -446,6 +452,13 @@ const char __mx_opts[] = "" #undef OPT_COREONLY #endif /* DYNCMD */ +#ifdef SHACRYPT + OPT_COMMA "sha" +#undef OPT_COMMA +#define OPT_COMMA ", " +#undef OPT_COREONLY +#endif /* SHACRYPT */ + #ifdef MD5CRYPT OPT_COMMA "md5" #undef OPT_COMMA diff --git a/src/global.h b/src/global.h index d723634..b47864a 100644 --- a/src/global.h +++ b/src/global.h @@ -1,7 +1,7 @@ /* EnergyMech, IRC bot software - Copyright (c) 1997-2009 proton + Copyright (c) 1997-2018 proton 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 @@ -41,7 +41,7 @@ #define MECHUSERLOGIN "v3.energymech.net" BEG const char VERSION[] MDEF("3.0.99p4"); -BEG const char SRCDATE[] MDEF("March 5th, 2018"); +BEG const char SRCDATE[] MDEF("March 9th, 2018"); #ifdef __CYGWIN__ BEG const char BOTCLASS[] MDEF("WinMech"); #else /* ! CYGWIN */ diff --git a/src/sha/sha.c b/src/sha/sha.c new file mode 100644 index 0000000..8f999dd --- /dev/null +++ b/src/sha/sha.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include "sha1.h" + +int main(int argc, char **argv) +{ + SHA1_CTX sha; + uint8_t results[20]; + char *buf; + int n; + + buf = "abc"; + n = strlen(buf); + SHA1Init(&sha); + SHA1Update(&sha, (uint8_t *)buf, n); + SHA1Final(results, &sha); + + /* Print the digest as one long hex value */ +printf("a9993e364706816aba3e25717850c26c9cd0d89d <-- expected result\n"); +for (n = 0; n < 20; n++) + printf("%02x", results[n]); + + putchar('\n'); + + return(0); +} diff --git a/src/sha/sha1.c b/src/sha/sha1.c new file mode 100644 index 0000000..c2bf174 --- /dev/null +++ b/src/sha/sha1.c @@ -0,0 +1,296 @@ +/* +SHA-1 in C +By Steve Reid +100% Public Domain + +Test Vectors (from FIPS PUB 180-1) +"abc" + A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D +"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 +A million repetitions of "a" + 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F +*/ + +/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */ +/* #define SHA1HANDSOFF * Copies data before messing with it. */ + +#define SHA1HANDSOFF + +#include +#include + +/* for uint32_t */ +#include + +#include "sha1.h" + + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#if BYTE_ORDER == LITTLE_ENDIAN +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ + |(rol(block->l[i],8)&0x00FF00FF)) +#elif BYTE_ORDER == BIG_ENDIAN +#define blk0(i) block->l[i] +#else +#error "Endianness not defined!" +#endif +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +void SHA1Transform( + uint32_t state[5], + const unsigned char buffer[64] +) +{ + uint32_t a, b, c, d, e; + + typedef union + { + unsigned char c[64]; + uint32_t l[16]; + } CHAR64LONG16; + +#ifdef SHA1HANDSOFF + CHAR64LONG16 block[1]; /* use array to appear as a pointer */ + + memcpy(block, buffer, 64); +#else + /* The following had better never be used because it causes the + * pointer-to-const buffer to be cast into a pointer to non-const. + * And the result is written through. I threw a "const" in, hoping + * this will cause a diagnostic. + */ + CHAR64LONG16 *block = (const CHAR64LONG16 *) buffer; +#endif + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a, b, c, d, e, 0); + R0(e, a, b, c, d, 1); + R0(d, e, a, b, c, 2); + R0(c, d, e, a, b, 3); + R0(b, c, d, e, a, 4); + R0(a, b, c, d, e, 5); + R0(e, a, b, c, d, 6); + R0(d, e, a, b, c, 7); + R0(c, d, e, a, b, 8); + R0(b, c, d, e, a, 9); + R0(a, b, c, d, e, 10); + R0(e, a, b, c, d, 11); + R0(d, e, a, b, c, 12); + R0(c, d, e, a, b, 13); + R0(b, c, d, e, a, 14); + R0(a, b, c, d, e, 15); + R1(e, a, b, c, d, 16); + R1(d, e, a, b, c, 17); + R1(c, d, e, a, b, 18); + R1(b, c, d, e, a, 19); + R2(a, b, c, d, e, 20); + R2(e, a, b, c, d, 21); + R2(d, e, a, b, c, 22); + R2(c, d, e, a, b, 23); + R2(b, c, d, e, a, 24); + R2(a, b, c, d, e, 25); + R2(e, a, b, c, d, 26); + R2(d, e, a, b, c, 27); + R2(c, d, e, a, b, 28); + R2(b, c, d, e, a, 29); + R2(a, b, c, d, e, 30); + R2(e, a, b, c, d, 31); + R2(d, e, a, b, c, 32); + R2(c, d, e, a, b, 33); + R2(b, c, d, e, a, 34); + R2(a, b, c, d, e, 35); + R2(e, a, b, c, d, 36); + R2(d, e, a, b, c, 37); + R2(c, d, e, a, b, 38); + R2(b, c, d, e, a, 39); + R3(a, b, c, d, e, 40); + R3(e, a, b, c, d, 41); + R3(d, e, a, b, c, 42); + R3(c, d, e, a, b, 43); + R3(b, c, d, e, a, 44); + R3(a, b, c, d, e, 45); + R3(e, a, b, c, d, 46); + R3(d, e, a, b, c, 47); + R3(c, d, e, a, b, 48); + R3(b, c, d, e, a, 49); + R3(a, b, c, d, e, 50); + R3(e, a, b, c, d, 51); + R3(d, e, a, b, c, 52); + R3(c, d, e, a, b, 53); + R3(b, c, d, e, a, 54); + R3(a, b, c, d, e, 55); + R3(e, a, b, c, d, 56); + R3(d, e, a, b, c, 57); + R3(c, d, e, a, b, 58); + R3(b, c, d, e, a, 59); + R4(a, b, c, d, e, 60); + R4(e, a, b, c, d, 61); + R4(d, e, a, b, c, 62); + R4(c, d, e, a, b, 63); + R4(b, c, d, e, a, 64); + R4(a, b, c, d, e, 65); + R4(e, a, b, c, d, 66); + R4(d, e, a, b, c, 67); + R4(c, d, e, a, b, 68); + R4(b, c, d, e, a, 69); + R4(a, b, c, d, e, 70); + R4(e, a, b, c, d, 71); + R4(d, e, a, b, c, 72); + R4(c, d, e, a, b, 73); + R4(b, c, d, e, a, 74); + R4(a, b, c, d, e, 75); + R4(e, a, b, c, d, 76); + R4(d, e, a, b, c, 77); + R4(c, d, e, a, b, 78); + R4(b, c, d, e, a, 79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; +#ifdef SHA1HANDSOFF + memset(block, '\0', sizeof(block)); +#endif +} + + +/* SHA1Init - Initialize new context */ + +void SHA1Init( + SHA1_CTX * context +) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +void SHA1Update( + SHA1_CTX * context, + const unsigned char *data, + uint32_t len +) +{ + uint32_t i; + + uint32_t j; + + j = context->count[0]; + if ((context->count[0] += len << 3) < j) + context->count[1]++; + context->count[1] += (len >> 29); + j = (j >> 3) & 63; + if ((j + len) > 63) + { + memcpy(&context->buffer[j], data, (i = 64 - j)); + SHA1Transform(context->state, context->buffer); + for (; i + 63 < len; i += 64) + { + SHA1Transform(context->state, &data[i]); + } + j = 0; + } + else + i = 0; + memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* Add padding and return the message digest. */ + +void SHA1Final( + unsigned char digest[20], + SHA1_CTX * context +) +{ + unsigned i; + + unsigned char finalcount[8]; + + unsigned char c; + +#if 0 /* untested "improvement" by DHR */ + /* Convert context->count to a sequence of bytes + * in finalcount. Second element first, but + * big-endian order within element. + * But we do it all backwards. + */ + unsigned char *fcp = &finalcount[8]; + + for (i = 0; i < 2; i++) + { + uint32_t t = context->count[i]; + + int j; + + for (j = 0; j < 4; t >>= 8, j++) + *--fcp = (unsigned char) t} +#else + for (i = 0; i < 8; i++) + { + finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); /* Endian independent */ + } +#endif + c = 0200; + SHA1Update(context, &c, 1); + while ((context->count[0] & 504) != 448) + { + c = 0000; + SHA1Update(context, &c, 1); + } + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++) + { + digest[i] = (unsigned char) + ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); + } + /* Wipe variables */ + memset(context, '\0', sizeof(*context)); + memset(&finalcount, '\0', sizeof(finalcount)); +} + +void SHA1( + char *hash_out, + const char *str, + int len) +{ + SHA1_CTX ctx; + unsigned int ii; + + SHA1Init(&ctx); + for (ii=0; ii + 100% Public Domain + */ + +#include "stdint.h" + +typedef struct +{ + uint32_t state[5]; + uint32_t count[2]; + unsigned char buffer[64]; +} SHA1_CTX; + +void SHA1Transform( + uint32_t state[5], + const unsigned char buffer[64] + ); + +void SHA1Init( + SHA1_CTX * context + ); + +void SHA1Update( + SHA1_CTX * context, + const unsigned char *data, + uint32_t len + ); + +void SHA1Final( + unsigned char digest[20], + SHA1_CTX * context + ); + +void SHA1( + char *hash_out, + const char *str, + int len); + +#endif /* SHA1_H */ diff --git a/src/user.c b/src/user.c index 92e019f..92b50cc 100644 --- a/src/user.c +++ b/src/user.c @@ -1255,7 +1255,7 @@ void do_user(COMMAND_ARGS) addtouser(&user->mask,tmpmask,FALSE); // does not run rehash_chanusers(), does not clobber nuh_buf addtouser(&user->chan,chan,TRUE); // clobbers nuh_buf #ifdef DEBUG - debug("(do_user) from %s, handle %s,\n\tmask %s (arg %s),\n\tuser->mask %s, chan %s\n",from,handle,mask,nick,user->mask,chan); + debug("(do_user) from %s, handle %s,\n\tmask %s, chan %s\n",from,handle,tmpmask,chan); #endif /* DEBUG */ to_user(from,"%s has been added as %s on %s",handle,tmpmask,chan); to_user(from,"Access level: %i%s%s",newaccess,(pass) ? " Password: " : "",(pass) ? pass : ""); @@ -1525,7 +1525,14 @@ void do_echo(COMMAND_ARGS) void change_pass(User *user, char *pass) { User *new,**uptr; + char *enc; + enc = makepass(pass); + if (strlen(user->pass) <= strlen(enc)) + { + Strcpy(user->pass,enc); + user->modcount++; + } /* * password is stuck in a solid malloc in a linked list * add_user() touches current->ul_save for us diff --git a/src/vars.c b/src/vars.c index 1d1f481..c23bdc8 100644 --- a/src/vars.c +++ b/src/vars.c @@ -133,6 +133,11 @@ void ec_access(char *from, char *to) nobo_strcpy(num); } +void ec_capabilities(char *from, char *to) +{ + nobo_strcpy(__mx_opts); +} + void ec_cc(char *from, char *to) { nobo_strcpy((current->activechan) ? current->activechan->name : TEXT_NONE); @@ -272,16 +277,17 @@ LS const struct } ecmd[] = { - { ec_access, "$access", 7 }, - { ec_cc, "$cc", 3 }, - { ec_channels, "$channels", 9 }, - { ec_time, "$time", 5 }, - { ec_set, "$var(", 5 }, - { ec_on, "$on", 3 }, - { ec_server, "$server", 7 }, - { ec_up, "$up", 3 }, - { ec_ver, "$ver", 4 }, - { NULL, "", 0 }, + { ec_access, "$access", 7 }, + { ec_capabilities, "$cap", 4 }, + { ec_cc, "$cc", 3 }, + { ec_channels, "$channels", 9 }, + { ec_time, "$time", 5 }, + { ec_set, "$var(", 5 }, + { ec_on, "$on", 3 }, + { ec_server, "$server", 7 }, + { ec_up, "$up", 3 }, + { ec_ver, "$ver", 4 }, + { NULL, "", 0 }, }; /*