diff options
author | hpa <hpa> | 2005-01-21 00:49:46 +0000 |
---|---|---|
committer | hpa <hpa> | 2005-01-21 00:49:46 +0000 |
commit | e8d5cb2b20b82c4e30942834fad8ddb1592bb1db (patch) | |
tree | d968800a7b80406059ba06508b84ed62ddfd89db | |
parent | f7c564216b2d987a1b0b30602fd33536c7f4276e (diff) | |
download | syslinux-e8d5cb2b20b82c4e30942834fad8ddb1592bb1db.tar.gz |
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.
-rw-r--r-- | com32/include/netinet/in.h | 4 | ||||
-rw-r--r-- | com32/libutil/Makefile | 2 | ||||
-rw-r--r-- | com32/libutil/include/base64.h | 42 | ||||
-rw-r--r-- | com32/libutil/include/sha1.h | 6 | ||||
-rw-r--r-- | com32/libutil/sha1hash.c | 4 | ||||
-rw-r--r-- | com32/libutil/unbase64.c | 78 | ||||
-rw-r--r-- | com32/modules/menu.c | 39 | ||||
-rw-r--r-- | com32/modules/menu.h | 1 | ||||
-rw-r--r-- | com32/modules/readconfig.c | 2 | ||||
-rwxr-xr-x | sha1pass | 29 |
10 files changed, 192 insertions, 15 deletions
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 <stddef.h> + +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 <stdint.h> + 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 <string.h> +#include <base64.h> + +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 <sys/times.h> #include <unistd.h> #include <sha1.h> +#include <base64.h> #ifdef __COM32__ #include <com32.h> #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]; diff --git a/sha1pass b/sha1pass new file mode 100755 index 00000000..10ec8b5b --- /dev/null +++ b/sha1pass @@ -0,0 +1,29 @@ +#!/usr/bin/perl + +use bytes; +use Digest::SHA1; +use MIME::Base64; + +sub random_bytes($) { + my($n) = @_; + my($v, $i); + + if ( open(RANDOM, '<', '/dev/random') || + open(RANDOM, '<', '/dev/urandom') ) { + read(RANDOM, $v, $n); + } else { + # No real RNG available... + srand($$ ^ time); + $v = ''; + for ( $i = 0 ; $i < $n ; $i++ ) { + $v .= ord(int(rand() * 256)); + } + } + + return $v; +} + +$salt = MIME::Base64::encode(random_bytes(6), ''); +$pass = Digest::SHA1::sha1_base64($salt, $ARGV[0]); + +print '$4$', $salt, '$', $pass, "\$\n"; |