summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhpa <hpa>2005-01-21 00:49:46 +0000
committerhpa <hpa>2005-01-21 00:49:46 +0000
commite8d5cb2b20b82c4e30942834fad8ddb1592bb1db (patch)
treed968800a7b80406059ba06508b84ed62ddfd89db
parentf7c564216b2d987a1b0b30602fd33536c7f4276e (diff)
downloadsyslinux-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.h4
-rw-r--r--com32/libutil/Makefile2
-rw-r--r--com32/libutil/include/base64.h42
-rw-r--r--com32/libutil/include/sha1.h6
-rw-r--r--com32/libutil/sha1hash.c4
-rw-r--r--com32/libutil/unbase64.c78
-rw-r--r--com32/modules/menu.c39
-rw-r--r--com32/modules/menu.h1
-rw-r--r--com32/modules/readconfig.c2
-rwxr-xr-xsha1pass29
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";