Subversion Repositories lsh

Compare Revisions

Ignore whitespace Rev 59 → Rev 60

/trunk/debian/control
13,6 → 13,7
Package: lsh-utils
Architecture: any
Depends: nettle-bin, ${shlibs:Depends}, ${misc:Depends}
Recommends: openssh-blacklist, openssh-blacklist-extra
Suggests: lsh-server, lsh-client, lsh-doc
Description: Secure Shell v2 (SSH2) protocol utilities
lsh is GNU GPL'd implementation of the Secure Shell protocol version
32,8 → 33,10
Package: lsh-server
Architecture: any
Provides: ssh-server
Depends: lsh-utils (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}, debconf (>= 1.2.0) | debconf-2.0
Depends: lsh-utils (= ${binary:Version}), openssh-blacklist
${shlibs:Depends}, ${misc:Depends}, debconf (>= 1.2.0) | debconf-2.0
Conflicts: lsh-utils (<< 1.0.2-3)
Recommends: openssh-blacklist-extra
Suggests: lsh-client | openssh-client, lsh-doc
Description: Secure Shell v2 (SSH2) protocol server
lsh is GNU GPL'd implementation of the Secure Shell
/trunk/debian/patches/blacklist.dpatch
0,0 → 1,351
#! /bin/sh /usr/share/dpatch/dpatch-run
## blacklist.dpatch by Magnus Holmgren <holmgren@debian.org>
## blacklist.c code copied from OpenSSH's authfile.c and adapted for LSH.
##
## DP: Check keys against openssh-blacklist before accepting for
## DP: pubkey authentication as well as on conversion by lsh-writekey
## DP: and lsh-decode-key.
 
