From e8d5cb2b20b82c4e30942834fad8ddb1592bb1db Mon Sep 17 00:00:00 2001 From: hpa Date: Fri, 21 Jan 2005 00:49:46 +0000 Subject: More work on password support for the menu systems. Make the base64 decoder work (necessary to handle encrypted passwords.) Simple SHA-1 password generator in Perl. --- com32/include/netinet/in.h | 4 +-- com32/libutil/Makefile | 2 +- com32/libutil/include/base64.h | 42 +++++++++++++++++++++++ com32/libutil/include/sha1.h | 6 ++-- com32/libutil/sha1hash.c | 4 +-- com32/libutil/unbase64.c | 78 ++++++++++++++++++++++++++++++++++++++++++ com32/modules/menu.c | 39 ++++++++++++++++----- com32/modules/menu.h | 1 + com32/modules/readconfig.c | 2 ++ 9 files changed, 163 insertions(+), 15 deletions(-) create mode 100644 com32/libutil/include/base64.h create mode 100644 com32/libutil/unbase64.c (limited to 'com32') diff --git a/com32/include/netinet/in.h b/com32/include/netinet/in.h index dc11448b..325bd4cf 100644 --- a/com32/include/netinet/in.h +++ b/com32/include/netinet/in.h @@ -27,7 +27,7 @@ static inline uint32_t __htonl(uint32_t v) } #define htonl(x) __htonl(x) -#define ntohl(x) __ntohl(x) +#define ntohl(x) __htonl(x) static inline uint64_t __htonq(uint64_t v) { @@ -35,7 +35,7 @@ static inline uint64_t __htonq(uint64_t v) } #define htonq(x) __htonq(x) -#define ntohq(x) __ntohq(x) +#define ntohq(x) __htonq(x) #endif /* _NETINET_IN_H */ diff --git a/com32/libutil/Makefile b/com32/libutil/Makefile index 9003f986..b9d19a5a 100644 --- a/com32/libutil/Makefile +++ b/com32/libutil/Makefile @@ -47,7 +47,7 @@ LNXCFLAGS = -I./include -W -Wall -O -g LNXSFLAGS = -g LNXLDFLAGS = -g OBJCOPY = objcopy -LIBOBJS = ansiline.o ansiraw.o get_key.o idle.o +LIBOBJS = ansiline.o ansiraw.o get_key.o idle.o sha1hash.o unbase64.o LNXLIBOBJS = $(patsubst %.o,%.lo,$(LIBOBJS)) .SUFFIXES: .lss .c .lo .o .elf .c32 .lnx diff --git a/com32/libutil/include/base64.h b/com32/libutil/include/base64.h new file mode 100644 index 00000000..45c69afc --- /dev/null +++ b/com32/libutil/include/base64.h @@ -0,0 +1,42 @@ +#ident "$Id$" +/* ----------------------------------------------------------------------- * + * + * Copyright 2005 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * base64.h + * + * Simple routines for handing base64 text + */ + +#ifndef LIBUTIL_BASE64_H +#define LIBUTIL_BASE64_H + +#include + +size_t unbase64(unsigned char *, size_t, const char *); + +#endif diff --git a/com32/libutil/include/sha1.h b/com32/libutil/include/sha1.h index 7f08ced3..ea324c72 100644 --- a/com32/libutil/include/sha1.h +++ b/com32/libutil/include/sha1.h @@ -1,15 +1,17 @@ #ifndef LIBUTIL_SHA1_H #define LIBUTIL_SHA1_H +#include + typedef struct { uint32_t state[5]; uint32_t count[2]; unsigned char buffer[64]; } SHA1_CTX; -void SHA1Transform(uint32_t state[5], unsigned char buffer[64]); +void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]); void SHA1Init(SHA1_CTX* context); -void SHA1Update(SHA1_CTX* context, unsigned char* data, uint32_t len); /* +void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len); /* JHB */ void SHA1Final(unsigned char digest[20], SHA1_CTX* context); diff --git a/com32/libutil/sha1hash.c b/com32/libutil/sha1hash.c index 6656b7d0..fc5cc358 100644 --- a/com32/libutil/sha1hash.c +++ b/com32/libutil/sha1hash.c @@ -114,7 +114,7 @@ void SHAPrintContext(SHA1_CTX *context, char *msg){ /* Hash a single 512-bit block. This is the core of the algorithm. */ -void SHA1Transform(uint32_t state[5], unsigned char buffer[64]) +void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]) { uint32_t a, b, c, d, e; typedef union { @@ -183,7 +183,7 @@ void SHA1Init(SHA1_CTX* context) /* Run your data through this. */ -void SHA1Update(SHA1_CTX* context, unsigned char* data, uint32_t len) /* +void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len) /* JHB */ { uint32_t i, j; /* JHB */ diff --git a/com32/libutil/unbase64.c b/com32/libutil/unbase64.c new file mode 100644 index 00000000..83007d3a --- /dev/null +++ b/com32/libutil/unbase64.c @@ -0,0 +1,78 @@ +#ident "$Id$" +/* ----------------------------------------------------------------------- * + * + * Copyright 2005 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * unbase64.c + * + * Convert a string in base64 format to a byte array. + */ + +#include +#include + +static const unsigned char _base64chars[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./"; + +size_t unbase64(unsigned char *buffer, size_t bufsiz, const char *txt) +{ + unsigned int bits = 0; + int nbits = 0; + char base64tbl[256]; + int i; + char v; + size_t nbytes = 0; + + + memset(base64tbl, -1, sizeof base64tbl); + + for ( i = 0 ; _base64chars[i] ; i++ ) { + base64tbl[_base64chars[i]] = i; + } + + /* Also support filesystem safe alternate base64 encoding */ + base64tbl['-'] = 62; + base64tbl['_'] = 63; + + while ( *txt ) { + if ( (v = base64tbl[(unsigned char) *txt]) >= 0 ) { + bits <<= 6; + bits += v; + nbits += 6; + if ( nbits >= 8 ) { + if ( nbytes < bufsiz ) + *buffer++ = (bits >> (nbits-8)); + nbytes++; + nbits -= 8; + } + } + txt++; + } + + return nbytes; +} + diff --git a/com32/modules/menu.c b/com32/modules/menu.c index e6527668..83d8b5bd 100644 --- a/com32/modules/menu.c +++ b/com32/modules/menu.c @@ -29,6 +29,7 @@ #include #include #include +#include #ifdef __COM32__ #include #endif @@ -52,7 +53,7 @@ struct menu_attrib { const char *cmdline; /* Command line */ const char *screen; /* Rest of the screen */ const char *pwdborder; /* Password box border */ - const char *pwdhdr; /* Password box header */ + const char *pwdheader; /* Password box header */ const char *pwdentry; /* Password box contents */ }; @@ -166,23 +167,41 @@ draw_row(int y, int sel, int top, int sbtop, int sbbot) } static int -passwd_compare(const char *entry, const char *passwd) +passwd_compare(const char *passwd, const char *entry) { const char *p; SHA1_CTX ctx; + unsigned char sha1[20], pwdsha1[20]; if ( passwd[0] != '$' ) /* Plaintext passwd, yuck! */ return !strcmp(entry, passwd); - if ( strncmp(passwd, "$2$", 3) ) + if ( strncmp(passwd, "$4$", 3) ) return 0; /* Only SHA-1 passwds supported */ - if ( p = + SHA1Init(&ctx); + + if ( (p = strchr(passwd+3, '$')) ) { + SHA1Update(&ctx, passwd+3, p-(passwd+3)); + p++; + } else { + p = passwd+3; /* Assume no salt */ + } + + SHA1Update(&ctx, entry, strlen(entry)); + SHA1Final(sha1, &ctx); + + memset(pwdsha1, 0, 20); + unbase64(pwdsha1, 20, p); + + return !memcmp(sha1, pwdsha1, 20); +} static int ask_passwd(const struct menu_entry *entry) { - const char title[] = "Password required"; + static const char title[] = "Password required"; + static char user_passwd[] = "passw0rd"; int x; printf("\033[%d;%dH%s\016l", PASSWD_ROW, PASSWD_MARGIN+1, @@ -200,12 +219,16 @@ ask_passwd(const struct menu_entry *entry) printf("j\017\033[%d;%dH%s %s \033[%d;%dH%s", PASSWD_ROW, WIDTH-(sizeof(title)+1)/2, - menu_attrib->pwdtitle, title, + menu_attrib->pwdheader, title, PASSWD_ROW+1, PASSWD_MARGIN+3, menu_attrib->pwdentry); /* Actually allow user to type a password, then compare to the SHA1 */ - - return 0; + if ( (menu_master_passwd && passwd_compare(menu_master_passwd, user_passwd)) + || (entry && entry->passwd && + passwd_compare(entry->passwd, user_passwd)) ) + return 1; + else + return 0; } diff --git a/com32/modules/menu.h b/com32/modules/menu.h index e38c612d..02df13ac 100644 --- a/com32/modules/menu.h +++ b/com32/modules/menu.h @@ -41,6 +41,7 @@ extern int timeout; extern char *menu_title; extern char *ontimeout; +extern char *menu_master_passwd; void parse_config(const char *filename); diff --git a/com32/modules/readconfig.c b/com32/modules/readconfig.c index b3314a75..82b2c56e 100644 --- a/com32/modules/readconfig.c +++ b/com32/modules/readconfig.c @@ -31,6 +31,8 @@ int timeout = 0; char *menu_title = ""; char *ontimeout = NULL; +char *menu_master_passwd = NULL; + struct menu_entry menu_entries[MAX_ENTRIES]; struct menu_entry *menu_hotkeys[256]; -- cgit v1.2.1