diff --git a/.cvsignore b/.cvsignore index fcc5d1e..a17a1b5 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,2 +1,2 @@ +openssh-5.5p1-noacss.tar.bz2 pam_ssh_agent_auth-0.9.2.tar.bz2 -openssh-5.4p1-noacss.tar.bz2 diff --git a/openssh-5.3p1-dso.patch b/openssh-5.3p1-dso.patch deleted file mode 100644 index 3cf9060..0000000 --- a/openssh-5.3p1-dso.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up openssh-5.3p1/contrib/Makefile.dso openssh-5.3p1/contrib/Makefile ---- openssh-5.3p1/contrib/Makefile.dso 2010-02-15 11:51:53.000000000 +0100 -+++ openssh-5.3p1/contrib/Makefile 2010-02-15 11:54:47.000000000 +0100 -@@ -9,7 +9,7 @@ gnome-ssh-askpass1: gnome-ssh-askpass1.c - gnome-ssh-askpass2: gnome-ssh-askpass2.c - $(CC) `pkg-config --cflags gtk+-2.0` \ - gnome-ssh-askpass2.c -o gnome-ssh-askpass2 \ -- `pkg-config --libs gtk+-2.0` -+ `pkg-config --libs gtk+-2.0` -lX11 - - clean: - rm -f *.o gnome-ssh-askpass1 gnome-ssh-askpass2 gnome-ssh-askpass diff --git a/openssh-5.4p1-fips.patch b/openssh-5.4p1-fips.patch deleted file mode 100644 index 943ab0f..0000000 --- a/openssh-5.4p1-fips.patch +++ /dev/null @@ -1,684 +0,0 @@ -diff -up openssh-5.4p1/auth2-pubkey.c.fips openssh-5.4p1/auth2-pubkey.c ---- openssh-5.4p1/auth2-pubkey.c.fips 2010-03-01 17:55:26.000000000 +0100 -+++ openssh-5.4p1/auth2-pubkey.c 2010-03-01 17:57:56.000000000 +0100 -@@ -35,6 +35,7 @@ - #include - #include - #include -+#include - - #include "xmalloc.h" - #include "ssh.h" -@@ -269,7 +270,7 @@ user_key_allowed2(struct passwd *pw, Key - found_key = 1; - debug("matching key found: file %s, line %lu", - file, linenum); -- fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); -+ fp = key_fingerprint(found, FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX); - verbose("Found matching %s key: %s", - key_type(found), fp); - xfree(fp); -diff -up openssh-5.4p1/authfile.c.fips openssh-5.4p1/authfile.c ---- openssh-5.4p1/authfile.c.fips 2010-01-12 09:42:29.000000000 +0100 -+++ openssh-5.4p1/authfile.c 2010-03-01 17:55:28.000000000 +0100 -@@ -146,8 +146,14 @@ key_save_private_rsa1(Key *key, const ch - /* Allocate space for the private part of the key in the buffer. */ - cp = buffer_append_space(&encrypted, buffer_len(&buffer)); - -- cipher_set_key_string(&ciphercontext, cipher, passphrase, -- CIPHER_ENCRYPT); -+ if (cipher_set_key_string(&ciphercontext, cipher, passphrase, -+ CIPHER_ENCRYPT) < 0) { -+ error("cipher_set_key_string failed."); -+ buffer_free(&encrypted); -+ buffer_free(&buffer); -+ return 0; -+ } -+ - cipher_crypt(&ciphercontext, cp, - buffer_ptr(&buffer), buffer_len(&buffer)); - cipher_cleanup(&ciphercontext); -@@ -421,8 +427,14 @@ key_load_private_rsa1(int fd, const char - cp = buffer_append_space(&decrypted, buffer_len(&buffer)); - - /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ -- cipher_set_key_string(&ciphercontext, cipher, passphrase, -- CIPHER_DECRYPT); -+ if (cipher_set_key_string(&ciphercontext, cipher, passphrase, -+ CIPHER_DECRYPT) < 0) { -+ error("cipher_set_key_string failed."); -+ buffer_free(&decrypted); -+ buffer_free(&buffer); -+ goto fail; -+ } -+ - cipher_crypt(&ciphercontext, cp, - buffer_ptr(&buffer), buffer_len(&buffer)); - cipher_cleanup(&ciphercontext); -diff -up openssh-5.4p1/cipher.c.fips openssh-5.4p1/cipher.c ---- openssh-5.4p1/cipher.c.fips 2010-03-01 15:09:22.000000000 +0100 -+++ openssh-5.4p1/cipher.c 2010-03-01 17:55:28.000000000 +0100 -@@ -40,6 +40,7 @@ - #include - - #include -+#include - - #include - #include -@@ -93,6 +94,22 @@ struct Cipher { - { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL } - }; - -+struct Cipher fips_ciphers[] = { -+ { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, EVP_enc_null }, -+ { "3des", SSH_CIPHER_3DES, 8, 16, 0, 1, evp_ssh1_3des }, -+ -+ { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 1, EVP_des_ede3_cbc }, -+ { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 1, EVP_aes_128_cbc }, -+ { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 1, EVP_aes_192_cbc }, -+ { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, -+ { "rijndael-cbc@lysator.liu.se", -+ SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, -+ { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_128_ctr }, -+ { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_128_ctr }, -+ { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_128_ctr }, -+ { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL } -+}; -+ - /*--*/ - - u_int -@@ -135,7 +152,7 @@ Cipher * - cipher_by_name(const char *name) - { - Cipher *c; -- for (c = ciphers; c->name != NULL; c++) -+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) - if (strcmp(c->name, name) == 0) - return c; - return NULL; -@@ -145,7 +162,7 @@ Cipher * - cipher_by_number(int id) - { - Cipher *c; -- for (c = ciphers; c->name != NULL; c++) -+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) - if (c->number == id) - return c; - return NULL; -@@ -189,7 +206,7 @@ cipher_number(const char *name) - Cipher *c; - if (name == NULL) - return -1; -- for (c = ciphers; c->name != NULL; c++) -+ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) - if (strcasecmp(c->name, name) == 0) - return c->number; - return -1; -@@ -296,14 +313,15 @@ cipher_cleanup(CipherContext *cc) - * passphrase and using the resulting 16 bytes as the key. - */ - --void -+int - cipher_set_key_string(CipherContext *cc, Cipher *cipher, - const char *passphrase, int do_encrypt) - { - MD5_CTX md; - u_char digest[16]; - -- MD5_Init(&md); -+ if (MD5_Init(&md) <= 0) -+ return -1; - MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); - MD5_Final(digest, &md); - -@@ -311,6 +329,7 @@ cipher_set_key_string(CipherContext *cc, - - memset(digest, 0, sizeof(digest)); - memset(&md, 0, sizeof(md)); -+ return 0; - } - - /* -diff -up openssh-5.4p1/cipher-ctr.c.fips openssh-5.4p1/cipher-ctr.c ---- openssh-5.4p1/cipher-ctr.c.fips 2007-06-14 15:21:33.000000000 +0200 -+++ openssh-5.4p1/cipher-ctr.c 2010-03-01 17:55:28.000000000 +0100 -@@ -140,7 +140,8 @@ evp_aes_128_ctr(void) - aes_ctr.do_cipher = ssh_aes_ctr; - #ifndef SSH_OLD_EVP - aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | -- EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; -+ EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV | -+ EVP_CIPH_FLAG_FIPS; - #endif - return (&aes_ctr); - } -diff -up openssh-5.4p1/cipher.h.fips openssh-5.4p1/cipher.h ---- openssh-5.4p1/cipher.h.fips 2009-01-28 06:38:41.000000000 +0100 -+++ openssh-5.4p1/cipher.h 2010-03-01 17:55:28.000000000 +0100 -@@ -78,7 +78,7 @@ void cipher_init(CipherContext *, Ciphe - const u_char *, u_int, int); - void cipher_crypt(CipherContext *, u_char *, const u_char *, u_int); - void cipher_cleanup(CipherContext *); --void cipher_set_key_string(CipherContext *, Cipher *, const char *, int); -+int cipher_set_key_string(CipherContext *, Cipher *, const char *, int); - u_int cipher_blocksize(const Cipher *); - u_int cipher_keylen(const Cipher *); - u_int cipher_is_cbc(const Cipher *); -diff -up openssh-5.4p1/mac.c.fips openssh-5.4p1/mac.c ---- openssh-5.4p1/mac.c.fips 2008-06-13 02:58:50.000000000 +0200 -+++ openssh-5.4p1/mac.c 2010-03-01 17:55:28.000000000 +0100 -@@ -28,6 +28,7 @@ - #include - - #include -+#include - - #include - #include -@@ -47,14 +48,14 @@ - #define SSH_EVP 1 /* OpenSSL EVP-based MAC */ - #define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */ - --struct { -+struct Macs { - char *name; - int type; - const EVP_MD * (*mdfunc)(void); - int truncatebits; /* truncate digest if != 0 */ - int key_len; /* just for UMAC */ - int len; /* just for UMAC */ --} macs[] = { -+} all_macs[] = { - { "hmac-sha1", SSH_EVP, EVP_sha1, 0, -1, -1 }, - { "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, -1, -1 }, - { "hmac-md5", SSH_EVP, EVP_md5, 0, -1, -1 }, -@@ -65,9 +66,15 @@ struct { - { NULL, 0, NULL, 0, -1, -1 } - }; - -+struct Macs fips_macs[] = { -+ { "hmac-sha1", SSH_EVP, EVP_sha1, 0, -1, -1 }, -+ { NULL, 0, NULL, 0, -1, -1 } -+}; -+ - static void - mac_setup_by_id(Mac *mac, int which) - { -+ struct Macs *macs = FIPS_mode() ? fips_macs : all_macs; - int evp_len; - mac->type = macs[which].type; - if (mac->type == SSH_EVP) { -@@ -88,6 +95,7 @@ int - mac_setup(Mac *mac, char *name) - { - int i; -+ struct Macs *macs = FIPS_mode() ? fips_macs : all_macs; - - for (i = 0; macs[i].name; i++) { - if (strcmp(name, macs[i].name) == 0) { -diff -up openssh-5.4p1/Makefile.in.fips openssh-5.4p1/Makefile.in ---- openssh-5.4p1/Makefile.in.fips 2010-02-24 08:18:51.000000000 +0100 -+++ openssh-5.4p1/Makefile.in 2010-03-01 17:55:28.000000000 +0100 -@@ -139,31 +139,31 @@ libssh.a: $(LIBSSH_OBJS) - $(RANLIB) $@ - - ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) -- $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) -- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) -+ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(LIBS) - - scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o - $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) - - ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o -- $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o -- $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-agent.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o -- $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readconf.o -- $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -+ $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) - - ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o - $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) - - ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o -- $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) -+ $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) - - sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o - $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) -diff -up openssh-5.4p1/myproposal.h.fips openssh-5.4p1/myproposal.h ---- openssh-5.4p1/myproposal.h.fips 2010-02-26 21:55:05.000000000 +0100 -+++ openssh-5.4p1/myproposal.h 2010-03-01 17:55:28.000000000 +0100 -@@ -55,7 +55,12 @@ - "hmac-sha1-96,hmac-md5-96" - #define KEX_DEFAULT_COMP "none,zlib@openssh.com,zlib" - #define KEX_DEFAULT_LANG "" -- -+#define KEX_FIPS_ENCRYPT \ -+ "aes128-ctr,aes192-ctr,aes256-ctr," \ -+ "aes128-cbc,3des-cbc," \ -+ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se" -+#define KEX_FIPS_MAC \ -+ "hmac-sha1" - - static char *myproposal[PROPOSAL_MAX] = { - KEX_DEFAULT_KEX, -diff -up openssh-5.4p1/openbsd-compat/bsd-arc4random.c.fips openssh-5.4p1/openbsd-compat/bsd-arc4random.c ---- openssh-5.4p1/openbsd-compat/bsd-arc4random.c.fips 2008-06-04 02:54:00.000000000 +0200 -+++ openssh-5.4p1/openbsd-compat/bsd-arc4random.c 2010-03-01 17:55:28.000000000 +0100 -@@ -39,6 +39,7 @@ - static int rc4_ready = 0; - static RC4_KEY rc4; - -+#if 0 - unsigned int - arc4random(void) - { -@@ -82,6 +83,32 @@ arc4random_stir(void) - - rc4_ready = REKEY_BYTES; - } -+#else -+unsigned int -+arc4random(void) -+{ -+ unsigned int r = 0; -+ void *rp = &r; -+ -+ if (!rc4_ready) { -+ arc4random_stir(); -+ } -+ RAND_bytes(rp, sizeof(r)); -+ -+ return(r); -+} -+ -+void -+arc4random_stir(void) -+{ -+ unsigned char rand_buf[SEED_SIZE]; -+ -+ if (RAND_bytes(rand_buf, sizeof(rand_buf)) <= 0) -+ fatal("Couldn't obtain random bytes (error %ld)", -+ ERR_get_error()); -+ rc4_ready = 1; -+} -+#endif - #endif /* !HAVE_ARC4RANDOM */ - - #ifndef ARC4RANDOM_BUF -diff -up openssh-5.4p1/ssh-add.c.fips openssh-5.4p1/ssh-add.c ---- openssh-5.4p1/ssh-add.c.fips 2010-02-26 21:55:06.000000000 +0100 -+++ openssh-5.4p1/ssh-add.c 2010-03-01 17:55:28.000000000 +0100 -@@ -42,6 +42,7 @@ - #include - - #include -+#include - #include "openbsd-compat/openssl-compat.h" - - #include -@@ -270,7 +271,7 @@ list_identities(AuthenticationConnection - key = ssh_get_next_identity(ac, &comment, version)) { - had_identities = 1; - if (do_fp) { -- fp = key_fingerprint(key, SSH_FP_MD5, -+ fp = key_fingerprint(key, FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, - SSH_FP_HEX); - printf("%d %s %s (%s)\n", - key_size(key), fp, comment, key_type(key)); -diff -up openssh-5.4p1/ssh-agent.c.fips openssh-5.4p1/ssh-agent.c ---- openssh-5.4p1/ssh-agent.c.fips 2010-02-26 21:55:06.000000000 +0100 -+++ openssh-5.4p1/ssh-agent.c 2010-03-01 17:55:28.000000000 +0100 -@@ -51,6 +51,7 @@ - - #include - #include -+#include - #include "openbsd-compat/openssl-compat.h" - - #include -@@ -199,9 +200,9 @@ confirm_key(Identity *id) - char *p; - int ret = -1; - -- p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); -- if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", -- id->comment, p)) -+ p = key_fingerprint(id->key, FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX); -+ if (ask_permission("Allow use of key %s?\nKey %sfingerprint %s.", -+ id->comment, FIPS_mode() ? "SHA1 " : "", p)) - ret = 0; - xfree(p); - -diff -up openssh-5.4p1/ssh.c.fips openssh-5.4p1/ssh.c ---- openssh-5.4p1/ssh.c.fips 2010-02-26 21:55:06.000000000 +0100 -+++ openssh-5.4p1/ssh.c 2010-03-01 17:55:28.000000000 +0100 -@@ -72,6 +72,8 @@ - - #include - #include -+#include -+#include - #include "openbsd-compat/openssl-compat.h" - #include "openbsd-compat/sys-queue.h" - -@@ -225,6 +227,10 @@ main(int ac, char **av) - sanitise_stdfd(); - - __progname = ssh_get_progname(av[0]); -+ SSLeay_add_all_algorithms(); -+ if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) { -+ fatal("FIPS integrity verification test failed."); -+ } - init_rng(); - - /* -@@ -285,6 +291,9 @@ main(int ac, char **av) - "ACD:F:I:KL:MNO:PR:S:TVw:W:XYy")) != -1) { - switch (opt) { - case '1': -+ if (FIPS_mode()) { -+ fatal("Protocol 1 not allowed in the FIPS mode."); -+ } - options.protocol = SSH_PROTO_1; - break; - case '2': -@@ -581,7 +590,6 @@ main(int ac, char **av) - if (!host) - usage(); - -- SSLeay_add_all_algorithms(); - ERR_load_crypto_strings(); - - /* Initialize the command to execute on remote host. */ -@@ -667,6 +675,10 @@ main(int ac, char **av) - - seed_rng(); - -+ if (FIPS_mode()) { -+ logit("FIPS mode initialized"); -+ } -+ - if (options.user == NULL) - options.user = xstrdup(pw->pw_name); - -@@ -733,6 +745,12 @@ main(int ac, char **av) - - timeout_ms = options.connection_timeout * 1000; - -+ if (FIPS_mode()) { -+ options.protocol &= SSH_PROTO_2; -+ if (options.protocol == 0) -+ fatal("Protocol 2 disabled by configuration but required in the FIPS mode."); -+ } -+ - /* Open a connection to the remote host. */ - if (ssh_connect(host, &hostaddr, options.port, - options.address_family, options.connection_attempts, &timeout_ms, -diff -up openssh-5.4p1/sshconnect2.c.fips openssh-5.4p1/sshconnect2.c ---- openssh-5.4p1/sshconnect2.c.fips 2010-03-01 17:55:28.000000000 +0100 -+++ openssh-5.4p1/sshconnect2.c 2010-03-01 17:55:29.000000000 +0100 -@@ -44,6 +44,8 @@ - #include - #endif - -+#include -+ - #include "openbsd-compat/sys-queue.h" - - #include "xmalloc.h" -@@ -116,6 +118,10 @@ ssh_kex2(char *host, struct sockaddr *ho - if (options.ciphers != NULL) { - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; -+ } else if (FIPS_mode()) { -+ myproposal[PROPOSAL_ENC_ALGS_CTOS] = -+ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_FIPS_ENCRYPT; -+ - } - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); -@@ -131,7 +137,11 @@ ssh_kex2(char *host, struct sockaddr *ho - if (options.macs != NULL) { - myproposal[PROPOSAL_MAC_ALGS_CTOS] = - myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; -+ } else if (FIPS_mode()) { -+ myproposal[PROPOSAL_MAC_ALGS_CTOS] = -+ myproposal[PROPOSAL_MAC_ALGS_STOC] = KEX_FIPS_MAC; - } -+ - if (options.hostkeyalgorithms != NULL) - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = - options.hostkeyalgorithms; -@@ -529,8 +539,8 @@ input_userauth_pk_ok(int type, u_int32_t - key->type, pktype); - goto done; - } -- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); -- debug2("input_userauth_pk_ok: fp %s", fp); -+ fp = key_fingerprint(key, SSH_FP_SHA1, SSH_FP_HEX); -+ debug2("input_userauth_pk_ok: SHA1 fp %s", fp); - xfree(fp); - - /* -diff -up openssh-5.4p1/sshconnect.c.fips openssh-5.4p1/sshconnect.c ---- openssh-5.4p1/sshconnect.c.fips 2010-02-26 21:55:06.000000000 +0100 -+++ openssh-5.4p1/sshconnect.c 2010-03-01 17:55:29.000000000 +0100 -@@ -40,6 +40,8 @@ - #include - #include - -+#include -+ - #include "xmalloc.h" - #include "key.h" - #include "hostfile.h" -@@ -789,6 +791,7 @@ check_host_key(char *hostname, struct so - goto fail; - } else if (options.strict_host_key_checking == 2) { - char msg1[1024], msg2[1024]; -+ int fips_on = FIPS_mode(); - - if (show_other_keys(host, host_key)) - snprintf(msg1, sizeof(msg1), -@@ -797,8 +800,8 @@ check_host_key(char *hostname, struct so - else - snprintf(msg1, sizeof(msg1), "."); - /* The default */ -- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); -- ra = key_fingerprint(host_key, SSH_FP_MD5, -+ fp = key_fingerprint(host_key, fips_on ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX); -+ ra = key_fingerprint(host_key, fips_on ? SSH_FP_SHA1 : SSH_FP_MD5, - SSH_FP_RANDOMART); - msg2[0] = '\0'; - if (options.verify_host_key_dns) { -@@ -814,10 +817,10 @@ check_host_key(char *hostname, struct so - snprintf(msg, sizeof(msg), - "The authenticity of host '%.200s (%s)' can't be " - "established%s\n" -- "%s key fingerprint is %s.%s%s\n%s" -+ "%s key %sfingerprint is %s.%s%s\n%s" - "Are you sure you want to continue connecting " - "(yes/no)? ", -- host, ip, msg1, type, fp, -+ host, ip, msg1, type, fips_on ? "SHA1 " : "", fp, - options.visual_host_key ? "\n" : "", - options.visual_host_key ? ra : "", - msg2); -@@ -1131,17 +1134,18 @@ show_key_from_file(const char *file, con - Key *found; - char *fp, *ra; - int line, ret; -+ int fips_on = FIPS_mode(); - - found = key_new(keytype); - if ((ret = lookup_key_in_hostfile_by_type(file, host, - keytype, found, &line))) { -- fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); -- ra = key_fingerprint(found, SSH_FP_MD5, SSH_FP_RANDOMART); -+ fp = key_fingerprint(found, fips_on ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX); -+ ra = key_fingerprint(found, fips_on ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_RANDOMART); - logit("WARNING: %s key found for host %s\n" - "in %s:%d\n" -- "%s key fingerprint %s.\n%s\n", -+ "%s key %sfingerprint %s.\n%s\n", - key_type(found), host, file, line, -- key_type(found), fp, ra); -+ key_type(found), fips_on ? "SHA1 ":"", fp, ra); - xfree(ra); - xfree(fp); - } -@@ -1187,8 +1191,9 @@ warn_changed_key(Key *host_key) - { - char *fp; - const char *type = key_type(host_key); -+ int fips_on = FIPS_mode(); - -- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); -+ fp = key_fingerprint(host_key, fips_on ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX); - - error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); -@@ -1196,8 +1201,8 @@ warn_changed_key(Key *host_key) - error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); - error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); - error("It is also possible that the %s host key has just been changed.", type); -- error("The fingerprint for the %s key sent by the remote host is\n%s.", -- type, fp); -+ error("The %sfingerprint for the %s key sent by the remote host is\n%s.", -+ fips_on ? "SHA1 ":"", type, fp); - error("Please contact your system administrator."); - - xfree(fp); -diff -up openssh-5.4p1/sshd.c.fips openssh-5.4p1/sshd.c ---- openssh-5.4p1/sshd.c.fips 2010-03-01 17:55:27.000000000 +0100 -+++ openssh-5.4p1/sshd.c 2010-03-01 17:55:29.000000000 +0100 -@@ -76,6 +76,8 @@ - #include - #include - #include -+#include -+#include - #include "openbsd-compat/openssl-compat.h" - - #ifdef HAVE_SECUREWARE -@@ -1298,6 +1300,12 @@ main(int ac, char **av) - (void)set_auth_parameters(ac, av); - #endif - __progname = ssh_get_progname(av[0]); -+ -+ SSLeay_add_all_algorithms(); -+ if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) { -+ fatal("FIPS integrity verification test failed."); -+ } -+ - init_rng(); - - /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ -@@ -1459,8 +1467,6 @@ main(int ac, char **av) - else - closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); - -- SSLeay_add_all_algorithms(); -- - /* - * Force logging to stderr until we have loaded the private host - * key (unless started from inetd) -@@ -1578,6 +1584,10 @@ main(int ac, char **av) - debug("private host key: #%d type %d %s", i, key->type, - key_type(key)); - } -+ if ((options.protocol & SSH_PROTO_1) && FIPS_mode()) { -+ logit("Disabling protocol version 1. Not allowed in the FIPS mode."); -+ options.protocol &= ~SSH_PROTO_1; -+ } - if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { - logit("Disabling protocol version 1. Could not load host key"); - options.protocol &= ~SSH_PROTO_1; -@@ -1742,6 +1752,10 @@ main(int ac, char **av) - /* Initialize the random number generator. */ - arc4random_stir(); - -+ if (FIPS_mode()) { -+ logit("FIPS mode initialized"); -+ } -+ - /* Chdir to the root directory so that the current disk can be - unmounted if desired. */ - chdir("/"); -@@ -2274,6 +2288,9 @@ do_ssh2_kex(void) - if (options.ciphers != NULL) { - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; -+ } else if (FIPS_mode()) { -+ myproposal[PROPOSAL_ENC_ALGS_CTOS] = -+ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_FIPS_ENCRYPT; - } - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); -@@ -2283,6 +2300,9 @@ do_ssh2_kex(void) - if (options.macs != NULL) { - myproposal[PROPOSAL_MAC_ALGS_CTOS] = - myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; -+ } else if (FIPS_mode()) { -+ myproposal[PROPOSAL_MAC_ALGS_CTOS] = -+ myproposal[PROPOSAL_MAC_ALGS_STOC] = KEX_FIPS_MAC; - } - if (options.compression == COMP_NONE) { - myproposal[PROPOSAL_COMP_ALGS_CTOS] = -diff -up openssh-5.4p1/ssh-keygen.c.fips openssh-5.4p1/ssh-keygen.c ---- openssh-5.4p1/ssh-keygen.c.fips 2010-02-26 21:55:06.000000000 +0100 -+++ openssh-5.4p1/ssh-keygen.c 2010-03-01 17:55:29.000000000 +0100 -@@ -21,6 +21,7 @@ - - #include - #include -+#include - #include "openbsd-compat/openssl-compat.h" - - #include -@@ -524,7 +525,7 @@ do_fingerprint(struct passwd *pw) - enum fp_type fptype; - struct stat st; - -- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; -+ fptype = print_bubblebabble ? SSH_FP_SHA1 : FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5; - rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; - - if (!have_identity) -@@ -1808,14 +1809,15 @@ passphrase_again: - fclose(f); - - if (!quiet) { -- char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); -- char *ra = key_fingerprint(public, SSH_FP_MD5, -+ int fips_on = FIPS_mode(); -+ char *fp = key_fingerprint(public, fips_on ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX); -+ char *ra = key_fingerprint(public, fips_on ? SSH_FP_SHA1 : SSH_FP_MD5, - SSH_FP_RANDOMART); - printf("Your public key has been saved in %s.\n", - identity_file); -- printf("The key fingerprint is:\n"); -+ printf("The key %sfingerprint is:\n", fips_on ? "SHA1 " : ""); - printf("%s %s\n", fp, comment); -- printf("The key's randomart image is:\n"); -+ printf("The key's %srandomart image is:\n", fips_on ? "SHA1 " :""); - printf("%s\n", ra); - xfree(ra); - xfree(fp); diff --git a/openssh-5.5p1-fips.patch b/openssh-5.5p1-fips.patch new file mode 100644 index 0000000..e098978 --- /dev/null +++ b/openssh-5.5p1-fips.patch @@ -0,0 +1,684 @@ +diff -up openssh-5.5p1/auth2-pubkey.c.fips openssh-5.5p1/auth2-pubkey.c +--- openssh-5.5p1/auth2-pubkey.c.fips 2010-04-16 08:46:47.000000000 +0200 ++++ openssh-5.5p1/auth2-pubkey.c 2010-04-16 08:46:48.000000000 +0200 +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + + #include "xmalloc.h" + #include "ssh.h" +@@ -274,7 +275,7 @@ user_key_allowed2(struct passwd *pw, Key + found_key = 1; + debug("matching key found: file %s, line %lu", + file, linenum); +- fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); ++ fp = key_fingerprint(found, FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX); + verbose("Found matching %s key: %s", + key_type(found), fp); + xfree(fp); +diff -up openssh-5.5p1/authfile.c.fips openssh-5.5p1/authfile.c +--- openssh-5.5p1/authfile.c.fips 2010-03-04 11:53:35.000000000 +0100 ++++ openssh-5.5p1/authfile.c 2010-04-16 08:46:49.000000000 +0200 +@@ -146,8 +146,14 @@ key_save_private_rsa1(Key *key, const ch + /* Allocate space for the private part of the key in the buffer. */ + cp = buffer_append_space(&encrypted, buffer_len(&buffer)); + +- cipher_set_key_string(&ciphercontext, cipher, passphrase, +- CIPHER_ENCRYPT); ++ if (cipher_set_key_string(&ciphercontext, cipher, passphrase, ++ CIPHER_ENCRYPT) < 0) { ++ error("cipher_set_key_string failed."); ++ buffer_free(&encrypted); ++ buffer_free(&buffer); ++ return 0; ++ } ++ + cipher_crypt(&ciphercontext, cp, + buffer_ptr(&buffer), buffer_len(&buffer)); + cipher_cleanup(&ciphercontext); +@@ -421,8 +427,14 @@ key_load_private_rsa1(int fd, const char + cp = buffer_append_space(&decrypted, buffer_len(&buffer)); + + /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ +- cipher_set_key_string(&ciphercontext, cipher, passphrase, +- CIPHER_DECRYPT); ++ if (cipher_set_key_string(&ciphercontext, cipher, passphrase, ++ CIPHER_DECRYPT) < 0) { ++ error("cipher_set_key_string failed."); ++ buffer_free(&decrypted); ++ buffer_free(&buffer); ++ goto fail; ++ } ++ + cipher_crypt(&ciphercontext, cp, + buffer_ptr(&buffer), buffer_len(&buffer)); + cipher_cleanup(&ciphercontext); +diff -up openssh-5.5p1/cipher.c.fips openssh-5.5p1/cipher.c +--- openssh-5.5p1/cipher.c.fips 2010-04-16 08:34:06.000000000 +0200 ++++ openssh-5.5p1/cipher.c 2010-04-16 08:46:49.000000000 +0200 +@@ -40,6 +40,7 @@ + #include + + #include ++#include + + #include + #include +@@ -93,6 +94,22 @@ struct Cipher { + { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL } + }; + ++struct Cipher fips_ciphers[] = { ++ { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, EVP_enc_null }, ++ { "3des", SSH_CIPHER_3DES, 8, 16, 0, 1, evp_ssh1_3des }, ++ ++ { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 1, EVP_des_ede3_cbc }, ++ { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 1, EVP_aes_128_cbc }, ++ { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 1, EVP_aes_192_cbc }, ++ { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, ++ { "rijndael-cbc@lysator.liu.se", ++ SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, ++ { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_128_ctr }, ++ { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_128_ctr }, ++ { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_128_ctr }, ++ { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL } ++}; ++ + /*--*/ + + u_int +@@ -135,7 +152,7 @@ Cipher * + cipher_by_name(const char *name) + { + Cipher *c; +- for (c = ciphers; c->name != NULL; c++) ++ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) + if (strcmp(c->name, name) == 0) + return c; + return NULL; +@@ -145,7 +162,7 @@ Cipher * + cipher_by_number(int id) + { + Cipher *c; +- for (c = ciphers; c->name != NULL; c++) ++ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) + if (c->number == id) + return c; + return NULL; +@@ -189,7 +206,7 @@ cipher_number(const char *name) + Cipher *c; + if (name == NULL) + return -1; +- for (c = ciphers; c->name != NULL; c++) ++ for (c = FIPS_mode() ? fips_ciphers : ciphers; c->name != NULL; c++) + if (strcasecmp(c->name, name) == 0) + return c->number; + return -1; +@@ -296,14 +313,15 @@ cipher_cleanup(CipherContext *cc) + * passphrase and using the resulting 16 bytes as the key. + */ + +-void ++int + cipher_set_key_string(CipherContext *cc, Cipher *cipher, + const char *passphrase, int do_encrypt) + { + MD5_CTX md; + u_char digest[16]; + +- MD5_Init(&md); ++ if (MD5_Init(&md) <= 0) ++ return -1; + MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); + MD5_Final(digest, &md); + +@@ -311,6 +329,7 @@ cipher_set_key_string(CipherContext *cc, + + memset(digest, 0, sizeof(digest)); + memset(&md, 0, sizeof(md)); ++ return 0; + } + + /* +diff -up openssh-5.5p1/cipher-ctr.c.fips openssh-5.5p1/cipher-ctr.c +--- openssh-5.5p1/cipher-ctr.c.fips 2007-06-14 15:21:33.000000000 +0200 ++++ openssh-5.5p1/cipher-ctr.c 2010-04-16 08:46:49.000000000 +0200 +@@ -140,7 +140,8 @@ evp_aes_128_ctr(void) + aes_ctr.do_cipher = ssh_aes_ctr; + #ifndef SSH_OLD_EVP + aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | +- EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; ++ EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV | ++ EVP_CIPH_FLAG_FIPS; + #endif + return (&aes_ctr); + } +diff -up openssh-5.5p1/cipher.h.fips openssh-5.5p1/cipher.h +--- openssh-5.5p1/cipher.h.fips 2009-01-28 06:38:41.000000000 +0100 ++++ openssh-5.5p1/cipher.h 2010-04-16 08:46:49.000000000 +0200 +@@ -78,7 +78,7 @@ void cipher_init(CipherContext *, Ciphe + const u_char *, u_int, int); + void cipher_crypt(CipherContext *, u_char *, const u_char *, u_int); + void cipher_cleanup(CipherContext *); +-void cipher_set_key_string(CipherContext *, Cipher *, const char *, int); ++int cipher_set_key_string(CipherContext *, Cipher *, const char *, int); + u_int cipher_blocksize(const Cipher *); + u_int cipher_keylen(const Cipher *); + u_int cipher_is_cbc(const Cipher *); +diff -up openssh-5.5p1/mac.c.fips openssh-5.5p1/mac.c +--- openssh-5.5p1/mac.c.fips 2008-06-13 02:58:50.000000000 +0200 ++++ openssh-5.5p1/mac.c 2010-04-16 08:46:49.000000000 +0200 +@@ -28,6 +28,7 @@ + #include + + #include ++#include + + #include + #include +@@ -47,14 +48,14 @@ + #define SSH_EVP 1 /* OpenSSL EVP-based MAC */ + #define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */ + +-struct { ++struct Macs { + char *name; + int type; + const EVP_MD * (*mdfunc)(void); + int truncatebits; /* truncate digest if != 0 */ + int key_len; /* just for UMAC */ + int len; /* just for UMAC */ +-} macs[] = { ++} all_macs[] = { + { "hmac-sha1", SSH_EVP, EVP_sha1, 0, -1, -1 }, + { "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, -1, -1 }, + { "hmac-md5", SSH_EVP, EVP_md5, 0, -1, -1 }, +@@ -65,9 +66,15 @@ struct { + { NULL, 0, NULL, 0, -1, -1 } + }; + ++struct Macs fips_macs[] = { ++ { "hmac-sha1", SSH_EVP, EVP_sha1, 0, -1, -1 }, ++ { NULL, 0, NULL, 0, -1, -1 } ++}; ++ + static void + mac_setup_by_id(Mac *mac, int which) + { ++ struct Macs *macs = FIPS_mode() ? fips_macs : all_macs; + int evp_len; + mac->type = macs[which].type; + if (mac->type == SSH_EVP) { +@@ -88,6 +95,7 @@ int + mac_setup(Mac *mac, char *name) + { + int i; ++ struct Macs *macs = FIPS_mode() ? fips_macs : all_macs; + + for (i = 0; macs[i].name; i++) { + if (strcmp(name, macs[i].name) == 0) { +diff -up openssh-5.5p1/Makefile.in.fips openssh-5.5p1/Makefile.in +--- openssh-5.5p1/Makefile.in.fips 2010-03-13 22:41:34.000000000 +0100 ++++ openssh-5.5p1/Makefile.in 2010-04-16 09:48:16.000000000 +0200 +@@ -139,31 +139,31 @@ libssh.a: $(LIBSSH_OBJS) + $(RANLIB) $@ + + ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) +- $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + + sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) +- $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) ++ $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(SSHDLIBS) $(LIBS) + + scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o + $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + + ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o +- $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + + ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o ssh-pkcs11-client.o +- $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ ssh-agent.o ssh-pkcs11-client.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + + ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o +- $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + + ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o readconf.o +- $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ++ $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS) + + ssh-pkcs11-helper$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-pkcs11-helper.o ssh-pkcs11.o + $(LD) -o $@ ssh-pkcs11-helper.o ssh-pkcs11.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) + + ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o +- $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) ++ $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS) + + sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o + $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) +diff -up openssh-5.5p1/myproposal.h.fips openssh-5.5p1/myproposal.h +--- openssh-5.5p1/myproposal.h.fips 2010-02-26 21:55:05.000000000 +0100 ++++ openssh-5.5p1/myproposal.h 2010-04-16 08:46:49.000000000 +0200 +@@ -55,7 +55,12 @@ + "hmac-sha1-96,hmac-md5-96" + #define KEX_DEFAULT_COMP "none,zlib@openssh.com,zlib" + #define KEX_DEFAULT_LANG "" +- ++#define KEX_FIPS_ENCRYPT \ ++ "aes128-ctr,aes192-ctr,aes256-ctr," \ ++ "aes128-cbc,3des-cbc," \ ++ "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se" ++#define KEX_FIPS_MAC \ ++ "hmac-sha1" + + static char *myproposal[PROPOSAL_MAX] = { + KEX_DEFAULT_KEX, +diff -up openssh-5.5p1/openbsd-compat/bsd-arc4random.c.fips openssh-5.5p1/openbsd-compat/bsd-arc4random.c +--- openssh-5.5p1/openbsd-compat/bsd-arc4random.c.fips 2010-03-25 22:52:02.000000000 +0100 ++++ openssh-5.5p1/openbsd-compat/bsd-arc4random.c 2010-04-16 09:17:30.000000000 +0200 +@@ -39,6 +39,7 @@ + static int rc4_ready = 0; + static RC4_KEY rc4; + ++#if 0 + unsigned int + arc4random(void) + { +@@ -82,6 +83,32 @@ arc4random_stir(void) + + rc4_ready = REKEY_BYTES; + } ++#else ++unsigned int ++arc4random(void) ++{ ++ unsigned int r = 0; ++ void *rp = &r; ++ ++ if (!rc4_ready) { ++ arc4random_stir(); ++ } ++ RAND_bytes(rp, sizeof(r)); ++ ++ return(r); ++} ++ ++void ++arc4random_stir(void) ++{ ++ unsigned char rand_buf[SEED_SIZE]; ++ ++ if (RAND_bytes(rand_buf, sizeof(rand_buf)) <= 0) ++ fatal("Couldn't obtain random bytes (error %ld)", ++ ERR_get_error()); ++ rc4_ready = 1; ++} ++#endif + #endif /* !HAVE_ARC4RANDOM */ + + #ifndef HAVE_ARC4RANDOM_BUF +diff -up openssh-5.5p1/ssh-add.c.fips openssh-5.5p1/ssh-add.c +--- openssh-5.5p1/ssh-add.c.fips 2010-03-03 00:25:42.000000000 +0100 ++++ openssh-5.5p1/ssh-add.c 2010-04-16 08:46:49.000000000 +0200 +@@ -42,6 +42,7 @@ + #include + + #include ++#include + #include "openbsd-compat/openssl-compat.h" + + #include +@@ -269,7 +270,7 @@ list_identities(AuthenticationConnection + key = ssh_get_next_identity(ac, &comment, version)) { + had_identities = 1; + if (do_fp) { +- fp = key_fingerprint(key, SSH_FP_MD5, ++ fp = key_fingerprint(key, FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, + SSH_FP_HEX); + printf("%d %s %s (%s)\n", + key_size(key), fp, comment, key_type(key)); +diff -up openssh-5.5p1/ssh-agent.c.fips openssh-5.5p1/ssh-agent.c +--- openssh-5.5p1/ssh-agent.c.fips 2010-02-26 21:55:06.000000000 +0100 ++++ openssh-5.5p1/ssh-agent.c 2010-04-16 08:46:49.000000000 +0200 +@@ -51,6 +51,7 @@ + + #include + #include ++#include + #include "openbsd-compat/openssl-compat.h" + + #include +@@ -199,9 +200,9 @@ confirm_key(Identity *id) + char *p; + int ret = -1; + +- p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); +- if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", +- id->comment, p)) ++ p = key_fingerprint(id->key, FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX); ++ if (ask_permission("Allow use of key %s?\nKey %sfingerprint %s.", ++ id->comment, FIPS_mode() ? "SHA1 " : "", p)) + ret = 0; + xfree(p); + +diff -up openssh-5.5p1/ssh.c.fips openssh-5.5p1/ssh.c +--- openssh-5.5p1/ssh.c.fips 2010-02-26 21:55:06.000000000 +0100 ++++ openssh-5.5p1/ssh.c 2010-04-16 08:46:49.000000000 +0200 +@@ -72,6 +72,8 @@ + + #include + #include ++#include ++#include + #include "openbsd-compat/openssl-compat.h" + #include "openbsd-compat/sys-queue.h" + +@@ -225,6 +227,10 @@ main(int ac, char **av) + sanitise_stdfd(); + + __progname = ssh_get_progname(av[0]); ++ SSLeay_add_all_algorithms(); ++ if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) { ++ fatal("FIPS integrity verification test failed."); ++ } + init_rng(); + + /* +@@ -285,6 +291,9 @@ main(int ac, char **av) + "ACD:F:I:KL:MNO:PR:S:TVw:W:XYy")) != -1) { + switch (opt) { + case '1': ++ if (FIPS_mode()) { ++ fatal("Protocol 1 not allowed in the FIPS mode."); ++ } + options.protocol = SSH_PROTO_1; + break; + case '2': +@@ -581,7 +590,6 @@ main(int ac, char **av) + if (!host) + usage(); + +- SSLeay_add_all_algorithms(); + ERR_load_crypto_strings(); + + /* Initialize the command to execute on remote host. */ +@@ -667,6 +675,10 @@ main(int ac, char **av) + + seed_rng(); + ++ if (FIPS_mode()) { ++ logit("FIPS mode initialized"); ++ } ++ + if (options.user == NULL) + options.user = xstrdup(pw->pw_name); + +@@ -733,6 +745,12 @@ main(int ac, char **av) + + timeout_ms = options.connection_timeout * 1000; + ++ if (FIPS_mode()) { ++ options.protocol &= SSH_PROTO_2; ++ if (options.protocol == 0) ++ fatal("Protocol 2 disabled by configuration but required in the FIPS mode."); ++ } ++ + /* Open a connection to the remote host. */ + if (ssh_connect(host, &hostaddr, options.port, + options.address_family, options.connection_attempts, &timeout_ms, +diff -up openssh-5.5p1/sshconnect2.c.fips openssh-5.5p1/sshconnect2.c +--- openssh-5.5p1/sshconnect2.c.fips 2010-04-16 08:46:48.000000000 +0200 ++++ openssh-5.5p1/sshconnect2.c 2010-04-16 08:46:49.000000000 +0200 +@@ -44,6 +44,8 @@ + #include + #endif + ++#include ++ + #include "openbsd-compat/sys-queue.h" + + #include "xmalloc.h" +@@ -116,6 +118,10 @@ ssh_kex2(char *host, struct sockaddr *ho + if (options.ciphers != NULL) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; ++ } else if (FIPS_mode()) { ++ myproposal[PROPOSAL_ENC_ALGS_CTOS] = ++ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_FIPS_ENCRYPT; ++ + } + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); +@@ -131,7 +137,11 @@ ssh_kex2(char *host, struct sockaddr *ho + if (options.macs != NULL) { + myproposal[PROPOSAL_MAC_ALGS_CTOS] = + myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; ++ } else if (FIPS_mode()) { ++ myproposal[PROPOSAL_MAC_ALGS_CTOS] = ++ myproposal[PROPOSAL_MAC_ALGS_STOC] = KEX_FIPS_MAC; + } ++ + if (options.hostkeyalgorithms != NULL) + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = + options.hostkeyalgorithms; +@@ -529,8 +539,8 @@ input_userauth_pk_ok(int type, u_int32_t + key->type, pktype); + goto done; + } +- fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); +- debug2("input_userauth_pk_ok: fp %s", fp); ++ fp = key_fingerprint(key, SSH_FP_SHA1, SSH_FP_HEX); ++ debug2("input_userauth_pk_ok: SHA1 fp %s", fp); + xfree(fp); + + /* +diff -up openssh-5.5p1/sshconnect.c.fips openssh-5.5p1/sshconnect.c +--- openssh-5.5p1/sshconnect.c.fips 2010-03-04 11:53:36.000000000 +0100 ++++ openssh-5.5p1/sshconnect.c 2010-04-16 08:46:49.000000000 +0200 +@@ -40,6 +40,8 @@ + #include + #include + ++#include ++ + #include "xmalloc.h" + #include "key.h" + #include "hostfile.h" +@@ -789,6 +791,7 @@ check_host_key(char *hostname, struct so + goto fail; + } else if (options.strict_host_key_checking == 2) { + char msg1[1024], msg2[1024]; ++ int fips_on = FIPS_mode(); + + if (show_other_keys(host, host_key)) + snprintf(msg1, sizeof(msg1), +@@ -797,8 +800,8 @@ check_host_key(char *hostname, struct so + else + snprintf(msg1, sizeof(msg1), "."); + /* The default */ +- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); +- ra = key_fingerprint(host_key, SSH_FP_MD5, ++ fp = key_fingerprint(host_key, fips_on ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX); ++ ra = key_fingerprint(host_key, fips_on ? SSH_FP_SHA1 : SSH_FP_MD5, + SSH_FP_RANDOMART); + msg2[0] = '\0'; + if (options.verify_host_key_dns) { +@@ -814,10 +817,10 @@ check_host_key(char *hostname, struct so + snprintf(msg, sizeof(msg), + "The authenticity of host '%.200s (%s)' can't be " + "established%s\n" +- "%s key fingerprint is %s.%s%s\n%s" ++ "%s key %sfingerprint is %s.%s%s\n%s" + "Are you sure you want to continue connecting " + "(yes/no)? ", +- host, ip, msg1, type, fp, ++ host, ip, msg1, type, fips_on ? "SHA1 " : "", fp, + options.visual_host_key ? "\n" : "", + options.visual_host_key ? ra : "", + msg2); +@@ -1151,17 +1154,18 @@ show_key_from_file(const char *file, con + Key *found; + char *fp, *ra; + int line, ret; ++ int fips_on = FIPS_mode(); + + found = key_new(keytype); + if ((ret = lookup_key_in_hostfile_by_type(file, host, + keytype, found, &line))) { +- fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); +- ra = key_fingerprint(found, SSH_FP_MD5, SSH_FP_RANDOMART); ++ fp = key_fingerprint(found, fips_on ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX); ++ ra = key_fingerprint(found, fips_on ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_RANDOMART); + logit("WARNING: %s key found for host %s\n" + "in %s:%d\n" +- "%s key fingerprint %s.\n%s\n", ++ "%s key %sfingerprint %s.\n%s\n", + key_type(found), host, file, line, +- key_type(found), fp, ra); ++ key_type(found), fips_on ? "SHA1 ":"", fp, ra); + xfree(ra); + xfree(fp); + } +@@ -1207,8 +1211,9 @@ warn_changed_key(Key *host_key) + { + char *fp; + const char *type = key_type(host_key); ++ int fips_on = FIPS_mode(); + +- fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX); ++ fp = key_fingerprint(host_key, fips_on ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX); + + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @"); +@@ -1216,8 +1221,8 @@ warn_changed_key(Key *host_key) + error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!"); + error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!"); + error("It is also possible that the %s host key has just been changed.", type); +- error("The fingerprint for the %s key sent by the remote host is\n%s.", +- type, fp); ++ error("The %sfingerprint for the %s key sent by the remote host is\n%s.", ++ fips_on ? "SHA1 ":"", type, fp); + error("Please contact your system administrator."); + + xfree(fp); +diff -up openssh-5.5p1/sshd.c.fips openssh-5.5p1/sshd.c +--- openssh-5.5p1/sshd.c.fips 2010-04-16 08:46:48.000000000 +0200 ++++ openssh-5.5p1/sshd.c 2010-04-16 08:46:49.000000000 +0200 +@@ -76,6 +76,8 @@ + #include + #include + #include ++#include ++#include + #include "openbsd-compat/openssl-compat.h" + + #ifdef HAVE_SECUREWARE +@@ -1298,6 +1300,12 @@ main(int ac, char **av) + (void)set_auth_parameters(ac, av); + #endif + __progname = ssh_get_progname(av[0]); ++ ++ SSLeay_add_all_algorithms(); ++ if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) { ++ fatal("FIPS integrity verification test failed."); ++ } ++ + init_rng(); + + /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ +@@ -1459,8 +1467,6 @@ main(int ac, char **av) + else + closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); + +- SSLeay_add_all_algorithms(); +- + /* + * Force logging to stderr until we have loaded the private host + * key (unless started from inetd) +@@ -1578,6 +1584,10 @@ main(int ac, char **av) + debug("private host key: #%d type %d %s", i, key->type, + key_type(key)); + } ++ if ((options.protocol & SSH_PROTO_1) && FIPS_mode()) { ++ logit("Disabling protocol version 1. Not allowed in the FIPS mode."); ++ options.protocol &= ~SSH_PROTO_1; ++ } + if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { + logit("Disabling protocol version 1. Could not load host key"); + options.protocol &= ~SSH_PROTO_1; +@@ -1742,6 +1752,10 @@ main(int ac, char **av) + /* Initialize the random number generator. */ + arc4random_stir(); + ++ if (FIPS_mode()) { ++ logit("FIPS mode initialized"); ++ } ++ + /* Chdir to the root directory so that the current disk can be + unmounted if desired. */ + chdir("/"); +@@ -2275,6 +2289,9 @@ do_ssh2_kex(void) + if (options.ciphers != NULL) { + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; ++ } else if (FIPS_mode()) { ++ myproposal[PROPOSAL_ENC_ALGS_CTOS] = ++ myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_FIPS_ENCRYPT; + } + myproposal[PROPOSAL_ENC_ALGS_CTOS] = + compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); +@@ -2284,6 +2301,9 @@ do_ssh2_kex(void) + if (options.macs != NULL) { + myproposal[PROPOSAL_MAC_ALGS_CTOS] = + myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; ++ } else if (FIPS_mode()) { ++ myproposal[PROPOSAL_MAC_ALGS_CTOS] = ++ myproposal[PROPOSAL_MAC_ALGS_STOC] = KEX_FIPS_MAC; + } + if (options.compression == COMP_NONE) { + myproposal[PROPOSAL_COMP_ALGS_CTOS] = +diff -up openssh-5.5p1/ssh-keygen.c.fips openssh-5.5p1/ssh-keygen.c +--- openssh-5.5p1/ssh-keygen.c.fips 2010-03-21 19:58:24.000000000 +0100 ++++ openssh-5.5p1/ssh-keygen.c 2010-04-16 08:46:49.000000000 +0200 +@@ -21,6 +21,7 @@ + + #include + #include ++#include + #include "openbsd-compat/openssl-compat.h" + + #include +@@ -527,7 +528,7 @@ do_fingerprint(struct passwd *pw) + enum fp_type fptype; + struct stat st; + +- fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5; ++ fptype = print_bubblebabble ? SSH_FP_SHA1 : FIPS_mode() ? SSH_FP_SHA1 : SSH_FP_MD5; + rep = print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX; + + if (!have_identity) +@@ -1916,14 +1917,15 @@ passphrase_again: + fclose(f); + + if (!quiet) { +- char *fp = key_fingerprint(public, SSH_FP_MD5, SSH_FP_HEX); +- char *ra = key_fingerprint(public, SSH_FP_MD5, ++ int fips_on = FIPS_mode(); ++ char *fp = key_fingerprint(public, fips_on ? SSH_FP_SHA1 : SSH_FP_MD5, SSH_FP_HEX); ++ char *ra = key_fingerprint(public, fips_on ? SSH_FP_SHA1 : SSH_FP_MD5, + SSH_FP_RANDOMART); + printf("Your public key has been saved in %s.\n", + identity_file); +- printf("The key fingerprint is:\n"); ++ printf("The key %sfingerprint is:\n", fips_on ? "SHA1 " : ""); + printf("%s %s\n", fp, comment); +- printf("The key's randomart image is:\n"); ++ printf("The key's %srandomart image is:\n", fips_on ? "SHA1 " :""); + printf("%s\n", ra); + xfree(ra); + xfree(fp); diff --git a/openssh-5.5p1-mls.patch b/openssh-5.5p1-mls.patch new file mode 100644 index 0000000..3c12716 --- /dev/null +++ b/openssh-5.5p1-mls.patch @@ -0,0 +1,432 @@ +diff -up openssh-5.4p1/configure.ac.mls openssh-5.4p1/configure.ac +--- openssh-5.4p1/configure.ac.mls 2010-03-01 15:24:27.000000000 +0100 ++++ openssh-5.4p1/configure.ac 2010-03-01 15:24:28.000000000 +0100 +@@ -3360,6 +3360,7 @@ AC_ARG_WITH(selinux, + SSHDLIBS="$SSHDLIBS $LIBSELINUX" + LIBS="$LIBS $LIBSELINUX" + AC_CHECK_FUNCS(getseuserbyname get_default_context_with_level) ++ AC_CHECK_FUNCS(setkeycreatecon) + LIBS="$save_LIBS" + fi ] + ) +diff -up openssh-5.4p1/misc.c.mls openssh-5.4p1/misc.c +--- openssh-5.4p1/misc.c.mls 2010-01-10 00:31:12.000000000 +0100 ++++ openssh-5.4p1/misc.c 2010-03-01 15:24:28.000000000 +0100 +@@ -423,6 +423,7 @@ char * + colon(char *cp) + { + int flag = 0; ++ int start = 1; + + if (*cp == ':') /* Leading colon is part of file name. */ + return (0); +@@ -436,8 +437,13 @@ colon(char *cp) + return (cp+1); + if (*cp == ':' && !flag) + return (cp); +- if (*cp == '/') +- return (0); ++ if (start) { ++ /* Slash on beginning or after dots only denotes file name. */ ++ if (*cp == '/') ++ return (0); ++ if (*cp != '.') ++ start = 0; ++ } + } + return (0); + } +diff -up openssh-5.4p1/openbsd-compat/port-linux.c.mls openssh-5.4p1/openbsd-compat/port-linux.c +--- openssh-5.4p1/openbsd-compat/port-linux.c.mls 2010-03-01 15:24:27.000000000 +0100 ++++ openssh-5.4p1/openbsd-compat/port-linux.c 2010-03-01 15:25:50.000000000 +0100 +@@ -35,13 +35,24 @@ + #include "key.h" + #include "hostfile.h" + #include "auth.h" ++#include "xmalloc.h" + + #ifdef WITH_SELINUX + #include + #include ++#include + #include ++#include ++#include ++ ++#ifdef HAVE_LINUX_AUDIT ++#include ++#include ++#endif + + extern Authctxt *the_authctxt; ++extern int inetd_flag; ++extern int rexeced_flag; + + /* Wrapper around is_selinux_enabled() to log its return value once only */ + int +@@ -57,17 +68,173 @@ ssh_selinux_enabled(void) + return (enabled); + } + ++/* Send audit message */ ++static int ++send_audit_message(int success, security_context_t default_context, ++ security_context_t selected_context) ++{ ++ int rc=0; ++#ifdef HAVE_LINUX_AUDIT ++ char *msg = NULL; ++ int audit_fd = audit_open(); ++ security_context_t default_raw=NULL; ++ security_context_t selected_raw=NULL; ++ rc = -1; ++ if (audit_fd < 0) { ++ if (errno == EINVAL || errno == EPROTONOSUPPORT || ++ errno == EAFNOSUPPORT) ++ return 0; /* No audit support in kernel */ ++ error("Error connecting to audit system."); ++ return rc; ++ } ++ if (selinux_trans_to_raw_context(default_context, &default_raw) < 0) { ++ error("Error translating default context."); ++ default_raw = NULL; ++ } ++ if (selinux_trans_to_raw_context(selected_context, &selected_raw) < 0) { ++ error("Error translating selected context."); ++ selected_raw = NULL; ++ } ++ if (asprintf(&msg, "sshd: default-context=%s selected-context=%s", ++ default_raw ? default_raw : (default_context ? default_context: "?"), ++ selected_context ? selected_raw : (selected_context ? selected_context :"?")) < 0) { ++ error("Error allocating memory."); ++ goto out; ++ } ++ if (audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE, ++ msg, NULL, NULL, NULL, success) <= 0) { ++ error("Error sending audit message."); ++ goto out; ++ } ++ rc = 0; ++ out: ++ free(msg); ++ freecon(default_raw); ++ freecon(selected_raw); ++ close(audit_fd); ++#endif ++ return rc; ++} ++ ++static int ++mls_range_allowed(security_context_t src, security_context_t dst) ++{ ++ struct av_decision avd; ++ int retval; ++ unsigned int bit = CONTEXT__CONTAINS; ++ ++ debug("%s: src:%s dst:%s", __func__, src, dst); ++ retval = security_compute_av(src, dst, SECCLASS_CONTEXT, bit, &avd); ++ if (retval || ((bit & avd.allowed) != bit)) ++ return 0; ++ ++ return 1; ++} ++ ++static int ++get_user_context(const char *sename, const char *role, const char *lvl, ++ security_context_t *sc) { ++#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL ++ if (lvl == NULL || lvl[0] == '\0' || get_default_context_with_level(sename, lvl, NULL, sc) != 0) { ++ /* User may have requested a level completely outside of his ++ allowed range. We get a context just for auditing as the ++ range check below will certainly fail for default context. */ ++#endif ++ if (get_default_context(sename, NULL, sc) != 0) { ++ *sc = NULL; ++ return -1; ++ } ++#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL ++ } ++#endif ++ if (role != NULL && role[0]) { ++ context_t con; ++ char *type=NULL; ++ if (get_default_type(role, &type) != 0) { ++ error("get_default_type: failed to get default type for '%s'", ++ role); ++ goto out; ++ } ++ con = context_new(*sc); ++ if (!con) { ++ goto out; ++ } ++ context_role_set(con, role); ++ context_type_set(con, type); ++ freecon(*sc); ++ *sc = strdup(context_str(con)); ++ context_free(con); ++ if (!*sc) ++ return -1; ++ } ++#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL ++ if (lvl != NULL && lvl[0]) { ++ /* verify that the requested range is obtained */ ++ context_t con; ++ security_context_t obtained_raw; ++ security_context_t requested_raw; ++ con = context_new(*sc); ++ if (!con) { ++ goto out; ++ } ++ context_range_set(con, lvl); ++ if (selinux_trans_to_raw_context(*sc, &obtained_raw) < 0) { ++ context_free(con); ++ goto out; ++ } ++ if (selinux_trans_to_raw_context(context_str(con), &requested_raw) < 0) { ++ freecon(obtained_raw); ++ context_free(con); ++ goto out; ++ } ++ ++ debug("get_user_context: obtained context '%s' requested context '%s'", ++ obtained_raw, requested_raw); ++ if (strcmp(obtained_raw, requested_raw)) { ++ /* set the context to the real requested one but fail */ ++ freecon(requested_raw); ++ freecon(obtained_raw); ++ freecon(*sc); ++ *sc = strdup(context_str(con)); ++ context_free(con); ++ return -1; ++ } ++ freecon(requested_raw); ++ freecon(obtained_raw); ++ context_free(con); ++ } ++#endif ++ return 0; ++ out: ++ freecon(*sc); ++ *sc = NULL; ++ return -1; ++} ++ + /* Return the default security context for the given username */ +-static security_context_t +-ssh_selinux_getctxbyname(char *pwname) ++static int ++ssh_selinux_getctxbyname(char *pwname, ++ security_context_t *default_sc, security_context_t *user_sc) + { +- security_context_t sc = NULL; + char *sename, *lvl; ++ const char *reqlvl = NULL; + char *role = NULL; +- int r = 0; ++ int r = -1; ++ context_t con = NULL; ++ ++ *default_sc = NULL; ++ *user_sc = NULL; ++ if (the_authctxt) { ++ if (the_authctxt->role != NULL) { ++ char *slash; ++ role = xstrdup(the_authctxt->role); ++ if ((slash = strchr(role, '/')) != NULL) { ++ *slash = '\0'; ++ reqlvl = slash + 1; ++ } ++ } ++ } + +- if (the_authctxt) +- role=the_authctxt->role; + #ifdef HAVE_GETSEUSERBYNAME + if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) { + sename = NULL; +@@ -75,38 +242,63 @@ ssh_selinux_getctxbyname(char *pwname) + } + #else + sename = pwname; +- lvl = NULL; ++ lvl = ""; + #endif + + if (r == 0) { + #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL +- if (role != NULL && role[0]) +- r = get_default_context_with_rolelevel(sename, role, lvl, NULL, &sc); +- else +- r = get_default_context_with_level(sename, lvl, NULL, &sc); ++ r = get_default_context_with_level(sename, lvl, NULL, default_sc); + #else +- if (role != NULL && role[0]) +- r = get_default_context_with_role(sename, role, NULL, &sc); +- else +- r = get_default_context(sename, NULL, &sc); ++ r = get_default_context(sename, NULL, default_sc); + #endif + } + +- if (r != 0) { +- switch (security_getenforce()) { +- case -1: +- fatal("%s: ssh_selinux_getctxbyname: " +- "security_getenforce() failed", __func__); +- case 0: +- error("%s: Failed to get default SELinux security " +- "context for %s", __func__, pwname); +- break; +- default: +- fatal("%s: Failed to get default SELinux security " +- "context for %s (in enforcing mode)", +- __func__, pwname); ++ if (r == 0) { ++ /* If launched from xinetd, we must use current level */ ++ if (inetd_flag && !rexeced_flag) { ++ security_context_t sshdsc=NULL; ++ ++ if (getcon_raw(&sshdsc) < 0) ++ fatal("failed to allocate security context"); ++ ++ if ((con=context_new(sshdsc)) == NULL) ++ fatal("failed to allocate selinux context"); ++ reqlvl = context_range_get(con); ++ freecon(sshdsc); ++ if (reqlvl !=NULL && lvl != NULL && strcmp(reqlvl, lvl) == 0) ++ /* we actually don't change level */ ++ reqlvl = ""; ++ ++ debug("%s: current connection level '%s'", __func__, reqlvl); ++ } ++ ++ if ((reqlvl != NULL && reqlvl[0]) || (role != NULL && role[0])) { ++ r = get_user_context(sename, role, reqlvl, user_sc); ++ ++ if (r == 0 && reqlvl != NULL && reqlvl[0]) { ++ security_context_t default_level_sc = *default_sc; ++ if (role != NULL && role[0]) { ++ if (get_user_context(sename, role, lvl, &default_level_sc) < 0) ++ default_level_sc = *default_sc; ++ } ++ /* verify that the requested range is contained in the user range */ ++ if (mls_range_allowed(default_level_sc, *user_sc)) { ++ logit("permit MLS level %s (user range %s)", reqlvl, lvl); ++ } else { ++ r = -1; ++ error("deny MLS level %s (user range %s)", reqlvl, lvl); ++ } ++ if (default_level_sc != *default_sc) ++ freecon(default_level_sc); ++ } ++ } else { ++ *user_sc = *default_sc; + } + } ++ if (r != 0) { ++ error("%s: Failed to get default SELinux security " ++ "context for %s", __func__, pwname); ++ } + + #ifdef HAVE_GETSEUSERBYNAME + if (sename != NULL) +@@ -114,14 +306,20 @@ ssh_selinux_getctxbyname(char *pwname) + if (lvl != NULL) + xfree(lvl); + #endif ++ if (role != NULL) ++ xfree(role); ++ if (con) ++ context_free(con); + +- return (sc); ++ return (r); + } + + /* Set the execution context to the default for the specified user */ + void + ssh_selinux_setup_exec_context(char *pwname) + { ++ int r = 0; ++ security_context_t default_ctx = NULL; + security_context_t user_ctx = NULL; + + if (!ssh_selinux_enabled()) +@@ -129,22 +327,45 @@ ssh_selinux_setup_exec_context(char *pwn + + debug3("%s: setting execution context", __func__); + +- user_ctx = ssh_selinux_getctxbyname(pwname); +- if (setexeccon(user_ctx) != 0) { ++ r = ssh_selinux_getctxbyname(pwname, &default_ctx, &user_ctx); ++ if (r >= 0) { ++ r = setexeccon(user_ctx); ++ if (r < 0) { ++ error("%s: Failed to set SELinux execution context %s for %s", ++ __func__, user_ctx, pwname); ++ } ++#ifdef HAVE_SETKEYCREATECON ++ else if (setkeycreatecon(user_ctx) < 0) { ++ error("%s: Failed to set SELinux keyring creation context %s for %s", ++ __func__, user_ctx, pwname); ++ } ++#endif ++ } ++ if (user_ctx == NULL) { ++ user_ctx = default_ctx; ++ } ++ if (r < 0 || user_ctx != default_ctx) { ++ /* audit just the case when user changed a role or there was ++ a failure */ ++ send_audit_message(r >= 0, default_ctx, user_ctx); ++ } ++ if (r < 0) { + switch (security_getenforce()) { + case -1: + fatal("%s: security_getenforce() failed", __func__); + case 0: +- error("%s: Failed to set SELinux execution " +- "context for %s", __func__, pwname); ++ error("%s: SELinux failure. Continuing in permissive mode.", ++ __func__); + break; + default: +- fatal("%s: Failed to set SELinux execution context " +- "for %s (in enforcing mode)", __func__, pwname); ++ fatal("%s: SELinux failure. Aborting connection.", ++ __func__); + } + } +- if (user_ctx != NULL) ++ if (user_ctx != NULL && user_ctx != default_ctx) + freecon(user_ctx); ++ if (default_ctx != NULL) ++ freecon(default_ctx); + + debug3("%s: done", __func__); + } +@@ -162,7 +383,10 @@ ssh_selinux_setup_pty(char *pwname, cons + + debug3("%s: setting TTY context on %s", __func__, tty); + +- user_ctx = ssh_selinux_getctxbyname(pwname); ++ if (getexeccon(&user_ctx) < 0) { ++ error("%s: getexeccon: %s", __func__, strerror(errno)); ++ goto out; ++ } + + /* XXX: should these calls fatal() upon failure in enforcing mode? */ + +diff -up openssh-5.4p1/sshd.c.mls openssh-5.4p1/sshd.c +--- openssh-5.4p1/sshd.c.mls 2010-03-01 15:24:27.000000000 +0100 ++++ openssh-5.4p1/sshd.c 2010-03-01 15:24:28.000000000 +0100 +@@ -1987,6 +1987,9 @@ main(int ac, char **av) + restore_uid(); + } + #endif ++#ifdef WITH_SELINUX ++ ssh_selinux_setup_exec_context(authctxt->pw->pw_name); ++#endif + #ifdef USE_PAM + if (options.use_pam) { + do_pam_setcred(1); diff --git a/openssh.spec b/openssh.spec index 76bf518..6c21c37 100644 --- a/openssh.spec +++ b/openssh.spec @@ -67,13 +67,14 @@ %endif # Do not forget to bump pam_ssh_agent_auth release if you rewind the main package release to 1 -%define openssh_rel 3 -%define pam_ssh_agent_rel 25 +%define openssh_rel 1 +%define openssh_ver 5.5p1 +%define pam_ssh_agent_rel 26 %define pam_ssh_agent_ver 0.9.2 Summary: An open source implementation of SSH protocol versions 1 and 2 Name: openssh -Version: 5.4p1 +Version: %{openssh_ver} Release: %{openssh_rel}%{?dist}%{?rescue_rel} URL: http://www.openssh.com/portable.html #URL1: http://pamsshagentauth.sourceforge.net @@ -93,7 +94,7 @@ Patch2: openssh-5.3p1-skip-initial.patch Patch4: openssh-5.2p1-vendor.patch Patch10: pam_ssh_agent_auth-0.9-build.patch Patch12: openssh-5.4p1-selinux.patch -Patch13: openssh-5.4p1-mls.patch +Patch13: openssh-5.5p1-mls.patch Patch16: openssh-5.3p1-audit.patch Patch18: openssh-5.4p1-pam_selinux.patch Patch24: openssh-4.3p1-fromto-remote.patch @@ -104,13 +105,12 @@ Patch38: openssh-4.3p2-askpass-grab-info.patch Patch44: openssh-5.2p1-allow-ip-opts.patch Patch49: openssh-4.3p2-gssapi-canohost.patch Patch62: openssh-5.1p1-scp-manpage.patch -Patch65: openssh-5.4p1-fips.patch +Patch65: openssh-5.5p1-fips.patch Patch69: openssh-5.3p1-selabel.patch Patch71: openssh-5.2p1-edns.patch Patch72: openssh-5.4p1-pka.patch Patch73: openssh-5.4p1-gsskex.patch Patch74: openssh-5.3p1-randclean.patch -Patch75: openssh-5.3p1-dso.patch Patch76: openssh-5.4p1-staterr.patch License: BSD @@ -264,7 +264,6 @@ popd %patch72 -p1 -b .pka %patch73 -p1 -b .gsskex %patch74 -p1 -b .randclean -%patch75 -p1 -b .dso %patch76 -p1 -b .staterr autoreconf @@ -531,6 +530,9 @@ fi %endif %changelog +* Fri Apr 16 2010 Jan F. Chadima - 5.5p1-1 + 0.9.2-26 +- Update to 5.5p1 + * Fri Mar 12 2010 Jan F. Chadima - 5.4p1-3 + 0.9.2-25 - repair configure script of pam_ssh_agent - repair error mesage in ssh-keygen diff --git a/sources b/sources index cf7b75c..7804bfb 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ +cc327297ee5a169c7997d403bf37c9b0 openssh-5.5p1-noacss.tar.bz2 b68f1c385d7885fbe2c3626bf77aa3d6 pam_ssh_agent_auth-0.9.2.tar.bz2 -96c95443133c2c5a459b95175ab7b555 openssh-5.4p1-noacss.tar.bz2