@DPATCH@
diff -urNad trunk~/src/Makefile.am trunk/src/Makefile.am
--- trunk~/src/Makefile.am 2004-11-18 22:52:16.000000000 +0100
+++ trunk/src/Makefile.am 2009-11-06 01:07:40.000000000 +0100
@@ -72,7 +72,8 @@
unix_interact.c unix_process.c unix_random.c unix_user.c \
userauth.c \
werror.c write_buffer.c write_packet.c \
- xalloc.c xauth.c zlib.c
+ xalloc.c xauth.c zlib.c \
+ blacklist.c
liblsh_a_LIBADD = @LIBOBJS@
diff -urNad trunk~/src/Makefile.in trunk/src/Makefile.in
--- trunk~/src/Makefile.in 2009-11-06 01:07:40.000000000 +0100
+++ trunk/src/Makefile.in 2009-11-06 01:07:40.000000000 +0100
@@ -91,7 +91,8 @@
tty.$(OBJEXT) unix_interact.$(OBJEXT) unix_process.$(OBJEXT) \
unix_random.$(OBJEXT) unix_user.$(OBJEXT) userauth.$(OBJEXT) \
werror.$(OBJEXT) write_buffer.$(OBJEXT) write_packet.$(OBJEXT) \
- xalloc.$(OBJEXT) xauth.$(OBJEXT) zlib.$(OBJEXT)
+ xalloc.$(OBJEXT) xauth.$(OBJEXT) zlib.$(OBJEXT) \
+ blacklist.$(OBJEXT)
liblsh_a_OBJECTS = $(am_liblsh_a_OBJECTS)
am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" \
"$(DESTDIR)$(bindir)"
@@ -510,7 +511,8 @@
unix_interact.c unix_process.c unix_random.c unix_user.c \
userauth.c \
werror.c write_buffer.c write_packet.c \
- xalloc.c xauth.c zlib.c
+ xalloc.c xauth.c zlib.c \
+ blacklist.c
liblsh_a_LIBADD = @LIBOBJS@
@@ -705,6 +707,7 @@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/algorithms.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alist.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atoms.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blacklist.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel_commands.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel_forward.Po@am__quote@
diff -urNad trunk~/src/blacklist.c trunk/src/blacklist.c
--- trunk~/src/blacklist.c 1970-01-01 01:00:00.000000000 +0100
+++ trunk/src/blacklist.c 2009-11-06 01:07:40.000000000 +0100
@@ -0,0 +1,164 @@
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+
+#include "nettle/bignum.h"
+#include "nettle/dsa.h"
+#include "nettle/rsa.h"
+#include "xalloc.h"
+#include "atoms.h"
+#include "format.h"
+#include "lsh_string.h"
+#include "abstract_crypto.h"
+#include "werror.h"
+#include "crypto.h"
+#define GABA_DECLARE
+#include "rsa.c.x"
+#include "dsa.c.x"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+
+/* Scan a blacklist of known-vulnerable keys in blacklist_file. */
+static int
+blacklisted_key_in_file(struct lsh_string *lsh_hash, struct lsh_string *blacklist_file)
+{
+ int fd = -1;
+ const char *hash = 0;
+ int i;
+ uint32_t line_len;
+ struct stat st;
+ char buf[256];
+ off_t start, lower, upper;
+ int ret = 0;
+
+ debug("Checking blacklist file %S\n", blacklist_file);
+ fd = open(lsh_get_cstring(blacklist_file), O_RDONLY);
+ if (fd < 0) {
+ ret = -1;
+ goto out;
+ }
+
+ hash = lsh_get_cstring(lsh_hash) + 12;
+ line_len = strlen(hash);
+ if (line_len != 20)
+ goto out;
+
+ /* Skip leading comments */
+ start = 0;
+ for (;;) {
+ ssize_t r;
+ char *newline;
+
+ r = read(fd, buf, sizeof(buf));
+ if (r <= 0)
+ goto out;
+ if (buf[0] != '#')
+ break;
+
+ newline = memchr(buf, '\n', sizeof(buf));
+ if (!newline)
+ goto out;
+ start += newline + 1 - buf;
+ if (lseek(fd, start, SEEK_SET) < 0)
+ goto out;
+ }
+
+ /* Initialise binary search record numbers */
+ if (fstat(fd, &st) < 0)
+ goto out;
+ lower = 0;
+ upper = (st.st_size - start) / (line_len + 1);
+
+ while (lower != upper) {
+ off_t cur;
+ int cmp;
+
+ cur = lower + (upper - lower) / 2;
+
+ /* Read this line and compare to digest; this is
+ * overflow-safe since cur < max(off_t) / (line_len + 1) */
+ if (lseek(fd, start + cur * (line_len + 1), SEEK_SET) < 0)
+ break;
+ if (read(fd, buf, line_len) != line_len)
+ break;
+ cmp = memcmp(buf, hash, line_len);
+ if (cmp < 0) {
+ if (cur == lower)
+ break;
+ lower = cur;
+ } else if (cmp > 0) {
+ if (cur == upper)
+ break;
+ upper = cur;
+ } else {
+ ret = 1;
+ break;
+ }
+ }
+
+out:
+ if (fd >= 0)
+ close(fd);
+ return ret;
+}
+
+/*
+ * Scan blacklists of known-vulnerable keys. If a vulnerable key is found,
+ * its fingerprint is returned in *fp, unless fp is NULL.
+ */
+int
+blacklisted_key(struct verifier *v, int method)
+{
+ size_t keysize;
+ const char *keytype;
+ int ret = -1;
+ const char *paths[] = { "/usr/share/ssh/blacklist", "/etc/ssh/blacklist", NULL };
+ const char **pp;
+ struct lsh_string *lsh_hash = ssh_format("%lfxS",
+ hash_string(&crypto_md5_algorithm,
+ PUBLIC_KEY(v), 1));
+
+ switch (method)
+ {
+ case ATOM_SSH_DSS:
+ case ATOM_DSA:
+ {
+ CAST(dsa_verifier, self, v);
+ keytype = "DSA";
+ keysize = mpz_sizeinbase(self->key.p, 2);
+ }
+ break;
+ case ATOM_SSH_RSA:
+ case ATOM_RSA_PKCS1_SHA1:
+ case ATOM_RSA_PKCS1_MD5:
+ case ATOM_RSA_PKCS1:
+ {
+ CAST(rsa_verifier, self, v);
+ keytype = "RSA";
+ keysize = mpz_sizeinbase(self->key.n, 2);
+ } break;
+ default:
+ werror("Unrecognized key type");
+ return 0;
+ }
+
+ for (pp = paths; *pp && ret <= 0; pp++) {
+ struct lsh_string *blacklist_file = ssh_format("%lz.%lz-%di",
+ *pp, keytype, keysize);
+ int r = blacklisted_key_in_file(lsh_hash, blacklist_file);
+ lsh_string_free(blacklist_file);
+ if (r > ret) ret = r;
+ }
+
+ if (ret > 0) {
+ werror("Key is compromised: %z %i %fS\n", keytype, keysize,
+ lsh_string_colonize(lsh_hash, 2, 0));
+ }
+ return ret;
+}
diff -urNad trunk~/src/lsh-decode-key.c trunk/src/lsh-decode-key.c
--- trunk~/src/lsh-decode-key.c 2005-09-06 14:43:15.000000000 +0200
+++ trunk/src/lsh-decode-key.c 2009-11-06 01:07:40.000000000 +0100
@@ -133,6 +133,10 @@
werror("Invalid dsa key.\n");
return NULL;
}
+ else if (blacklisted_key(v, type))
+ {
+ return NULL;
+ }
else
return PUBLIC_SPKI_KEY(v, 1);
}
@@ -150,6 +154,10 @@
werror("Invalid rsa key.\n");
return NULL;
}
+ else if (blacklisted_key(v, type))
+ {
+ return NULL;
+ }
else
return PUBLIC_SPKI_KEY(v, 1);
}
diff -urNad trunk~/src/lsh-writekey.c trunk/src/lsh-writekey.c
--- trunk~/src/lsh-writekey.c 2004-11-17 11:55:11.000000000 +0100
+++ trunk/src/lsh-writekey.c 2009-11-06 01:11:54.000000000 +0100
@@ -397,14 +397,18 @@
{
struct signer *s;
struct verifier *v;
+ int algorithm_name;
- s = spki_make_signer(options->signature_algorithms, key, NULL);
+ s = spki_make_signer(options->signature_algorithms, key, &algorithm_name);
if (!s)
return NULL;
v = SIGNER_GET_VERIFIER(s);
assert(v);
+ if (blacklisted_key(v, algorithm_name)) {
+ return NULL;
+ }
return PUBLIC_SPKI_KEY(v, 1);
}
@@ -416,7 +420,8 @@
int private_fd;
int public_fd;
struct lsh_string *input;
- struct lsh_string *output;
+ struct lsh_string *priv_output;
+ struct lsh_string *pub_output;
const struct exception *e;
argp_parse(&main_argp, argc, argv, 0, NULL, options);
@@ -439,16 +444,22 @@
return EXIT_FAILURE;
}
- output = process_private(input, options);
- if (!output)
+ pub_output = process_public(input, options);
+ if (!pub_output)
+ return EXIT_FAILURE;
+
+ priv_output = process_private(input, options);
+ if (!priv_output)
return EXIT_FAILURE;
+ lsh_string_free(input);
+
private_fd = open_file(options->private_file);
if (private_fd < 0)
return EXIT_FAILURE;
- e = write_raw(private_fd, STRING_LD(output));
- lsh_string_free(output);
+ e = write_raw(private_fd, STRING_LD(priv_output));
+ lsh_string_free(priv_output);
if (e)
{
@@ -457,18 +468,12 @@
return EXIT_FAILURE;
}
- output = process_public(input, options);
- lsh_string_free(input);
-
- if (!output)
- return EXIT_FAILURE;
-
public_fd = open_file(options->public_file);
if (public_fd < 0)
return EXIT_FAILURE;
- e = write_raw(public_fd, STRING_LD(output));
- lsh_string_free(output);
+ e = write_raw(public_fd, STRING_LD(pub_output));
+ lsh_string_free(pub_output);
if (e)
{
diff -urNad trunk~/src/publickey_crypto.h trunk/src/publickey_crypto.h
--- trunk~/src/publickey_crypto.h 2004-06-15 13:32:51.000000000 +0200
+++ trunk/src/publickey_crypto.h 2009-11-06 01:07:40.000000000 +0100
@@ -203,5 +203,7 @@
struct verifier *
make_ssh_dss_verifier(const struct lsh_string *public);
+int
+blacklisted_key(struct verifier *v, int method);
#endif /* LSH_PUBLICKEY_CRYPTO_H_INCLUDED */
diff -urNad trunk~/src/server_authorization.c trunk/src/server_authorization.c
--- trunk~/src/server_authorization.c 2004-06-08 20:01:15.000000000 +0200
+++ trunk/src/server_authorization.c 2009-11-06 01:07:40.000000000 +0100
@@ -93,7 +93,8 @@
PUBLIC_SPKI_KEY(v, 0),
1));
- if (USER_FILE_EXISTS(keyholder, filename, 1))
+ if (USER_FILE_EXISTS(keyholder, filename, 1)
+ && blacklisted_key(v, method) < 1)
return v;
return NULL;
Property changes:
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: debian/patches/00list
===================================================================
--- debian/patches/00list (revision 59)
+++ debian/patches/00list (revision 60)
@@ -2,3 +2,4 @@
30_nonettle
40_better_errmsg_when_dotlsh_missing
nettle_2.0
+blacklist
Index: debian/changelog
===================================================================
--- debian/changelog (revision 59)
+++ debian/changelog (revision 60)
@@ -2,8 +2,13 @@
* lsh-server.init.d: Don't suppress start/stop messages when $VERBOSE =
"no". /etc/init.d/skeleton is not a good example in this matter.
+ * blacklist.dpatch: Check keys against openssh-blacklist before
+ accepting for pubkey authentication as well as on conversion by
+ lsh-writekey and lsh-decode-key.
+ * lsh-server: Depend on openssh-blacklist, recommend -blacklist-extra.
+ lsh-utils: Recommend openssh-blacklist and -blacklist-extra.
- -- Magnus Holmgren <holmgren@debian.org> Sat, 10 Oct 2009 23:16:33 +0200
+ -- Magnus Holmgren <holmgren@debian.org> Sat, 07 Nov 2009 23:08:23 +0100
lsh-utils (2.0.4-dfsg-4) unstable; urgency=high