rpms/openssh/devel openssh-5.2p1-fips.patch, 1.1, 1.2 openssh-5.2p1-nss-keys.patch, 1.1, 1.2 openssh-5.2p1-redhat.patch, 1.1, 1.2 openssh-5.2p1-selinux.patch, 1.1, 1.2 openssh-5.2p1-vendor.patch, 1.1, 1.2

Jan F. Chadima jfch2222 at fedoraproject.org
Tue Mar 10 13:39:34 UTC 2009


Author: jfch2222

Update of /cvs/pkgs/rpms/openssh/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv6105

Modified Files:
	openssh-5.2p1-fips.patch openssh-5.2p1-nss-keys.patch 
	openssh-5.2p1-redhat.patch openssh-5.2p1-selinux.patch 
	openssh-5.2p1-vendor.patch 
Log Message:
Upgrade to version 5.2p1


openssh-5.2p1-fips.patch:

Index: openssh-5.2p1-fips.patch
===================================================================
RCS file: /cvs/pkgs/rpms/openssh/devel/openssh-5.2p1-fips.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- openssh-5.2p1-fips.patch	10 Mar 2009 11:54:43 -0000	1.1
+++ openssh-5.2p1-fips.patch	10 Mar 2009 13:39:03 -0000	1.2
@@ -1,6 +1,43 @@
+diff -up openssh-5.2p1/ssh-agent.c.fips openssh-5.2p1/ssh-agent.c
+--- openssh-5.2p1/ssh-agent.c.fips	2009-02-11 19:01:26.000000000 +0100
++++ openssh-5.2p1/ssh-agent.c	2009-02-12 13:46:18.000000000 +0100
+@@ -51,6 +51,8 @@
+ 
+ #include <openssl/evp.h>
+ #include <openssl/md5.h>
++#include <openssl/fips.h>
++#include <fipscheck.h>
+ #include "openbsd-compat/openssl-compat.h"
+ 
+ #include <errno.h>
+@@ -200,9 +202,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);
+ 
+@@ -1196,6 +1198,11 @@ main(int ac, char **av)
+ #endif
+ 
+ 	SSLeay_add_all_algorithms();
++        if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) {
++                fprintf(stderr,
++                    "FIPS integrity verification test failed.\n");
++                exit(3);
++        }
+ 
+ 	__progname = ssh_get_progname(av[0]);
+ 	init_rng();
 diff -up openssh-5.2p1/auth2-pubkey.c.fips openssh-5.2p1/auth2-pubkey.c
---- openssh-5.2p1/auth2-pubkey.c.fips	2009-03-10 03:51:55.047234449 +0100
-+++ openssh-5.2p1/auth2-pubkey.c	2009-03-10 03:51:56.174214480 +0100
+--- openssh-5.2p1/auth2-pubkey.c.fips	2009-02-11 19:01:25.000000000 +0100
++++ openssh-5.2p1/auth2-pubkey.c	2009-02-11 19:01:26.000000000 +0100
 @@ -33,6 +33,7 @@
  #include <stdio.h>
  #include <stdarg.h>
@@ -18,70 +55,179 @@
  			verbose("Found matching %s key: %s",
  			    key_type(found), fp);
  			xfree(fp);
-diff -up openssh-5.2p1/cipher.c.fips openssh-5.2p1/cipher.c
---- openssh-5.2p1/cipher.c.fips	2009-03-09 09:47:30.000000000 +0100
-+++ openssh-5.2p1/cipher.c	2009-03-10 03:51:56.297398184 +0100
-@@ -40,6 +40,7 @@
- #include <sys/types.h>
+diff -up openssh-5.2p1/ssh.c.fips openssh-5.2p1/ssh.c
+--- openssh-5.2p1/ssh.c.fips	2009-02-11 19:01:26.000000000 +0100
++++ openssh-5.2p1/ssh.c	2009-02-12 13:48:43.000000000 +0100
+@@ -71,6 +71,8 @@
  
- #include <openssl/md5.h>
+ #include <openssl/evp.h>
+ #include <openssl/err.h>
 +#include <openssl/fips.h>
++#include <fipscheck.h>
+ #include "openbsd-compat/openssl-compat.h"
+ #include "openbsd-compat/sys-queue.h"
  
- #include <string.h>
- #include <stdarg.h>
-@@ -93,6 +94,22 @@ struct Cipher {
- 	{ NULL,			SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL }
- };
+@@ -220,6 +222,10 @@ main(int ac, char **av)
+ 	sanitise_stdfd();
  
-+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 },
+ 	__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();
+ 
+ 	/*
+@@ -562,7 +568,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. */
+diff -up openssh-5.2p1/sshconnect2.c.fips openssh-5.2p1/sshconnect2.c
+--- openssh-5.2p1/sshconnect2.c.fips	2009-02-11 19:01:26.000000000 +0100
++++ openssh-5.2p1/sshconnect2.c	2009-02-11 19:01:26.000000000 +0100
+@@ -43,6 +43,8 @@
+ #include <vis.h>
+ #endif
+ 
++#include <openssl/fips.h>
 +
-+	{ "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 at 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 }
-+};
+ #include "openbsd-compat/sys-queue.h"
+ 
+ #include "xmalloc.h"
+@@ -113,6 +115,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]);
+@@ -128,7 +134,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;
+@@ -478,8 +488,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);
  
- 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;
+ 	/*
+diff -up openssh-5.2p1/Makefile.in.fips openssh-5.2p1/Makefile.in
+--- openssh-5.2p1/Makefile.in.fips	2009-02-11 19:01:26.000000000 +0100
++++ openssh-5.2p1/Makefile.in	2009-02-12 14:06:25.000000000 +0100
+@@ -134,28 +134,28 @@ 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 $(SSHDLIBS) -lfipscheck $(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
+-	$(LD) -o $@ ssh-agent.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
+-	$(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
++	$(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
+ 
+ ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
+-	$(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
++	$(LD) -o $@ ssh-keyscan.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.2p1/sshd.c.fips openssh-5.2p1/sshd.c
+--- openssh-5.2p1/sshd.c.fips	2009-02-11 19:01:25.000000000 +0100
++++ openssh-5.2p1/sshd.c	2009-02-12 13:51:51.000000000 +0100
+@@ -76,6 +76,8 @@
+ #include <openssl/bn.h>
+ #include <openssl/md5.h>
+ #include <openssl/rand.h>
++#include <openssl/fips.h>
++#include <fipscheck.h>
+ #include "openbsd-compat/openssl-compat.h"
+ 
+ #ifdef HAVE_SECUREWARE
+@@ -1261,6 +1263,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 */
+@@ -1413,8 +1421,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)
+@@ -2183,6 +2189,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]);
+@@ -2192,6 +2201,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.2p1/mac.c.fips openssh-5.2p1/mac.c
 --- openssh-5.2p1/mac.c.fips	2008-06-13 02:58:50.000000000 +0200
-+++ openssh-5.2p1/mac.c	2009-03-10 03:51:56.227222184 +0100
++++ openssh-5.2p1/mac.c	2009-02-11 19:01:26.000000000 +0100
 @@ -28,6 +28,7 @@
  #include <sys/types.h>
  
@@ -131,64 +277,63 @@
  
  	for (i = 0; macs[i].name; i++) {
  		if (strcmp(name, macs[i].name) == 0) {
-diff -up openssh-5.2p1/Makefile.in.fips openssh-5.2p1/Makefile.in
---- openssh-5.2p1/Makefile.in.fips	2009-03-10 03:51:55.910250677 +0100
-+++ openssh-5.2p1/Makefile.in	2009-03-10 03:51:56.222702935 +0100
-@@ -134,28 +134,28 @@ 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 $(SSHDLIBS) -lfipscheck $(LIBS)
- 
- scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o
- 	$(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+diff -up openssh-5.2p1/ssh-keygen.c.fips openssh-5.2p1/ssh-keygen.c
+--- openssh-5.2p1/ssh-keygen.c.fips	2009-02-11 19:01:26.000000000 +0100
++++ openssh-5.2p1/ssh-keygen.c	2009-02-12 13:46:00.000000000 +0100
+@@ -21,6 +21,8 @@
  
- 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)
+ #include <openssl/evp.h>
+ #include <openssl/pem.h>
++#include <openssl/fips.h>
++#include <fipscheck.h>
+ #include "openbsd-compat/openssl-compat.h"
  
- ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o
--	$(LD) -o $@ ssh-agent.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
-+	$(LD) -o $@ ssh-agent.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
+ #include <errno.h>
+@@ -537,7 +539,7 @@ do_fingerprint(struct passwd *pw)
+ 	enum fp_type fptype;
+ 	struct stat st;
  
- 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)
+-	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;
  
- ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o
--	$(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
-+	$(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
+ 	if (!have_identity)
+@@ -1125,6 +1127,12 @@ main(int argc, char **argv)
+ 	__progname = ssh_get_progname(argv[0]);
  
- ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
--	$(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
-+	$(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS)
+ 	SSLeay_add_all_algorithms();
++        if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) {
++                fprintf(stderr,
++                    "FIPS integrity verification test failed.\n");
++                exit(3);
++        }
++
+ 	log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
  
- 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.2p1/myproposal.h.fips openssh-5.2p1/myproposal.h
---- openssh-5.2p1/myproposal.h.fips	2009-01-28 06:33:31.000000000 +0100
-+++ openssh-5.2p1/myproposal.h	2009-03-10 03:51:56.257243733 +0100
-@@ -53,7 +53,11 @@
- 	"hmac-sha1-96,hmac-md5-96"
- #define	KEX_DEFAULT_COMP	"none,zlib at openssh.com,zlib"
- #define	KEX_DEFAULT_LANG	""
--
-+#define	KEX_FIPS_ENCRYPT \
-+	"aes128-cbc,3des-cbc," \
-+	"aes192-cbc,aes256-cbc,rijndael-cbc at lysator.liu.se"
-+#define	KEX_FIPS_MAC \
-+	"hmac-sha1"
+ 	init_rng();
+@@ -1506,14 +1514,15 @@ passphrase_again:
+ 	fclose(f);
  
- static char *myproposal[PROPOSAL_MAX] = {
- 	KEX_DEFAULT_KEX,
+ 	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 -up openssh-5.2p1/nsskeys.c.fips openssh-5.2p1/nsskeys.c
---- openssh-5.2p1/nsskeys.c.fips	2009-03-10 03:51:55.871242620 +0100
-+++ openssh-5.2p1/nsskeys.c	2009-03-10 03:51:56.251363837 +0100
+--- openssh-5.2p1/nsskeys.c.fips	2009-02-11 19:01:26.000000000 +0100
++++ openssh-5.2p1/nsskeys.c	2009-02-11 19:01:26.000000000 +0100
 @@ -183,8 +183,8 @@ nss_convert_pubkey(Key *k)
  			break;
  	}
@@ -200,9 +345,49 @@
  	xfree(p);
  
  	return 0;
+diff -up openssh-5.2p1/ssh-add.c.fips openssh-5.2p1/ssh-add.c
+--- openssh-5.2p1/ssh-add.c.fips	2009-02-11 19:01:26.000000000 +0100
++++ openssh-5.2p1/ssh-add.c	2009-02-12 13:46:31.000000000 +0100
+@@ -42,6 +42,8 @@
+ #include <sys/param.h>
+ 
+ #include <openssl/evp.h>
++#include <openssl/fips.h>
++#include <fipscheck.h>
+ #include "openbsd-compat/openssl-compat.h"
+ 
+ #ifdef HAVE_LIBNSS
+@@ -254,7 +256,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));
+@@ -463,11 +465,16 @@ main(int argc, char **argv)
+ 	sanitise_stdfd();
+ 
+ 	__progname = ssh_get_progname(argv[0]);
++	SSLeay_add_all_algorithms();
++	if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) {
++		fprintf(stderr,
++		    "FIPS integrity verification test failed.\n");
++		exit(3);
++	}
++
+ 	init_rng();
+ 	seed_rng();
+ 
+-	SSLeay_add_all_algorithms();
+-
+ 	/* At first, get a connection to the authentication agent. */
+ 	ac = ssh_get_authentication_connection();
+ 	if (ac == NULL) {
 diff -up openssh-5.2p1/openbsd-compat/bsd-arc4random.c.fips openssh-5.2p1/openbsd-compat/bsd-arc4random.c
 --- openssh-5.2p1/openbsd-compat/bsd-arc4random.c.fips	2008-06-04 02:54:00.000000000 +0200
-+++ openssh-5.2p1/openbsd-compat/bsd-arc4random.c	2009-03-10 03:51:56.255331659 +0100
++++ openssh-5.2p1/openbsd-compat/bsd-arc4random.c	2009-02-11 19:01:26.000000000 +0100
 @@ -39,6 +39,7 @@
  static int rc4_ready = 0;
  static RC4_KEY rc4;
@@ -244,163 +429,144 @@
  #endif /* !HAVE_ARC4RANDOM */
  
  #ifndef ARC4RANDOM_BUF
-diff -up openssh-5.2p1/ssh-add.c.fips openssh-5.2p1/ssh-add.c
---- openssh-5.2p1/ssh-add.c.fips	2009-03-10 03:51:55.928225121 +0100
-+++ openssh-5.2p1/ssh-add.c	2009-03-10 03:51:56.254252403 +0100
-@@ -42,6 +42,8 @@
- #include <sys/param.h>
+diff -up openssh-5.2p1/myproposal.h.fips openssh-5.2p1/myproposal.h
+--- openssh-5.2p1/myproposal.h.fips	2007-06-11 06:01:42.000000000 +0200
++++ openssh-5.2p1/myproposal.h	2009-02-11 19:01:26.000000000 +0100
+@@ -52,7 +52,11 @@
+ 	"hmac-sha1-96,hmac-md5-96"
+ #define	KEX_DEFAULT_COMP	"none,zlib at openssh.com,zlib"
+ #define	KEX_DEFAULT_LANG	""
+-
++#define	KEX_FIPS_ENCRYPT \
++	"aes128-cbc,3des-cbc," \
++	"aes192-cbc,aes256-cbc,rijndael-cbc at lysator.liu.se"
++#define	KEX_FIPS_MAC \
++	"hmac-sha1"
  
+ static char *myproposal[PROPOSAL_MAX] = {
+ 	KEX_DEFAULT_KEX,
+diff -up openssh-5.2p1/ssh-keysign.c.fips openssh-5.2p1/ssh-keysign.c
+--- openssh-5.2p1/ssh-keysign.c.fips	2006-09-01 07:38:37.000000000 +0200
++++ openssh-5.2p1/ssh-keysign.c	2009-02-12 13:44:41.000000000 +0100
+@@ -38,6 +38,8 @@
  #include <openssl/evp.h>
+ #include <openssl/rand.h>
+ #include <openssl/rsa.h>
 +#include <openssl/fips.h>
 +#include <fipscheck.h>
- #include "openbsd-compat/openssl-compat.h"
  
- #ifdef HAVE_LIBNSS
-@@ -254,7 +256,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));
-@@ -463,11 +465,16 @@ main(int argc, char **argv)
- 	sanitise_stdfd();
+ #include "xmalloc.h"
+ #include "log.h"
+@@ -175,6 +177,11 @@ main(int argc, char **argv)
  
- 	__progname = ssh_get_progname(argv[0]);
-+	SSLeay_add_all_algorithms();
-+	if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) {
-+		fprintf(stderr,
-+		    "FIPS integrity verification test failed.\n");
-+		exit(3);
-+	}
+ 	permanently_set_uid(pw);
+ 
++        SSLeay_add_all_algorithms();
++        if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) {
++                fatal("FIPS integrity verification test failed");
++        }
 +
  	init_rng();
  	seed_rng();
+ 	arc4random_stir();
+@@ -194,7 +201,6 @@ main(int argc, char **argv)
+ 	if (key_fd[0] == -1 && key_fd[1] == -1)
+ 		fatal("could not open any host key");
  
 -	SSLeay_add_all_algorithms();
--
- 	/* At first, get a connection to the authentication agent. */
- 	ac = ssh_get_authentication_connection();
- 	if (ac == NULL) {
-diff -up openssh-5.2p1/ssh-agent.c.fips openssh-5.2p1/ssh-agent.c
---- openssh-5.2p1/ssh-agent.c.fips	2009-03-10 03:51:55.846341085 +0100
-+++ openssh-5.2p1/ssh-agent.c	2009-03-10 03:51:56.171221623 +0100
-@@ -51,6 +51,8 @@
+ 	for (i = 0; i < 256; i++)
+ 		rnd[i] = arc4random();
+ 	RAND_seed(rnd, sizeof(rnd));
+diff -up openssh-5.2p1/cipher.c.fips openssh-5.2p1/cipher.c
+--- openssh-5.2p1/cipher.c.fips	2008-07-23 14:03:19.000000000 +0200
++++ openssh-5.2p1/cipher.c	2009-02-11 19:01:26.000000000 +0100
+@@ -40,6 +40,7 @@
+ #include <sys/types.h>
+ 
+ #include <openssl/md5.h>
++#include <openssl/fips.h>
+ 
+ #include <string.h>
+ #include <stdarg.h>
+@@ -91,6 +92,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 at 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
+@@ -133,7 +150,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;
+@@ -143,7 +160,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;
+@@ -187,7 +204,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;
+diff -up openssh-5.2p1/ssh-keyscan.c.fips openssh-5.2p1/ssh-keyscan.c
+--- openssh-5.2p1/ssh-keyscan.c.fips	2008-07-04 15:10:49.000000000 +0200
++++ openssh-5.2p1/ssh-keyscan.c	2009-02-12 13:44:21.000000000 +0100
+@@ -19,6 +19,8 @@
+ #include <arpa/inet.h>
  
- #include <openssl/evp.h>
- #include <openssl/md5.h>
+ #include <openssl/bn.h>
 +#include <openssl/fips.h>
 +#include <fipscheck.h>
- #include "openbsd-compat/openssl-compat.h"
  
+ #include <netdb.h>
  #include <errno.h>
-@@ -200,9 +202,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);
- 
-@@ -1196,6 +1198,11 @@ main(int ac, char **av)
- #endif
+@@ -730,6 +732,13 @@ main(int argc, char **argv)
+ 	extern char *optarg;
  
- 	SSLeay_add_all_algorithms();
+ 	__progname = ssh_get_progname(argv[0]);
++        SSLeay_add_all_algorithms();
 +        if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) {
 +                fprintf(stderr,
 +                    "FIPS integrity verification test failed.\n");
 +                exit(3);
 +        }
- 
- 	__progname = ssh_get_progname(av[0]);
- 	init_rng();
-diff -up openssh-5.2p1/ssh.c.fips openssh-5.2p1/ssh.c
---- openssh-5.2p1/ssh.c.fips	2009-03-10 03:51:55.906266464 +0100
-+++ openssh-5.2p1/ssh.c	2009-03-10 03:51:56.176206362 +0100
-@@ -71,6 +71,8 @@
- 
- #include <openssl/evp.h>
- #include <openssl/err.h>
-+#include <openssl/fips.h>
-+#include <fipscheck.h>
- #include "openbsd-compat/openssl-compat.h"
- #include "openbsd-compat/sys-queue.h"
- 
-@@ -220,6 +222,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();
- 
- 	/*
-@@ -550,7 +556,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. */
-diff -up openssh-5.2p1/sshconnect2.c.fips openssh-5.2p1/sshconnect2.c
---- openssh-5.2p1/sshconnect2.c.fips	2009-03-10 03:51:56.079247745 +0100
-+++ openssh-5.2p1/sshconnect2.c	2009-03-10 03:51:56.197416110 +0100
-@@ -44,6 +44,8 @@
- #include <vis.h>
- #endif
- 
-+#include <openssl/fips.h>
-+
- #include "openbsd-compat/sys-queue.h"
- 
- #include "xmalloc.h"
-@@ -115,6 +117,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]);
-@@ -130,7 +136,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;
-@@ -507,8 +517,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);
- 
- 	/*
+ 	init_rng();
+ 	seed_rng();
+ 	TAILQ_INIT(&tq);
 diff -up openssh-5.2p1/sshconnect.c.fips openssh-5.2p1/sshconnect.c
---- openssh-5.2p1/sshconnect.c.fips	2009-03-10 03:51:56.085211598 +0100
-+++ openssh-5.2p1/sshconnect.c	2009-03-10 03:51:56.315348971 +0100
+--- openssh-5.2p1/sshconnect.c.fips	2009-02-11 19:01:26.000000000 +0100
++++ openssh-5.2p1/sshconnect.c	2009-02-11 19:01:26.000000000 +0100
 @@ -40,6 +40,8 @@
  #include <unistd.h>
  #include <fcntl.h>
@@ -410,7 +576,7 @@
  #include "xmalloc.h"
  #include "key.h"
  #include "hostfile.h"
-@@ -761,6 +763,7 @@ check_host_key(char *hostname, struct so
+@@ -765,6 +767,7 @@ check_host_key(char *hostname, struct so
  			goto fail;
  		} else if (options.strict_host_key_checking == 2) {
  			char msg1[1024], msg2[1024];
@@ -418,7 +584,7 @@
  
  			if (show_other_keys(host, host_key))
  				snprintf(msg1, sizeof(msg1),
-@@ -769,8 +772,8 @@ check_host_key(char *hostname, struct so
+@@ -773,8 +776,8 @@ check_host_key(char *hostname, struct so
  			else
  				snprintf(msg1, sizeof(msg1), ".");
  			/* The default */
@@ -429,7 +595,7 @@
  			    SSH_FP_RANDOMART);
  			msg2[0] = '\0';
  			if (options.verify_host_key_dns) {
-@@ -786,10 +789,10 @@ check_host_key(char *hostname, struct so
+@@ -790,10 +793,10 @@ check_host_key(char *hostname, struct so
  			snprintf(msg, sizeof(msg),
  			    "The authenticity of host '%.200s (%s)' can't be "
  			    "established%s\n"
@@ -442,7 +608,7 @@
  			    options.visual_host_key ? "\n" : "",
  			    options.visual_host_key ? ra : "",
  			    msg2);
-@@ -1077,17 +1080,18 @@ show_key_from_file(const char *file, con
+@@ -1081,17 +1084,18 @@ show_key_from_file(const char *file, con
  	Key *found;
  	char *fp, *ra;
  	int line, ret;
@@ -465,7 +631,7 @@
  		xfree(ra);
  		xfree(fp);
  	}
-@@ -1133,8 +1137,9 @@ warn_changed_key(Key *host_key)
+@@ -1137,8 +1141,9 @@ warn_changed_key(Key *host_key)
  {
  	char *fp;
  	const char *type = key_type(host_key);
@@ -476,7 +642,7 @@
  
  	error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
  	error("@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @");
-@@ -1142,8 +1147,8 @@ warn_changed_key(Key *host_key)
+@@ -1146,8 +1151,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);
@@ -487,169 +653,3 @@
  	error("Please contact your system administrator.");
  
  	xfree(fp);
-diff -up openssh-5.2p1/sshd.c.fips openssh-5.2p1/sshd.c
---- openssh-5.2p1/sshd.c.fips	2009-03-10 03:51:55.512212775 +0100
-+++ openssh-5.2p1/sshd.c	2009-03-10 03:51:56.224238563 +0100
-@@ -76,6 +76,8 @@
- #include <openssl/bn.h>
- #include <openssl/md5.h>
- #include <openssl/rand.h>
-+#include <openssl/fips.h>
-+#include <fipscheck.h>
- #include "openbsd-compat/openssl-compat.h"
- 
- #ifdef HAVE_SECUREWARE
-@@ -1260,6 +1262,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 */
-@@ -1412,8 +1420,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)
-@@ -2182,6 +2188,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]);
-@@ -2191,6 +2200,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.2p1/ssh-keygen.c.fips openssh-5.2p1/ssh-keygen.c
---- openssh-5.2p1/ssh-keygen.c.fips	2009-03-10 03:51:55.948283636 +0100
-+++ openssh-5.2p1/ssh-keygen.c	2009-03-10 03:51:56.249239228 +0100
-@@ -21,6 +21,8 @@
- 
- #include <openssl/evp.h>
- #include <openssl/pem.h>
-+#include <openssl/fips.h>
-+#include <fipscheck.h>
- #include "openbsd-compat/openssl-compat.h"
- 
- #include <errno.h>
-@@ -537,7 +539,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)
-@@ -1125,6 +1127,12 @@ main(int argc, char **argv)
- 	__progname = ssh_get_progname(argv[0]);
- 
- 	SSLeay_add_all_algorithms();
-+        if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) {
-+                fprintf(stderr,
-+                    "FIPS integrity verification test failed.\n");
-+                exit(3);
-+        }
-+
- 	log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
- 
- 	init_rng();
-@@ -1506,14 +1514,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 -up openssh-5.2p1/ssh-keyscan.c.fips openssh-5.2p1/ssh-keyscan.c
---- openssh-5.2p1/ssh-keyscan.c.fips	2009-01-28 06:31:23.000000000 +0100
-+++ openssh-5.2p1/ssh-keyscan.c	2009-03-10 03:51:56.313291759 +0100
-@@ -19,6 +19,8 @@
- #include <arpa/inet.h>
- 
- #include <openssl/bn.h>
-+#include <openssl/fips.h>
-+#include <fipscheck.h>
- 
- #include <netdb.h>
- #include <errno.h>
-@@ -731,6 +733,13 @@ main(int argc, char **argv)
- 	extern char *optarg;
- 
- 	__progname = ssh_get_progname(argv[0]);
-+        SSLeay_add_all_algorithms();
-+        if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) {
-+                fprintf(stderr,
-+                    "FIPS integrity verification test failed.\n");
-+                exit(3);
-+        }
-+
- 	init_rng();
- 	seed_rng();
- 	TAILQ_INIT(&tq);
-diff -up openssh-5.2p1/ssh-keysign.c.fips openssh-5.2p1/ssh-keysign.c
---- openssh-5.2p1/ssh-keysign.c.fips	2006-09-01 07:38:37.000000000 +0200
-+++ openssh-5.2p1/ssh-keysign.c	2009-03-10 03:51:56.295222876 +0100
-@@ -38,6 +38,8 @@
- #include <openssl/evp.h>
- #include <openssl/rand.h>
- #include <openssl/rsa.h>
-+#include <openssl/fips.h>
-+#include <fipscheck.h>
- 
- #include "xmalloc.h"
- #include "log.h"
-@@ -175,6 +177,11 @@ main(int argc, char **argv)
- 
- 	permanently_set_uid(pw);
- 
-+        SSLeay_add_all_algorithms();
-+        if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) {
-+                fatal("FIPS integrity verification test failed");
-+        }
-+
- 	init_rng();
- 	seed_rng();
- 	arc4random_stir();
-@@ -194,7 +201,6 @@ main(int argc, char **argv)
- 	if (key_fd[0] == -1 && key_fd[1] == -1)
- 		fatal("could not open any host key");
- 
--	SSLeay_add_all_algorithms();
- 	for (i = 0; i < 256; i++)
- 		rnd[i] = arc4random();
- 	RAND_seed(rnd, sizeof(rnd));

openssh-5.2p1-nss-keys.patch:

Index: openssh-5.2p1-nss-keys.patch
===================================================================
RCS file: /cvs/pkgs/rpms/openssh/devel/openssh-5.2p1-nss-keys.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- openssh-5.2p1-nss-keys.patch	10 Mar 2009 11:54:43 -0000	1.1
+++ openssh-5.2p1-nss-keys.patch	10 Mar 2009 13:39:03 -0000	1.2
@@ -1,55 +1,289 @@
-diff -up openssh-5.2p1/authfd.c.nss-keys openssh-5.2p1/authfd.c
---- openssh-5.2p1/authfd.c.nss-keys	2006-09-01 07:38:36.000000000 +0200
-+++ openssh-5.2p1/authfd.c	2009-03-10 03:51:55.866208145 +0100
-@@ -626,6 +626,45 @@ ssh_update_card(AuthenticationConnection
- 	return decode_reply(type);
+diff -up openssh-5.2p1/key.c.nss-keys openssh-5.2p1/key.c
+--- openssh-5.2p1/key.c.nss-keys	2008-07-11 09:35:09.000000000 +0200
++++ openssh-5.2p1/key.c	2008-11-18 19:11:41.000000000 +0100
+@@ -96,6 +96,54 @@ key_new(int type)
+ 	return k;
  }
  
-+int
-+ssh_update_nss_key(AuthenticationConnection *auth, int add,
-+    const char *tokenname, const char *keyname,
-+    const char *pass, u_int life, u_int confirm)
++#ifdef HAVE_LIBNSS
++Key *
++key_new_nss(int type)
 +{
-+	Buffer msg;
-+	int type, constrained = (life || confirm);
++	Key *k = key_new(type);
 +
-+	if (add) {
-+		type = constrained ?
-+		    SSH_AGENTC_ADD_NSS_KEY_CONSTRAINED :
-+		    SSH_AGENTC_ADD_NSS_KEY;
-+	} else
-+		type = SSH_AGENTC_REMOVE_NSS_KEY;
++	k->nss = xcalloc(1, sizeof(*k->nss));
++	k->flags = KEY_FLAG_EXT | KEY_FLAG_NSS;
 +
-+	buffer_init(&msg);
-+	buffer_put_char(&msg, type);
-+	buffer_put_cstring(&msg, tokenname);
-+	buffer_put_cstring(&msg, keyname);
-+	buffer_put_cstring(&msg, pass);
++	return k;
++}
 +
-+	if (constrained) {
-+		if (life != 0) {
-+			buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME);
-+			buffer_put_int(&msg, life);
++Key *
++key_new_nss_copy(int type, const Key *c)
++{
++	Key *k = key_new_nss(type);
++
++	switch (k->type) {
++		case KEY_RSA:
++			if ((BN_copy(k->rsa->n, c->rsa->n) == NULL) ||
++				(BN_copy(k->rsa->e, c->rsa->e) == NULL))
++				fatal("key_new_nss_copy: BN_copy failed");
++			break;
++		case KEY_DSA:
++			if ((BN_copy(k->dsa->p, c->rsa->p) == NULL) ||
++				(BN_copy(k->dsa->q, c->dsa->q) == NULL) ||
++				(BN_copy(k->dsa->g, c->dsa->g) == NULL) ||
++				(BN_copy(k->dsa->pub_key, c->dsa->pub_key) == NULL))
++				fatal("key_new_nss_copy: BN_copy failed");
++			break;
++	}
++		
++	k->nss->privk = SECKEY_CopyPrivateKey(c->nss->privk);
++	if (k->nss->privk == NULL)
++		fatal("key_new_nss_copy: SECKEY_CopyPrivateKey failed");
++
++	k->nss->pubk = SECKEY_CopyPublicKey(c->nss->pubk);
++	if (k->nss->pubk == NULL)
++		fatal("key_new_nss_copy: SECKEY_CopyPublicKey failed");
++	
++	if (c->nss->privk->wincx)
++		k->nss->privk->wincx = xstrdup(c->nss->privk->wincx);
++
++	return k;
++}
++#endif
++
++
+ Key *
+ key_new_private(int type)
+ {
+@@ -151,6 +199,19 @@ key_free(Key *k)
+ 		fatal("key_free: bad key type %d", k->type);
+ 		break;
+ 	}
++#ifdef HAVE_LIBNSS
++	if (k->flags & KEY_FLAG_NSS) {
++		if (k->nss->privk != NULL && k->nss->privk->wincx != NULL) {
++			memset(k->nss->privk->wincx, 0,
++				strlen(k->nss->privk->wincx));
++			xfree(k->nss->privk->wincx);
++			k->nss->privk->wincx = NULL;
 +		}
-+		if (confirm != 0)
-+			buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_CONFIRM);
++		SECKEY_DestroyPrivateKey(k->nss->privk);
++		SECKEY_DestroyPublicKey(k->nss->pubk);
++		xfree(k->nss);
 +	}
++#endif
+ 	xfree(k);
+ }
+ 
+diff -up openssh-5.2p1/ssh-dss.c.nss-keys openssh-5.2p1/ssh-dss.c
+--- openssh-5.2p1/ssh-dss.c.nss-keys	2006-11-07 13:14:42.000000000 +0100
++++ openssh-5.2p1/ssh-dss.c	2008-11-18 19:11:41.000000000 +0100
+@@ -39,6 +39,10 @@
+ #include "log.h"
+ #include "key.h"
+ 
++#ifdef HAVE_LIBNSS
++#include <cryptohi.h>
++#endif
 +
-+	if (ssh_request_reply(auth, &msg, &msg) == 0) {
-+		buffer_free(&msg);
-+		return 0;
+ #define INTBLOB_LEN	20
+ #define SIGBLOB_LEN	(2*INTBLOB_LEN)
+ 
+@@ -57,6 +61,34 @@ ssh_dss_sign(const Key *key, u_char **si
+ 		error("ssh_dss_sign: no DSA key");
+ 		return -1;
+ 	}
++#ifdef HAVE_LIBNSS
++	if (key->flags & KEY_FLAG_NSS) {
++		SECItem sigitem;
++		SECItem *rawsig;
++
++		memset(&sigitem, 0, sizeof(sigitem));
++		if (SEC_SignData(&sigitem, (u_char *)data, datalen, key->nss->privk,
++			SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) != SECSuccess) {
++			error("ssh_dss_sign: sign failed");
++			return -1;
++		}
++		
++		if ((rawsig=DSAU_DecodeDerSig(&sigitem)) == NULL) {
++			error("ssh_dss_sign: der decode failed");
++			SECITEM_ZfreeItem(&sigitem, PR_FALSE);
++			return -1;
++		}
++		SECITEM_ZfreeItem(&sigitem, PR_FALSE);
++		if (rawsig->len != SIGBLOB_LEN) {
++			error("ssh_dss_sign: unsupported signature length %d",
++				rawsig->len);
++			SECITEM_ZfreeItem(rawsig, PR_TRUE);
++			return -1;
++		}
++		memcpy(sigblob, rawsig->data, SIGBLOB_LEN);
++		SECITEM_ZfreeItem(rawsig, PR_TRUE);
++	} else {
++#endif
+ 	EVP_DigestInit(&md, evp_md);
+ 	EVP_DigestUpdate(&md, data, datalen);
+ 	EVP_DigestFinal(&md, digest, &dlen);
+@@ -80,7 +112,9 @@ ssh_dss_sign(const Key *key, u_char **si
+ 	BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
+ 	BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
+ 	DSA_SIG_free(sig);
+-
++#ifdef HAVE_LIBNSS
 +	}
-+	type = buffer_get_char(&msg);
-+	buffer_free(&msg);
-+	return decode_reply(type);
++#endif
+ 	if (datafellows & SSH_BUG_SIGBLOB) {
+ 		if (lenp != NULL)
+ 			*lenp = SIGBLOB_LEN;
+diff -up openssh-5.2p1/ssh-agent.c.nss-keys openssh-5.2p1/ssh-agent.c
+--- openssh-5.2p1/ssh-agent.c.nss-keys	2008-07-04 15:10:49.000000000 +0200
++++ openssh-5.2p1/ssh-agent.c	2008-11-18 19:11:41.000000000 +0100
+@@ -80,6 +80,10 @@
+ #include "scard.h"
+ #endif
+ 
++#ifdef HAVE_LIBNSS
++#include "nsskeys.h"
++#endif
++
+ #if defined(HAVE_SYS_PRCTL_H)
+ #include <sys/prctl.h>	/* For prctl() and PR_SET_DUMPABLE */
+ #endif
+@@ -714,6 +718,114 @@ send:
+ }
+ #endif /* SMARTCARD */
+ 
++#ifdef HAVE_LIBNSS
++static void
++process_add_nss_key (SocketEntry *e)
++{
++	char *tokenname = NULL, *keyname = NULL, *password = NULL;
++	int i, version, success = 0, death = 0, confirm = 0;
++	Key **keys, *k;
++	Identity *id;
++	Idtab *tab;
++
++	tokenname = buffer_get_string(&e->request, NULL);
++	keyname = buffer_get_string(&e->request, NULL);
++	password = buffer_get_string(&e->request, NULL);
++
++	while (buffer_len(&e->request)) {
++		switch (buffer_get_char(&e->request)) {
++		case SSH_AGENT_CONSTRAIN_LIFETIME:
++			death = time(NULL) + buffer_get_int(&e->request);
++			break;
++		case SSH_AGENT_CONSTRAIN_CONFIRM:
++			confirm = 1;
++			break;
++		default:
++			break;
++		}
++	}
++	if (lifetime && !death)
++		death = time(NULL) + lifetime;
++
++	keys = nss_get_keys(tokenname, keyname, password);
++	/* password is owned by keys[0] now */
++	xfree(tokenname);
++	xfree(keyname);
++
++	if (keys == NULL) {
++		memset(password, 0, strlen(password));
++		xfree(password);
++		error("nss_get_keys failed");
++		goto send;
++	}
++	for (i = 0; keys[i] != NULL; i++) {
++		k = keys[i];
++		version = k->type == KEY_RSA1 ? 1 : 2;
++		tab = idtab_lookup(version);
++		if (lookup_identity(k, version) == NULL) {
++			id = xmalloc(sizeof(Identity));
++			id->key = k;
++			id->comment = nss_get_key_label(k);
++			id->death = death;
++			id->confirm = confirm;
++			TAILQ_INSERT_TAIL(&tab->idlist, id, next);
++			tab->nentries++;
++			success = 1;
++		} else {
++			key_free(k);
++		}
++		keys[i] = NULL;
++	}
++	xfree(keys);
++send:
++	buffer_put_int(&e->output, 1);
++	buffer_put_char(&e->output,
++	    success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
 +}
 +
- /*
-  * Removes all identities from the agent.  This call is not meant to be used
-  * by normal applications.
++static void
++process_remove_nss_key(SocketEntry *e)
++{
++	char *tokenname = NULL, *keyname = NULL, *password = NULL;
++	int i, version, success = 0;
++	Key **keys, *k = NULL;
++	Identity *id;
++	Idtab *tab;
++
++	tokenname = buffer_get_string(&e->request, NULL);
++	keyname = buffer_get_string(&e->request, NULL);
++	password = buffer_get_string(&e->request, NULL);
++
++	keys = nss_get_keys(tokenname, keyname, password);
++	xfree(tokenname);
++	xfree(keyname);
++	xfree(password);
++
++	if (keys == NULL || keys[0] == NULL) {
++		error("nss_get_keys failed");
++		goto send;
++	}
++	for (i = 0; keys[i] != NULL; i++) {
++		k = keys[i];
++		version = k->type == KEY_RSA1 ? 1 : 2;
++		if ((id = lookup_identity(k, version)) != NULL) {
++			tab = idtab_lookup(version);
++			TAILQ_REMOVE(&tab->idlist, id, next);
++			tab->nentries--;
++			free_identity(id);
++			success = 1;
++		}
++		key_free(k);
++		keys[i] = NULL;
++	}
++	xfree(keys);
++send:
++	buffer_put_int(&e->output, 1);
++	buffer_put_char(&e->output,
++	    success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
++}
++#endif /* HAVE_LIBNSS */
++
+ /* dispatch incoming messages */
+ 
+ static void
+@@ -806,6 +918,15 @@ process_message(SocketEntry *e)
+ 		process_remove_smartcard_key(e);
+ 		break;
+ #endif /* SMARTCARD */
++#ifdef HAVE_LIBNSS
++	case SSH_AGENTC_ADD_NSS_KEY:
++	case SSH_AGENTC_ADD_NSS_KEY_CONSTRAINED:
++		process_add_nss_key(e);
++		break;
++	case SSH_AGENTC_REMOVE_NSS_KEY:
++		process_remove_nss_key(e);
++		break;
++#endif /* SMARTCARD */
+ 	default:
+ 		/* Unknown message.  Respond with failure. */
+ 		error("Unknown message %d", type);
 diff -up openssh-5.2p1/authfd.h.nss-keys openssh-5.2p1/authfd.h
 --- openssh-5.2p1/authfd.h.nss-keys	2006-08-05 04:39:39.000000000 +0200
-+++ openssh-5.2p1/authfd.h	2009-03-10 03:51:55.847449129 +0100
++++ openssh-5.2p1/authfd.h	2008-11-18 19:11:41.000000000 +0100
 @@ -49,6 +49,12 @@
  #define SSH2_AGENTC_ADD_ID_CONSTRAINED		25
  #define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
@@ -73,9 +307,9 @@
  int
  ssh_decrypt_challenge(AuthenticationConnection *, Key *, BIGNUM *, u_char[16],
 diff -up openssh-5.2p1/configure.ac.nss-keys openssh-5.2p1/configure.ac
---- openssh-5.2p1/configure.ac.nss-keys	2009-03-10 03:51:55.285821039 +0100
-+++ openssh-5.2p1/configure.ac	2009-03-10 03:51:55.850215090 +0100
-@@ -3462,6 +3462,20 @@ AC_ARG_WITH(kerberos5,
+--- openssh-5.2p1/configure.ac.nss-keys	2008-11-18 19:11:41.000000000 +0100
++++ openssh-5.2p1/configure.ac	2008-11-18 19:12:38.000000000 +0100
+@@ -3436,6 +3436,20 @@ AC_ARG_WITH(kerberos5,
  	]
  )
  
@@ -96,7 +330,7 @@
  # Looking for programs, paths and files
  
  PRIVSEP_PATH=/var/empty
-@@ -4189,6 +4203,7 @@ echo "              TCP Wrappers support
+@@ -4163,6 +4177,7 @@ echo "              TCP Wrappers support
  echo "              MD5 password support: $MD5_MSG"
  echo "                   libedit support: $LIBEDIT_MSG"
  echo "  Solaris process contract support: $SPC_MSG"
@@ -104,187 +338,110 @@
  echo "       IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
  echo "           Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
  echo "                  BSD Auth support: $BSD_AUTH_MSG"
-diff -up openssh-5.2p1/key.c.nss-keys openssh-5.2p1/key.c
---- openssh-5.2p1/key.c.nss-keys	2008-11-03 09:24:17.000000000 +0100
-+++ openssh-5.2p1/key.c	2009-03-10 03:51:55.840226575 +0100
-@@ -96,6 +96,54 @@ key_new(int type)
- 	return k;
- }
- 
-+#ifdef HAVE_LIBNSS
-+Key *
-+key_new_nss(int type)
-+{
-+	Key *k = key_new(type);
+diff -up /dev/null openssh-5.2p1/README.nss
+--- /dev/null	2008-11-17 17:51:52.160001870 +0100
++++ openssh-5.2p1/README.nss	2008-11-18 19:11:41.000000000 +0100
+@@ -0,0 +1,36 @@
++How to use NSS tokens with OpenSSH?
 +
-+	k->nss = xcalloc(1, sizeof(*k->nss));
-+	k->flags = KEY_FLAG_EXT | KEY_FLAG_NSS;
++This version of OpenSSH contains experimental support for authentication using
++keys stored in tokens stored in NSS database. This for example includes any
++PKCS#11 tokens which are installed in your NSS database.
 +
-+	return k;
-+}
++As the code is experimental and preliminary only SSH protocol 2 is supported.
++The NSS certificate and token databases are looked for in the ~/.ssh
++directory or in a directory specified by environment variable NSS_DB_PATH.
 +
-+Key *
-+key_new_nss_copy(int type, const Key *c)
-+{
-+	Key *k = key_new_nss(type);
++Common operations:
 +
-+	switch (k->type) {
-+		case KEY_RSA:
-+			if ((BN_copy(k->rsa->n, c->rsa->n) == NULL) ||
-+				(BN_copy(k->rsa->e, c->rsa->e) == NULL))
-+				fatal("key_new_nss_copy: BN_copy failed");
-+			break;
-+		case KEY_DSA:
-+			if ((BN_copy(k->dsa->p, c->rsa->p) == NULL) ||
-+				(BN_copy(k->dsa->q, c->dsa->q) == NULL) ||
-+				(BN_copy(k->dsa->g, c->dsa->g) == NULL) ||
-+				(BN_copy(k->dsa->pub_key, c->dsa->pub_key) == NULL))
-+				fatal("key_new_nss_copy: BN_copy failed");
-+			break;
-+	}
-+		
-+	k->nss->privk = SECKEY_CopyPrivateKey(c->nss->privk);
-+	if (k->nss->privk == NULL)
-+		fatal("key_new_nss_copy: SECKEY_CopyPrivateKey failed");
++(1) tell the ssh client to use the NSS keys:
 +
-+	k->nss->pubk = SECKEY_CopyPublicKey(c->nss->pubk);
-+	if (k->nss->pubk == NULL)
-+		fatal("key_new_nss_copy: SECKEY_CopyPublicKey failed");
++	$ ssh -o 'UseNSS yes' otherhost
 +	
-+	if (c->nss->privk->wincx)
-+		k->nss->privk->wincx = xstrdup(c->nss->privk->wincx);
++	if you want to use a specific token:
++	
++	$ ssh -o 'UseNSS yes' -o 'NSS Token My PKCS11 Token' otherhost
++
++(2) or tell the agent to use the NSS keys:
++
++	$ ssh-add -n
++	
++	if you want to use a specific token:
++	
++	$ ssh-add -n -T 'My PKCS11 Token'
++
++(3) extract the public key from token so it can be added to the
++server:
++
++	$ ssh-keygen -n
++	
++	if you want to use a specific token and/or key:
++	
++	$ ssh-keygen -n -D 'My PKCS11 Token' 'My Key ID'
+diff -up openssh-5.2p1/authfd.c.nss-keys openssh-5.2p1/authfd.c
+--- openssh-5.2p1/authfd.c.nss-keys	2006-09-01 07:38:36.000000000 +0200
++++ openssh-5.2p1/authfd.c	2008-11-18 19:11:41.000000000 +0100
+@@ -626,6 +626,45 @@ ssh_update_card(AuthenticationConnection
+ 	return decode_reply(type);
+ }
+ 
++int
++ssh_update_nss_key(AuthenticationConnection *auth, int add,
++    const char *tokenname, const char *keyname,
++    const char *pass, u_int life, u_int confirm)
++{
++	Buffer msg;
++	int type, constrained = (life || confirm);
 +
-+	return k;
-+}
-+#endif
++	if (add) {
++		type = constrained ?
++		    SSH_AGENTC_ADD_NSS_KEY_CONSTRAINED :
++		    SSH_AGENTC_ADD_NSS_KEY;
++	} else
++		type = SSH_AGENTC_REMOVE_NSS_KEY;
 +
++	buffer_init(&msg);
++	buffer_put_char(&msg, type);
++	buffer_put_cstring(&msg, tokenname);
++	buffer_put_cstring(&msg, keyname);
++	buffer_put_cstring(&msg, pass);
 +
- Key *
- key_new_private(int type)
- {
-@@ -151,6 +199,19 @@ key_free(Key *k)
- 		fatal("key_free: bad key type %d", k->type);
- 		break;
- 	}
-+#ifdef HAVE_LIBNSS
-+	if (k->flags & KEY_FLAG_NSS) {
-+		if (k->nss->privk != NULL && k->nss->privk->wincx != NULL) {
-+			memset(k->nss->privk->wincx, 0,
-+				strlen(k->nss->privk->wincx));
-+			xfree(k->nss->privk->wincx);
-+			k->nss->privk->wincx = NULL;
++	if (constrained) {
++		if (life != 0) {
++			buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME);
++			buffer_put_int(&msg, life);
 +		}
-+		SECKEY_DestroyPrivateKey(k->nss->privk);
-+		SECKEY_DestroyPublicKey(k->nss->pubk);
-+		xfree(k->nss);
++		if (confirm != 0)
++			buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_CONFIRM);
 +	}
-+#endif
- 	xfree(k);
- }
- 
-diff -up openssh-5.2p1/key.h.nss-keys openssh-5.2p1/key.h
---- openssh-5.2p1/key.h.nss-keys	2008-06-12 20:40:35.000000000 +0200
-+++ openssh-5.2p1/key.h	2009-03-10 03:51:55.925279322 +0100
-@@ -29,11 +29,17 @@
- #include <openssl/rsa.h>
- #include <openssl/dsa.h>
- 
-+#ifdef HAVE_LIBNSS
-+#include <nss.h>
-+#include <keyhi.h>
-+#endif
 +
- typedef struct Key Key;
- enum types {
- 	KEY_RSA1,
- 	KEY_RSA,
- 	KEY_DSA,
-+	KEY_NSS,
- 	KEY_UNSPEC
- };
- enum fp_type {
-@@ -48,16 +54,30 @@ enum fp_rep {
- 
- /* key is stored in external hardware */
- #define KEY_FLAG_EXT		0x0001
-+#define KEY_FLAG_NSS		0x0002
++	if (ssh_request_reply(auth, &msg, &msg) == 0) {
++		buffer_free(&msg);
++		return 0;
++	}
++	type = buffer_get_char(&msg);
++	buffer_free(&msg);
++	return decode_reply(type);
++}
 +
-+#ifdef HAVE_LIBNSS
-+typedef struct NSSKey NSSKey;
-+struct NSSKey {
-+	SECKEYPrivateKey *privk;
-+	SECKEYPublicKey *pubk;
-+};
-+#endif
- 
- struct Key {
- 	int	 type;
- 	int	 flags;
- 	RSA	*rsa;
- 	DSA	*dsa;
-+#ifdef HAVE_LIBNSS
-+	NSSKey  *nss;
-+#endif
- };
- 
- Key		*key_new(int);
- Key		*key_new_private(int);
-+Key 		*key_new_nss(int);
-+Key		*key_new_nss_copy(int, const Key *);
- void		 key_free(Key *);
- Key		*key_demote(const Key *);
- int		 key_equal(const Key *, const Key *);
-diff -up openssh-5.2p1/Makefile.in.nss-keys openssh-5.2p1/Makefile.in
---- openssh-5.2p1/Makefile.in.nss-keys	2008-11-05 06:20:46.000000000 +0100
-+++ openssh-5.2p1/Makefile.in	2009-03-10 03:51:56.222702935 +0100
-@@ -71,7 +71,7 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o b
- 	atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \
- 	monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \
- 	kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \
--	entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o
-+	entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o nsskeys.o
- 
- SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
- 	sshconnect.o sshconnect1.o sshconnect2.o mux.o
-@@ -134,28 +134,28 @@ 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 $(SSHDLIBS) -lfipscheck $(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
--	$(LD) -o $@ ssh-agent.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
--	$(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
-+	$(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat -lfipscheck $(LIBS)
- 
- ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
--	$(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
-+	$(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lfipscheck $(LIBS)
+ /*
+  * Removes all identities from the agent.  This call is not meant to be used
+  * by normal applications.
+diff -up openssh-5.2p1/readconf.h.nss-keys openssh-5.2p1/readconf.h
+--- openssh-5.2p1/readconf.h.nss-keys	2008-06-29 16:04:03.000000000 +0200
++++ openssh-5.2p1/readconf.h	2008-11-18 19:11:41.000000000 +0100
+@@ -84,6 +84,8 @@ typedef struct {
+ 	char   *preferred_authentications;
+ 	char   *bind_address;	/* local socket address for connection to sshd */
+ 	char   *smartcard_device; /* Smartcard reader device */
++	int     use_nss;        /* Use NSS library for keys */
++	char   *nss_token;      /* Look for NSS keys on token */
+ 	int	verify_host_key_dns;	/* Verify host key using DNS */
  
- 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)
+ 	int     num_identity_files;	/* Number of files for RSA/DSA identities. */
 diff -up /dev/null openssh-5.2p1/nsskeys.c
---- /dev/null	2009-03-09 14:26:59.819020596 +0100
-+++ openssh-5.2p1/nsskeys.c	2009-03-10 03:51:56.251363837 +0100
+--- /dev/null	2008-11-17 17:51:52.160001870 +0100
++++ openssh-5.2p1/nsskeys.c	2008-11-18 19:11:41.000000000 +0100
 @@ -0,0 +1,327 @@
 +/*
 + * Copyright (c) 2001 Markus Friedl.  All rights reserved.
@@ -471,8 +628,8 @@
 +			break;
 +	}
 +
-+	p = key_fingerprint(k, SSH_FP_SHA1, SSH_FP_HEX);
-+	debug("SHA1 fingerprint %u %s", key_size(k), p);
++	p = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
++	debug("fingerprint %u %s", key_size(k), p);
 +	xfree(p);
 +
 +	return 0;
@@ -613,9 +770,63 @@
 +}
 +
 +#endif /* HAVE_LIBNSS */
+diff -up openssh-5.2p1/ssh.c.nss-keys openssh-5.2p1/ssh.c
+--- openssh-5.2p1/ssh.c.nss-keys	2008-07-04 04:53:50.000000000 +0200
++++ openssh-5.2p1/ssh.c	2008-11-18 19:11:41.000000000 +0100
+@@ -104,6 +104,9 @@
+ #ifdef SMARTCARD
+ #include "scard.h"
+ #endif
++#ifdef HAVE_LIBNSS
++#include "nsskeys.h"
++#endif
+ 
+ extern char *__progname;
+ 
+@@ -1235,9 +1238,11 @@ load_public_identity_files(void)
+ 	int i = 0;
+ 	Key *public;
+ 	struct passwd *pw;
+-#ifdef SMARTCARD
++#if defined(SMARTCARD) || defined(HAVE_LIBNSS)
+ 	Key **keys;
++#endif
+ 
++#ifdef SMARTCARD
+ 	if (options.smartcard_device != NULL &&
+ 	    options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
+ 	    (keys = sc_get_keys(options.smartcard_device, NULL)) != NULL) {
+@@ -1260,6 +1265,27 @@ load_public_identity_files(void)
+ 		xfree(keys);
+ 	}
+ #endif /* SMARTCARD */
++#ifdef HAVE_LIBNSS
++	if (options.use_nss &&
++	    options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
++	    (keys = nss_get_keys(options.nss_token, NULL, NULL)) != NULL) {
++		int count;
++		for (count = 0; keys[count] != NULL; count++) {
++			memmove(&options.identity_files[1], &options.identity_files[0],
++			    sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1));
++			memmove(&options.identity_keys[1], &options.identity_keys[0],
++			    sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1));
++			options.num_identity_files++;
++			options.identity_keys[0] = keys[count];
++			options.identity_files[0] = nss_get_key_label(keys[count]);
++		}
++		if (options.num_identity_files > SSH_MAX_IDENTITY_FILES)
++			options.num_identity_files = SSH_MAX_IDENTITY_FILES;
++		i += count;
++		xfree(keys);
++	}
++#endif /* HAVE_LIBNSS */
++
+ 	if ((pw = getpwuid(original_real_uid)) == NULL)
+ 		fatal("load_public_identity_files: getpwuid failed");
+ 	pwname = xstrdup(pw->pw_name);
 diff -up /dev/null openssh-5.2p1/nsskeys.h
---- /dev/null	2009-03-09 14:26:59.819020596 +0100
-+++ openssh-5.2p1/nsskeys.h	2009-03-10 03:51:55.908243644 +0100
+--- /dev/null	2008-11-17 17:51:52.160001870 +0100
++++ openssh-5.2p1/nsskeys.h	2008-11-18 19:11:41.000000000 +0100
 @@ -0,0 +1,39 @@
 +/*
 + * Copyright (c) 2001 Markus Friedl.  All rights reserved.
@@ -656,85 +867,75 @@
 +
 +#endif
 +#endif
-diff -up openssh-5.2p1/readconf.c.nss-keys openssh-5.2p1/readconf.c
---- openssh-5.2p1/readconf.c.nss-keys	2009-02-14 06:28:21.000000000 +0100
-+++ openssh-5.2p1/readconf.c	2009-03-10 03:51:55.950217925 +0100
-@@ -124,6 +124,7 @@ typedef enum {
- 	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
- 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
- 	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
-+	oUseNSS, oNSSToken,
- 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
- 	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
- 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
-@@ -210,6 +211,13 @@ static struct {
- #else
- 	{ "smartcarddevice", oUnsupported },
- #endif
+diff -up openssh-5.2p1/Makefile.in.nss-keys openssh-5.2p1/Makefile.in
+--- openssh-5.2p1/Makefile.in.nss-keys	2008-07-08 16:21:12.000000000 +0200
++++ openssh-5.2p1/Makefile.in	2008-11-18 19:11:41.000000000 +0100
+@@ -71,7 +71,7 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o b
+ 	atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \
+ 	monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \
+ 	kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \
+-	entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o
++	entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o nsskeys.o
+ 
+ SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
+ 	sshconnect.o sshconnect1.o sshconnect2.o mux.o
+diff -up openssh-5.2p1/key.h.nss-keys openssh-5.2p1/key.h
+--- openssh-5.2p1/key.h.nss-keys	2008-06-12 20:40:35.000000000 +0200
++++ openssh-5.2p1/key.h	2008-11-18 19:11:41.000000000 +0100
+@@ -29,11 +29,17 @@
+ #include <openssl/rsa.h>
+ #include <openssl/dsa.h>
+ 
 +#ifdef HAVE_LIBNSS
-+	{ "usenss", oUseNSS },
-+	{ "nsstoken", oNSSToken },
-+#else
-+	{ "usenss", oUnsupported },
-+	{ "nsstoken", oNSSToken },
++#include <nss.h>
++#include <keyhi.h>
 +#endif
- 	{ "clearallforwardings", oClearAllForwardings },
- 	{ "enablesshkeysign", oEnableSSHKeysign },
- 	{ "verifyhostkeydns", oVerifyHostKeyDNS },
-@@ -612,6 +620,14 @@ parse_string:
- 		charptr = &options->smartcard_device;
- 		goto parse_string;
- 
-+	case oUseNSS:
-+		intptr = &options->use_nss;
-+		goto parse_flag;
-+
-+	case oNSSToken:
-+		charptr = &options->nss_token;
-+		goto parse_command;
 +
- 	case oProxyCommand:
- 		charptr = &options->proxy_command;
- parse_command:
-@@ -1047,6 +1063,8 @@ initialize_options(Options * options)
- 	options->preferred_authentications = NULL;
- 	options->bind_address = NULL;
- 	options->smartcard_device = NULL;
-+	options->use_nss = -1;
-+	options->nss_token = NULL;
- 	options->enable_ssh_keysign = - 1;
- 	options->no_host_authentication_for_localhost = - 1;
- 	options->identities_only = - 1;
-@@ -1177,6 +1195,8 @@ fill_default_options(Options * options)
- 		options->no_host_authentication_for_localhost = 0;
- 	if (options->identities_only == -1)
- 		options->identities_only = 0;
-+	if (options->use_nss == -1)
-+		options->use_nss = 0;
- 	if (options->enable_ssh_keysign == -1)
- 		options->enable_ssh_keysign = 0;
- 	if (options->rekey_limit == -1)
-diff -up openssh-5.2p1/readconf.h.nss-keys openssh-5.2p1/readconf.h
---- openssh-5.2p1/readconf.h.nss-keys	2009-02-14 06:28:21.000000000 +0100
-+++ openssh-5.2p1/readconf.h	2009-03-10 03:51:55.868252768 +0100
-@@ -85,6 +85,8 @@ typedef struct {
- 	char   *preferred_authentications;
- 	char   *bind_address;	/* local socket address for connection to sshd */
- 	char   *smartcard_device; /* Smartcard reader device */
-+	int     use_nss;        /* Use NSS library for keys */
-+	char   *nss_token;      /* Look for NSS keys on token */
- 	int	verify_host_key_dns;	/* Verify host key using DNS */
+ typedef struct Key Key;
+ enum types {
+ 	KEY_RSA1,
+ 	KEY_RSA,
+ 	KEY_DSA,
++	KEY_NSS,
+ 	KEY_UNSPEC
+ };
+ enum fp_type {
+@@ -48,16 +54,30 @@ enum fp_rep {
  
- 	int     num_identity_files;	/* Number of files for RSA/DSA identities. */
+ /* key is stored in external hardware */
+ #define KEY_FLAG_EXT		0x0001
++#define KEY_FLAG_NSS		0x0002
++
++#ifdef HAVE_LIBNSS
++typedef struct NSSKey NSSKey;
++struct NSSKey {
++	SECKEYPrivateKey *privk;
++	SECKEYPublicKey *pubk;
++};
++#endif
+ 
+ struct Key {
+ 	int	 type;
+ 	int	 flags;
+ 	RSA	*rsa;
+ 	DSA	*dsa;
++#ifdef HAVE_LIBNSS
++	NSSKey  *nss;
++#endif
+ };
+ 
+ Key		*key_new(int);
+ Key		*key_new_private(int);
++Key 		*key_new_nss(int);
++Key		*key_new_nss_copy(int, const Key *);
+ void		 key_free(Key *);
+ Key		*key_demote(const Key *);
+ int		 key_equal(const Key *, const Key *);
 diff -up openssh-5.2p1/ssh-add.c.nss-keys openssh-5.2p1/ssh-add.c
 --- openssh-5.2p1/ssh-add.c.nss-keys	2008-02-28 09:13:52.000000000 +0100
-+++ openssh-5.2p1/ssh-add.c	2009-03-10 03:51:56.254252403 +0100
-@@ -42,8 +42,18 @@
- #include <sys/param.h>
- 
++++ openssh-5.2p1/ssh-add.c	2008-11-18 19:11:41.000000000 +0100
+@@ -44,6 +44,14 @@
  #include <openssl/evp.h>
-+#include <openssl/fips.h>
-+#include <fipscheck.h>
  #include "openbsd-compat/openssl-compat.h"
  
 +#ifdef HAVE_LIBNSS
@@ -748,7 +949,7 @@
  #include <fcntl.h>
  #include <pwd.h>
  #include <stdarg.h>
-@@ -57,6 +67,7 @@
+@@ -57,6 +65,7 @@
  #include "rsa.h"
  #include "log.h"
  #include "key.h"
@@ -756,16 +957,7 @@
  #include "buffer.h"
  #include "authfd.h"
  #include "authfile.h"
-@@ -245,7 +256,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));
-@@ -307,6 +318,117 @@ do_file(AuthenticationConnection *ac, in
+@@ -307,6 +316,117 @@ do_file(AuthenticationConnection *ac, in
  	return 0;
  }
  
@@ -883,7 +1075,7 @@
  static void
  usage(void)
  {
-@@ -334,16 +456,25 @@ main(int argc, char **argv)
+@@ -334,6 +454,10 @@ main(int argc, char **argv)
  	AuthenticationConnection *ac = NULL;
  	char *sc_reader_id = NULL;
  	int i, ch, deleting = 0, ret = 0;
@@ -894,24 +1086,7 @@
  
  	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
  	sanitise_stdfd();
- 
- 	__progname = ssh_get_progname(argv[0]);
-+	SSLeay_add_all_algorithms();
-+	if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) {
-+		fprintf(stderr,
-+		    "FIPS integrity verification test failed.\n");
-+		exit(3);
-+	}
-+
- 	init_rng();
- 	seed_rng();
- 
--	SSLeay_add_all_algorithms();
--
- 	/* At first, get a connection to the authentication agent. */
- 	ac = ssh_get_authentication_connection();
- 	if (ac == NULL) {
-@@ -351,7 +482,7 @@ main(int argc, char **argv)
+@@ -351,7 +475,7 @@ main(int argc, char **argv)
  		    "Could not open a connection to your authentication agent.\n");
  		exit(2);
  	}
@@ -920,7 +1095,7 @@
  		switch (ch) {
  		case 'l':
  		case 'L':
-@@ -373,6 +504,11 @@ main(int argc, char **argv)
+@@ -373,6 +497,11 @@ main(int argc, char **argv)
  			if (delete_all(ac) == -1)
  				ret = 1;
  			goto done;
@@ -932,7 +1107,7 @@
  		case 's':
  			sc_reader_id = optarg;
  			break;
-@@ -387,6 +523,11 @@ main(int argc, char **argv)
+@@ -387,6 +516,11 @@ main(int argc, char **argv)
  				goto done;
  			}
  			break;
@@ -944,381 +1119,124 @@
  		default:
  			usage();
  			ret = 1;
-@@ -400,6 +541,40 @@ main(int argc, char **argv)
+@@ -400,6 +534,40 @@ main(int argc, char **argv)
  			ret = 1;
  		goto done;
  	}
 +#ifdef HAVE_LIBNSS
-+	if (use_nss) {
-+		PK11SlotList *slots;
-+		PK11SlotListElement *sle;
-+		int count = 0;
-+		if (nss_init(password_cb) == -1) {
-+			fprintf(stderr, "Failed to initialize NSS library\n");
-+			ret = 1;
-+			goto done;
-+		}
-+		
-+		if ((slots=PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE,
-+			NULL)) == NULL) {
-+			fprintf(stderr, "No tokens found\n");
-+			ret = 1;
-+			goto nss_done;
-+		}
-+
-+		for (sle = slots->head; sle; sle = sle->next) {
-+			int rv;
-+			if ((rv=add_slot_keys(ac, sle->slot, !deleting)) == -1) {
-+				ret = 1;
-+			}
-+			count += rv;
-+		}
-+		if (count == 0) {
-+			ret = 1;
-+		}
-+nss_done:		
-+		NSS_Shutdown();
-+		clear_pass();
-+		goto done;
-+	}
-+#endif
- 	if (argc == 0) {
- 		char buf[MAXPATHLEN];
- 		struct passwd *pw;
-diff -up openssh-5.2p1/ssh-agent.c.nss-keys openssh-5.2p1/ssh-agent.c
---- openssh-5.2p1/ssh-agent.c.nss-keys	2008-07-04 15:10:49.000000000 +0200
-+++ openssh-5.2p1/ssh-agent.c	2009-03-10 03:51:56.171221623 +0100
-@@ -51,6 +51,8 @@
- 
- #include <openssl/evp.h>
- #include <openssl/md5.h>
-+#include <openssl/fips.h>
-+#include <fipscheck.h>
- #include "openbsd-compat/openssl-compat.h"
- 
- #include <errno.h>
-@@ -80,6 +82,10 @@
- #include "scard.h"
- #endif
- 
-+#ifdef HAVE_LIBNSS
-+#include "nsskeys.h"
-+#endif
-+
- #if defined(HAVE_SYS_PRCTL_H)
- #include <sys/prctl.h>	/* For prctl() and PR_SET_DUMPABLE */
- #endif
-@@ -196,9 +202,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);
- 
-@@ -714,6 +720,114 @@ send:
- }
- #endif /* SMARTCARD */
- 
-+#ifdef HAVE_LIBNSS
-+static void
-+process_add_nss_key (SocketEntry *e)
-+{
-+	char *tokenname = NULL, *keyname = NULL, *password = NULL;
-+	int i, version, success = 0, death = 0, confirm = 0;
-+	Key **keys, *k;
-+	Identity *id;
-+	Idtab *tab;
-+
-+	tokenname = buffer_get_string(&e->request, NULL);
-+	keyname = buffer_get_string(&e->request, NULL);
-+	password = buffer_get_string(&e->request, NULL);
-+
-+	while (buffer_len(&e->request)) {
-+		switch (buffer_get_char(&e->request)) {
-+		case SSH_AGENT_CONSTRAIN_LIFETIME:
-+			death = time(NULL) + buffer_get_int(&e->request);
-+			break;
-+		case SSH_AGENT_CONSTRAIN_CONFIRM:
-+			confirm = 1;
-+			break;
-+		default:
-+			break;
-+		}
-+	}
-+	if (lifetime && !death)
-+		death = time(NULL) + lifetime;
-+
-+	keys = nss_get_keys(tokenname, keyname, password);
-+	/* password is owned by keys[0] now */
-+	xfree(tokenname);
-+	xfree(keyname);
-+
-+	if (keys == NULL) {
-+		memset(password, 0, strlen(password));
-+		xfree(password);
-+		error("nss_get_keys failed");
-+		goto send;
-+	}
-+	for (i = 0; keys[i] != NULL; i++) {
-+		k = keys[i];
-+		version = k->type == KEY_RSA1 ? 1 : 2;
-+		tab = idtab_lookup(version);
-+		if (lookup_identity(k, version) == NULL) {
-+			id = xmalloc(sizeof(Identity));
-+			id->key = k;
-+			id->comment = nss_get_key_label(k);
-+			id->death = death;
-+			id->confirm = confirm;
-+			TAILQ_INSERT_TAIL(&tab->idlist, id, next);
-+			tab->nentries++;
-+			success = 1;
-+		} else {
-+			key_free(k);
-+		}
-+		keys[i] = NULL;
-+	}
-+	xfree(keys);
-+send:
-+	buffer_put_int(&e->output, 1);
-+	buffer_put_char(&e->output,
-+	    success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
-+}
-+
-+static void
-+process_remove_nss_key(SocketEntry *e)
-+{
-+	char *tokenname = NULL, *keyname = NULL, *password = NULL;
-+	int i, version, success = 0;
-+	Key **keys, *k = NULL;
-+	Identity *id;
-+	Idtab *tab;
-+
-+	tokenname = buffer_get_string(&e->request, NULL);
-+	keyname = buffer_get_string(&e->request, NULL);
-+	password = buffer_get_string(&e->request, NULL);
-+
-+	keys = nss_get_keys(tokenname, keyname, password);
-+	xfree(tokenname);
-+	xfree(keyname);
-+	xfree(password);
-+
-+	if (keys == NULL || keys[0] == NULL) {
-+		error("nss_get_keys failed");
-+		goto send;
-+	}
-+	for (i = 0; keys[i] != NULL; i++) {
-+		k = keys[i];
-+		version = k->type == KEY_RSA1 ? 1 : 2;
-+		if ((id = lookup_identity(k, version)) != NULL) {
-+			tab = idtab_lookup(version);
-+			TAILQ_REMOVE(&tab->idlist, id, next);
-+			tab->nentries--;
-+			free_identity(id);
-+			success = 1;
-+		}
-+		key_free(k);
-+		keys[i] = NULL;
-+	}
-+	xfree(keys);
-+send:
-+	buffer_put_int(&e->output, 1);
-+	buffer_put_char(&e->output,
-+	    success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
-+}
-+#endif /* HAVE_LIBNSS */
-+
- /* dispatch incoming messages */
- 
- static void
-@@ -806,6 +920,15 @@ process_message(SocketEntry *e)
- 		process_remove_smartcard_key(e);
- 		break;
- #endif /* SMARTCARD */
-+#ifdef HAVE_LIBNSS
-+	case SSH_AGENTC_ADD_NSS_KEY:
-+	case SSH_AGENTC_ADD_NSS_KEY_CONSTRAINED:
-+		process_add_nss_key(e);
-+		break;
-+	case SSH_AGENTC_REMOVE_NSS_KEY:
-+		process_remove_nss_key(e);
-+		break;
-+#endif /* SMARTCARD */
- 	default:
- 		/* Unknown message.  Respond with failure. */
- 		error("Unknown message %d", type);
-@@ -1075,6 +1198,11 @@ main(int ac, char **av)
- #endif
- 
- 	SSLeay_add_all_algorithms();
-+        if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) {
-+                fprintf(stderr,
-+                    "FIPS integrity verification test failed.\n");
-+                exit(3);
-+        }
- 
- 	__progname = ssh_get_progname(av[0]);
- 	init_rng();
-diff -up openssh-5.2p1/ssh.c.nss-keys openssh-5.2p1/ssh.c
---- openssh-5.2p1/ssh.c.nss-keys	2009-02-14 06:28:21.000000000 +0100
-+++ openssh-5.2p1/ssh.c	2009-03-10 03:51:56.176206362 +0100
-@@ -71,6 +71,8 @@
- 
- #include <openssl/evp.h>
- #include <openssl/err.h>
-+#include <openssl/fips.h>
-+#include <fipscheck.h>
- #include "openbsd-compat/openssl-compat.h"
- #include "openbsd-compat/sys-queue.h"
- 
-@@ -104,6 +106,9 @@
- #ifdef SMARTCARD
- #include "scard.h"
- #endif
-+#ifdef HAVE_LIBNSS
-+#include "nsskeys.h"
-+#endif
- 
- extern char *__progname;
- 
-@@ -217,6 +222,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();
- 
- 	/*
-@@ -547,7 +556,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. */
-@@ -1231,9 +1239,11 @@ load_public_identity_files(void)
- 	int i = 0;
- 	Key *public;
- 	struct passwd *pw;
--#ifdef SMARTCARD
-+#if defined(SMARTCARD) || defined(HAVE_LIBNSS)
- 	Key **keys;
-+#endif
- 
-+#ifdef SMARTCARD
- 	if (options.smartcard_device != NULL &&
- 	    options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
- 	    (keys = sc_get_keys(options.smartcard_device, NULL)) != NULL) {
-@@ -1256,6 +1266,27 @@ load_public_identity_files(void)
- 		xfree(keys);
- 	}
- #endif /* SMARTCARD */
-+#ifdef HAVE_LIBNSS
-+	if (options.use_nss &&
-+	    options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
-+	    (keys = nss_get_keys(options.nss_token, NULL, NULL)) != NULL) {
-+		int count;
-+		for (count = 0; keys[count] != NULL; count++) {
-+			memmove(&options.identity_files[1], &options.identity_files[0],
-+			    sizeof(char *) * (SSH_MAX_IDENTITY_FILES - 1));
-+			memmove(&options.identity_keys[1], &options.identity_keys[0],
-+			    sizeof(Key *) * (SSH_MAX_IDENTITY_FILES - 1));
-+			options.num_identity_files++;
-+			options.identity_keys[0] = keys[count];
-+			options.identity_files[0] = nss_get_key_label(keys[count]);
++	if (use_nss) {
++		PK11SlotList *slots;
++		PK11SlotListElement *sle;
++		int count = 0;
++		if (nss_init(password_cb) == -1) {
++			fprintf(stderr, "Failed to initialize NSS library\n");
++			ret = 1;
++			goto done;
++		}
++		
++		if ((slots=PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE,
++			NULL)) == NULL) {
++			fprintf(stderr, "No tokens found\n");
++			ret = 1;
++			goto nss_done;
 +		}
-+		if (options.num_identity_files > SSH_MAX_IDENTITY_FILES)
-+			options.num_identity_files = SSH_MAX_IDENTITY_FILES;
-+		i += count;
-+		xfree(keys);
-+	}
-+#endif /* HAVE_LIBNSS */
 +
- 	if ((pw = getpwuid(original_real_uid)) == NULL)
- 		fatal("load_public_identity_files: getpwuid failed");
- 	pwname = xstrdup(pw->pw_name);
-diff -up openssh-5.2p1/ssh-dss.c.nss-keys openssh-5.2p1/ssh-dss.c
---- openssh-5.2p1/ssh-dss.c.nss-keys	2006-11-07 13:14:42.000000000 +0100
-+++ openssh-5.2p1/ssh-dss.c	2009-03-10 03:51:55.843232632 +0100
-@@ -39,6 +39,10 @@
- #include "log.h"
- #include "key.h"
++		for (sle = slots->head; sle; sle = sle->next) {
++			int rv;
++			if ((rv=add_slot_keys(ac, sle->slot, !deleting)) == -1) {
++				ret = 1;
++			}
++			count += rv;
++		}
++		if (count == 0) {
++			ret = 1;
++		}
++nss_done:		
++		NSS_Shutdown();
++		clear_pass();
++		goto done;
++	}
++#endif
+ 	if (argc == 0) {
+ 		char buf[MAXPATHLEN];
+ 		struct passwd *pw;
+diff -up openssh-5.2p1/ssh-rsa.c.nss-keys openssh-5.2p1/ssh-rsa.c
+--- openssh-5.2p1/ssh-rsa.c.nss-keys	2006-09-01 07:38:37.000000000 +0200
++++ openssh-5.2p1/ssh-rsa.c	2008-11-18 19:11:41.000000000 +0100
+@@ -32,6 +32,10 @@
+ #include "compat.h"
+ #include "ssh.h"
  
 +#ifdef HAVE_LIBNSS
 +#include <cryptohi.h>
 +#endif
 +
- #define INTBLOB_LEN	20
- #define SIGBLOB_LEN	(2*INTBLOB_LEN)
+ static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *);
  
-@@ -57,6 +61,34 @@ ssh_dss_sign(const Key *key, u_char **si
- 		error("ssh_dss_sign: no DSA key");
+ /* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
+@@ -50,6 +54,38 @@ ssh_rsa_sign(const Key *key, u_char **si
+ 		error("ssh_rsa_sign: no RSA key");
  		return -1;
  	}
++
++	slen = RSA_size(key->rsa);
++	sig = xmalloc(slen);
++
 +#ifdef HAVE_LIBNSS
 +	if (key->flags & KEY_FLAG_NSS) {
 +		SECItem sigitem;
-+		SECItem *rawsig;
++		SECOidTag alg;
 +
 +		memset(&sigitem, 0, sizeof(sigitem));
++		alg = (datafellows & SSH_BUG_RSASIGMD5) ?
++			SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION :
++			SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
++
 +		if (SEC_SignData(&sigitem, (u_char *)data, datalen, key->nss->privk,
-+			SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) != SECSuccess) {
-+			error("ssh_dss_sign: sign failed");
++			alg) != SECSuccess) {
++			error("ssh_rsa_sign: sign failed");
 +			return -1;
 +		}
-+		
-+		if ((rawsig=DSAU_DecodeDerSig(&sigitem)) == NULL) {
-+			error("ssh_dss_sign: der decode failed");
++		if (sigitem.len > slen) {
++			error("ssh_rsa_sign: slen %u slen2 %u", slen, sigitem.len);
++			xfree(sig);
 +			SECITEM_ZfreeItem(&sigitem, PR_FALSE);
 +			return -1;
 +		}
-+		SECITEM_ZfreeItem(&sigitem, PR_FALSE);
-+		if (rawsig->len != SIGBLOB_LEN) {
-+			error("ssh_dss_sign: unsupported signature length %d",
-+				rawsig->len);
-+			SECITEM_ZfreeItem(rawsig, PR_TRUE);
-+			return -1;
++		if (sigitem.len < slen) {
++			memset(sig, 0, slen - sigitem.len);
 +		}
-+		memcpy(sigblob, rawsig->data, SIGBLOB_LEN);
-+		SECITEM_ZfreeItem(rawsig, PR_TRUE);
++		memcpy(sig+slen-sigitem.len, sigitem.data, sigitem.len);
++		SECITEM_ZfreeItem(&sigitem, PR_FALSE);
 +	} else {
 +#endif
- 	EVP_DigestInit(&md, evp_md);
+ 	nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
+ 	if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
+ 		error("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid);
+@@ -59,9 +95,6 @@ ssh_rsa_sign(const Key *key, u_char **si
  	EVP_DigestUpdate(&md, data, datalen);
  	EVP_DigestFinal(&md, digest, &dlen);
-@@ -80,7 +112,9 @@ ssh_dss_sign(const Key *key, u_char **si
- 	BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
- 	BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
- 	DSA_SIG_free(sig);
+ 
+-	slen = RSA_size(key->rsa);
+-	sig = xmalloc(slen);
 -
+ 	ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa);
+ 	memset(digest, 'd', sizeof(digest));
+ 
+@@ -83,6 +116,9 @@ ssh_rsa_sign(const Key *key, u_char **si
+ 		xfree(sig);
+ 		return -1;
+ 	}
 +#ifdef HAVE_LIBNSS
 +	}
 +#endif
- 	if (datafellows & SSH_BUG_SIGBLOB) {
- 		if (lenp != NULL)
- 			*lenp = SIGBLOB_LEN;
+ 	/* encode signature */
+ 	buffer_init(&b);
+ 	buffer_put_cstring(&b, "ssh-rsa");
 diff -up openssh-5.2p1/ssh-keygen.c.nss-keys openssh-5.2p1/ssh-keygen.c
---- openssh-5.2p1/ssh-keygen.c.nss-keys	2009-02-21 22:47:02.000000000 +0100
-+++ openssh-5.2p1/ssh-keygen.c	2009-03-10 03:51:56.249239228 +0100
-@@ -21,6 +21,8 @@
- 
- #include <openssl/evp.h>
- #include <openssl/pem.h>
-+#include <openssl/fips.h>
-+#include <fipscheck.h>
- #include "openbsd-compat/openssl-compat.h"
- 
- #include <errno.h>
-@@ -53,6 +55,11 @@
+--- openssh-5.2p1/ssh-keygen.c.nss-keys	2008-07-14 03:28:29.000000000 +0200
++++ openssh-5.2p1/ssh-keygen.c	2008-11-18 19:11:41.000000000 +0100
+@@ -53,6 +53,11 @@
  #include "scard.h"
  #endif
  
@@ -1330,7 +1248,7 @@
  /* Number of bits in the RSA/DSA key.  This value can be set on the command line. */
  #define DEFAULT_BITS		2048
  #define DEFAULT_BITS_DSA	1024
-@@ -501,6 +508,26 @@ do_download(struct passwd *pw, const cha
+@@ -501,6 +506,26 @@ do_download(struct passwd *pw, const cha
  }
  #endif /* SMARTCARD */
  
@@ -1357,16 +1275,7 @@
  static void
  do_fingerprint(struct passwd *pw)
  {
-@@ -512,7 +539,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)
-@@ -1083,7 +1110,8 @@ main(int argc, char **argv)
+@@ -1083,7 +1108,8 @@ main(int argc, char **argv)
  	Key *private, *public;
  	struct passwd *pw;
  	struct stat st;
@@ -1376,20 +1285,7 @@
  	u_int32_t memory = 0, generator_wanted = 0, trials = 100;
  	int do_gen_candidates = 0, do_screen_candidates = 0;
  	BIGNUM *start = NULL;
-@@ -1099,6 +1127,12 @@ main(int argc, char **argv)
- 	__progname = ssh_get_progname(argv[0]);
- 
- 	SSLeay_add_all_algorithms();
-+        if (FIPS_mode() && !FIPSCHECK_verify(NULL, NULL)) {
-+                fprintf(stderr,
-+                    "FIPS integrity verification test failed.\n");
-+                exit(3);
-+        }
-+
- 	log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);
- 
- 	init_rng();
-@@ -1116,7 +1150,7 @@ main(int argc, char **argv)
+@@ -1116,7 +1142,7 @@ main(int argc, char **argv)
  	}
  
  	while ((opt = getopt(argc, argv,
@@ -1398,7 +1294,7 @@
  		switch (opt) {
  		case 'b':
  			bits = (u_int32_t)strtonum(optarg, 768, 32768, &errstr);
-@@ -1156,6 +1190,10 @@ main(int argc, char **argv)
+@@ -1156,6 +1182,10 @@ main(int argc, char **argv)
  		case 'g':
  			print_generic = 1;
  			break;
@@ -1409,7 +1305,7 @@
  		case 'P':
  			identity_passphrase = optarg;
  			break;
-@@ -1187,10 +1225,10 @@ main(int argc, char **argv)
+@@ -1187,10 +1217,10 @@ main(int argc, char **argv)
  		case 't':
  			key_type_name = optarg;
  			break;
@@ -1423,7 +1319,7 @@
  			reader_id = optarg;
  			break;
  		case 'v':
-@@ -1299,6 +1337,17 @@ main(int argc, char **argv)
+@@ -1299,6 +1329,17 @@ main(int argc, char **argv)
  			exit(0);
  		}
  	}
@@ -1441,96 +1337,61 @@
  	if (reader_id != NULL) {
  #ifdef SMARTCARD
  		if (download)
-@@ -1465,14 +1514,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 -up openssh-5.2p1/ssh-rsa.c.nss-keys openssh-5.2p1/ssh-rsa.c
---- openssh-5.2p1/ssh-rsa.c.nss-keys	2006-09-01 07:38:37.000000000 +0200
-+++ openssh-5.2p1/ssh-rsa.c	2009-03-10 03:51:55.930219040 +0100
-@@ -32,6 +32,10 @@
- #include "compat.h"
- #include "ssh.h"
- 
+diff -up openssh-5.2p1/readconf.c.nss-keys openssh-5.2p1/readconf.c
+--- openssh-5.2p1/readconf.c.nss-keys	2008-06-29 16:04:03.000000000 +0200
++++ openssh-5.2p1/readconf.c	2008-11-18 19:11:41.000000000 +0100
+@@ -124,6 +124,7 @@ typedef enum {
+ 	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
+ 	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
+ 	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
++	oUseNSS, oNSSToken,
+ 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
+ 	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
+ 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
+@@ -210,6 +211,13 @@ static struct {
+ #else
+ 	{ "smartcarddevice", oUnsupported },
+ #endif
 +#ifdef HAVE_LIBNSS
-+#include <cryptohi.h>
++	{ "usenss", oUseNSS },
++	{ "nsstoken", oNSSToken },
++#else
++	{ "usenss", oUnsupported },
++	{ "nsstoken", oNSSToken },
 +#endif
-+
- static int openssh_RSA_verify(int, u_char *, u_int, u_char *, u_int, RSA *);
+ 	{ "clearallforwardings", oClearAllForwardings },
+ 	{ "enablesshkeysign", oEnableSSHKeysign },
+ 	{ "verifyhostkeydns", oVerifyHostKeyDNS },
+@@ -603,6 +611,14 @@ parse_string:
+ 		charptr = &options->smartcard_device;
+ 		goto parse_string;
  
- /* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
-@@ -50,6 +54,38 @@ ssh_rsa_sign(const Key *key, u_char **si
- 		error("ssh_rsa_sign: no RSA key");
- 		return -1;
- 	}
-+
-+	slen = RSA_size(key->rsa);
-+	sig = xmalloc(slen);
-+
-+#ifdef HAVE_LIBNSS
-+	if (key->flags & KEY_FLAG_NSS) {
-+		SECItem sigitem;
-+		SECOidTag alg;
++	case oUseNSS:
++		intptr = &options->use_nss;
++		goto parse_flag;
 +
-+		memset(&sigitem, 0, sizeof(sigitem));
-+		alg = (datafellows & SSH_BUG_RSASIGMD5) ?
-+			SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION :
-+			SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
++	case oNSSToken:
++		charptr = &options->nss_token;
++		goto parse_command;
 +
-+		if (SEC_SignData(&sigitem, (u_char *)data, datalen, key->nss->privk,
-+			alg) != SECSuccess) {
-+			error("ssh_rsa_sign: sign failed");
-+			return -1;
-+		}
-+		if (sigitem.len > slen) {
-+			error("ssh_rsa_sign: slen %u slen2 %u", slen, sigitem.len);
-+			xfree(sig);
-+			SECITEM_ZfreeItem(&sigitem, PR_FALSE);
-+			return -1;
-+		}
-+		if (sigitem.len < slen) {
-+			memset(sig, 0, slen - sigitem.len);
-+		}
-+		memcpy(sig+slen-sigitem.len, sigitem.data, sigitem.len);
-+		SECITEM_ZfreeItem(&sigitem, PR_FALSE);
-+	} else {
-+#endif
- 	nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
- 	if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
- 		error("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid);
-@@ -59,9 +95,6 @@ ssh_rsa_sign(const Key *key, u_char **si
- 	EVP_DigestUpdate(&md, data, datalen);
- 	EVP_DigestFinal(&md, digest, &dlen);
- 
--	slen = RSA_size(key->rsa);
--	sig = xmalloc(slen);
--
- 	ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa);
- 	memset(digest, 'd', sizeof(digest));
- 
-@@ -83,6 +116,9 @@ ssh_rsa_sign(const Key *key, u_char **si
- 		xfree(sig);
- 		return -1;
- 	}
-+#ifdef HAVE_LIBNSS
-+	}
-+#endif
- 	/* encode signature */
- 	buffer_init(&b);
- 	buffer_put_cstring(&b, "ssh-rsa");
+ 	case oProxyCommand:
+ 		charptr = &options->proxy_command;
+ parse_command:
+@@ -1055,6 +1071,8 @@ initialize_options(Options * options)
+ 	options->preferred_authentications = NULL;
+ 	options->bind_address = NULL;
+ 	options->smartcard_device = NULL;
++	options->use_nss = -1;
++	options->nss_token = NULL;
+ 	options->enable_ssh_keysign = - 1;
+ 	options->no_host_authentication_for_localhost = - 1;
+ 	options->identities_only = - 1;
+@@ -1184,6 +1202,8 @@ fill_default_options(Options * options)
+ 		options->no_host_authentication_for_localhost = 0;
+ 	if (options->identities_only == -1)
+ 		options->identities_only = 0;
++	if (options->use_nss == -1)
++		options->use_nss = 0;
+ 	if (options->enable_ssh_keysign == -1)
+ 		options->enable_ssh_keysign = 0;
+ 	if (options->rekey_limit == -1)

openssh-5.2p1-redhat.patch:

Index: openssh-5.2p1-redhat.patch
===================================================================
RCS file: /cvs/pkgs/rpms/openssh/devel/openssh-5.2p1-redhat.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- openssh-5.2p1-redhat.patch	10 Mar 2009 11:54:43 -0000	1.1
+++ openssh-5.2p1-redhat.patch	10 Mar 2009 13:39:03 -0000	1.2
@@ -1,78 +1,6 @@
-diff -up openssh-5.2p1/ssh_config.redhat openssh-5.2p1/ssh_config
---- openssh-5.2p1/ssh_config.redhat	2009-02-21 02:45:02.000000000 +0100
-+++ openssh-5.2p1/ssh_config	2009-03-10 03:51:54.749290375 +0100
-@@ -44,3 +44,13 @@
- #   TunnelDevice any:any
- #   PermitLocalCommand no
- #   VisualHostKey no
-+Host *
-+	GSSAPIAuthentication yes
-+# If this option is set to yes then remote X11 clients will have full access
-+# to the original X11 display. As virtually no X11 client supports the untrusted
-+# mode correctly we set this to yes.
-+	ForwardX11Trusted yes
-+# Send locale-related environment variables
-+	SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES 
-+	SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT 
-+	SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
-diff -up openssh-5.2p1/sshd_config.0.redhat openssh-5.2p1/sshd_config.0
---- openssh-5.2p1/sshd_config.0.redhat	2009-02-23 01:18:15.000000000 +0100
-+++ openssh-5.2p1/sshd_config.0	2009-03-10 03:51:54.958364611 +0100
-@@ -467,6 +467,11 @@ DESCRIPTION
-              Defines the number of bits in the ephemeral protocol version 1
-              server key.  The minimum value is 512, and the default is 1024.
- 
-+     ShowPatchLevel
-+	     Specifies whether sshd will display the specific patch level of
-+	     the binary in the server identification string.  The patch level
-+	     is set at compile-time.  The default is M-bM-^@M-^\noM-bM-^@M-^].
-+
-      StrictModes
-              Specifies whether sshd(8) should check file modes and ownership
-              of the user's files and home directory before accepting login.
-@@ -491,9 +496,9 @@ DESCRIPTION
- 
-      SyslogFacility
-              Gives the facility code that is used when logging messages from
--             sshd(8).  The possible values are: DAEMON, USER, AUTH, LOCAL0,
--             LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.  The de-
--             fault is AUTH.
-+             sshd(8).  The possible values are: DAEMON, USER, AUTH, AUTHPRIV,
-+             LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
-+             The default is AUTH.
- 
-      TCPKeepAlive
-              Specifies whether the system should send TCP keepalive messages
-diff -up openssh-5.2p1/sshd_config.5.redhat openssh-5.2p1/sshd_config.5
---- openssh-5.2p1/sshd_config.5.redhat	2009-02-23 01:00:24.000000000 +0100
-+++ openssh-5.2p1/sshd_config.5	2009-03-10 03:51:54.931352756 +0100
-@@ -814,6 +814,14 @@ This option applies to protocol version 
- .It Cm ServerKeyBits
- Defines the number of bits in the ephemeral protocol version 1 server key.
- The minimum value is 512, and the default is 1024.
-+.It Cm ShowPatchLevel 
-+Specifies whether 
-+.Nm sshd 
-+will display the patch level of the binary in the identification string. 
-+The patch level is set at compile-time. 
-+The default is 
-+.Dq no . 
-+This option applies to protocol version 1 only. 
- .It Cm StrictModes
- Specifies whether
- .Xr sshd 8
-@@ -848,7 +856,7 @@ Note that this option applies to protoco
- .It Cm SyslogFacility
- Gives the facility code that is used when logging messages from
- .Xr sshd 8 .
--The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
-+The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, LOCAL2,
- LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
- The default is AUTH.
- .It Cm TCPKeepAlive
 diff -up openssh-5.2p1/sshd_config.redhat openssh-5.2p1/sshd_config
 --- openssh-5.2p1/sshd_config.redhat	2008-07-02 14:35:43.000000000 +0200
-+++ openssh-5.2p1/sshd_config	2009-03-10 03:51:54.960221540 +0100
++++ openssh-5.2p1/sshd_config	2008-07-23 14:11:12.000000000 +0200
 @@ -33,6 +33,7 @@ Protocol 2
  # Logging
  # obsoletes QuietMode and FascistLogging
@@ -122,11 +50,48 @@
  #X11DisplayOffset 10
  #X11UseLocalhost yes
  #PrintMotd yes
-@@ -100,6 +112,7 @@ Protocol 2
- #Compression delayed
- #ClientAliveInterval 0
- #ClientAliveCountMax 3
-+#ShowPatchLevel no
- #UseDNS yes
- #PidFile /var/run/sshd.pid
- #MaxStartups 10
+diff -up openssh-5.2p1/ssh_config.redhat openssh-5.2p1/ssh_config
+--- openssh-5.2p1/ssh_config.redhat	2007-06-11 06:04:42.000000000 +0200
++++ openssh-5.2p1/ssh_config	2008-07-23 14:07:29.000000000 +0200
+@@ -44,3 +44,13 @@
+ #   TunnelDevice any:any
+ #   PermitLocalCommand no
+ #   VisualHostKey no
++Host *
++	GSSAPIAuthentication yes
++# If this option is set to yes then remote X11 clients will have full access
++# to the original X11 display. As virtually no X11 client supports the untrusted
++# mode correctly we set this to yes.
++	ForwardX11Trusted yes
++# Send locale-related environment variables
++	SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES 
++	SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT 
++	SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
+diff -up openssh-5.2p1/sshd_config.0.redhat openssh-5.2p1/sshd_config.0
+--- openssh-5.2p1/sshd_config.0.redhat	2008-07-21 10:30:51.000000000 +0200
++++ openssh-5.2p1/sshd_config.0	2008-07-23 14:07:29.000000000 +0200
+@@ -490,9 +490,9 @@ DESCRIPTION
+ 
+      SyslogFacility
+              Gives the facility code that is used when logging messages from
+-             sshd(8).  The possible values are: DAEMON, USER, AUTH, LOCAL0,
+-             LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.  The de-
+-             fault is AUTH.
++             sshd(8).  The possible values are: DAEMON, USER, AUTH, AUTHPRIV,
++             LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
++             The default is AUTH.
+ 
+      TCPKeepAlive
+              Specifies whether the system should send TCP keepalive messages
+diff -up openssh-5.2p1/sshd_config.5.redhat openssh-5.2p1/sshd_config.5
+--- openssh-5.2p1/sshd_config.5.redhat	2008-07-02 14:35:43.000000000 +0200
++++ openssh-5.2p1/sshd_config.5	2008-07-23 14:07:29.000000000 +0200
+@@ -846,7 +846,7 @@ Note that this option applies to protoco
+ .It Cm SyslogFacility
+ Gives the facility code that is used when logging messages from
+ .Xr sshd 8 .
+-The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
++The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, LOCAL2,
+ LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
+ The default is AUTH.
+ .It Cm TCPKeepAlive

openssh-5.2p1-selinux.patch:

Index: openssh-5.2p1-selinux.patch
===================================================================
RCS file: /cvs/pkgs/rpms/openssh/devel/openssh-5.2p1-selinux.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- openssh-5.2p1-selinux.patch	10 Mar 2009 11:54:44 -0000	1.1
+++ openssh-5.2p1-selinux.patch	10 Mar 2009 13:39:03 -0000	1.2
@@ -1,6 +1,17 @@
+diff -up openssh-5.2p1/configure.ac.selinux openssh-5.2p1/configure.ac
+--- openssh-5.2p1/configure.ac.selinux	2008-07-23 16:32:13.000000000 +0200
++++ openssh-5.2p1/configure.ac	2008-07-23 16:32:13.000000000 +0200
+@@ -3309,6 +3309,7 @@ AC_ARG_WITH(selinux,
+ 		AC_CHECK_LIB(selinux, setexeccon, [ LIBSELINUX="-lselinux" ],
+ 		    AC_MSG_ERROR(SELinux support requires libselinux library))
+ 		SSHDLIBS="$SSHDLIBS $LIBSELINUX"
++		LIBS="$LIBS $LIBSELINUX"
+ 		AC_CHECK_FUNCS(getseuserbyname get_default_context_with_level)
+ 		LIBS="$save_LIBS"
+ 	fi ]
 diff -up openssh-5.2p1/auth1.c.selinux openssh-5.2p1/auth1.c
---- openssh-5.2p1/auth1.c.selinux	2009-03-10 03:51:54.813223420 +0100
-+++ openssh-5.2p1/auth1.c	2009-03-10 03:51:55.045214236 +0100
+--- openssh-5.2p1/auth1.c.selinux	2008-07-23 16:32:13.000000000 +0200
++++ openssh-5.2p1/auth1.c	2008-07-23 16:32:13.000000000 +0200
 @@ -391,7 +391,7 @@ void
  do_authentication(Authctxt *authctxt)
  {
@@ -30,10 +41,173 @@
  
  	/* Verify that the user is a valid user. */
  	if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
+diff -up openssh-5.2p1/auth2-pubkey.c.selinux openssh-5.2p1/auth2-pubkey.c
+--- openssh-5.2p1/auth2-pubkey.c.selinux	2008-07-04 04:54:25.000000000 +0200
++++ openssh-5.2p1/auth2-pubkey.c	2008-07-23 16:32:13.000000000 +0200
+@@ -117,7 +117,14 @@ userauth_pubkey(Authctxt *authctxt)
+ 		}
+ 		/* reconstruct packet */
+ 		buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
+-		buffer_put_cstring(&b, authctxt->user);
++		if (authctxt->role) {
++			buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1);
++			buffer_append(&b, authctxt->user, strlen(authctxt->user));
++			buffer_put_char(&b, '/');
++			buffer_append(&b, authctxt->role, strlen(authctxt->role));
++		} else {
++			buffer_put_cstring(&b, authctxt->user);
++		}
+ 		buffer_put_cstring(&b,
+ 		    datafellows & SSH_BUG_PKSERVICE ?
+ 		    "ssh-userauth" :
+diff -up openssh-5.2p1/monitor_wrap.h.selinux openssh-5.2p1/monitor_wrap.h
+--- openssh-5.2p1/monitor_wrap.h.selinux	2006-08-05 04:39:40.000000000 +0200
++++ openssh-5.2p1/monitor_wrap.h	2008-07-23 16:32:13.000000000 +0200
+@@ -41,6 +41,7 @@ int mm_is_monitor(void);
+ DH *mm_choose_dh(int, int, int);
+ int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int);
+ void mm_inform_authserv(char *, char *);
++void mm_inform_authrole(char *);
+ struct passwd *mm_getpwnamallow(const char *);
+ char *mm_auth2_read_banner(void);
+ int mm_auth_password(struct Authctxt *, char *);
+diff -up openssh-5.2p1/monitor.h.selinux openssh-5.2p1/monitor.h
+--- openssh-5.2p1/monitor.h.selinux	2006-03-26 05:30:02.000000000 +0200
++++ openssh-5.2p1/monitor.h	2008-07-23 16:32:13.000000000 +0200
+@@ -30,7 +30,7 @@
+ 
+ enum monitor_reqtype {
+ 	MONITOR_REQ_MODULI, MONITOR_ANS_MODULI,
+-	MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV,
++	MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV,MONITOR_REQ_AUTHROLE,
+ 	MONITOR_REQ_SIGN, MONITOR_ANS_SIGN,
+ 	MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM,
+ 	MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER,
+diff -up openssh-5.2p1/auth2-hostbased.c.selinux openssh-5.2p1/auth2-hostbased.c
+--- openssh-5.2p1/auth2-hostbased.c.selinux	2008-07-17 10:57:19.000000000 +0200
++++ openssh-5.2p1/auth2-hostbased.c	2008-07-23 16:32:13.000000000 +0200
+@@ -106,7 +106,14 @@ userauth_hostbased(Authctxt *authctxt)
+ 	buffer_put_string(&b, session_id2, session_id2_len);
+ 	/* reconstruct packet */
+ 	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
+-	buffer_put_cstring(&b, authctxt->user);
++	if (authctxt->role) {
++		buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1);
++		buffer_append(&b, authctxt->user, strlen(authctxt->user));
++		buffer_put_char(&b, '/');
++		buffer_append(&b, authctxt->role, strlen(authctxt->role));
++	} else {
++		buffer_put_cstring(&b, authctxt->user);
++	}
+ 	buffer_put_cstring(&b, service);
+ 	buffer_put_cstring(&b, "hostbased");
+ 	buffer_put_string(&b, pkalg, alen);
+diff -up openssh-5.2p1/monitor_wrap.c.selinux openssh-5.2p1/monitor_wrap.c
+--- openssh-5.2p1/monitor_wrap.c.selinux	2008-07-11 09:36:48.000000000 +0200
++++ openssh-5.2p1/monitor_wrap.c	2008-07-23 16:32:13.000000000 +0200
+@@ -296,6 +296,23 @@ mm_inform_authserv(char *service, char *
+ 	buffer_free(&m);
+ }
+ 
++/* Inform the privileged process about role */
++
++void
++mm_inform_authrole(char *role)
++{
++	Buffer m;
++
++	debug3("%s entering", __func__);
++
++	buffer_init(&m);
++	buffer_put_cstring(&m, role ? role : "");
++
++	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m);
++
++	buffer_free(&m);
++}
++
+ /* Do the password authentication */
+ int
+ mm_auth_password(Authctxt *authctxt, char *password)
+diff -up openssh-5.2p1/openbsd-compat/port-linux.c.selinux openssh-5.2p1/openbsd-compat/port-linux.c
+--- openssh-5.2p1/openbsd-compat/port-linux.c.selinux	2008-03-26 21:27:21.000000000 +0100
++++ openssh-5.2p1/openbsd-compat/port-linux.c	2008-07-23 16:32:13.000000000 +0200
+@@ -30,11 +30,16 @@
+ #ifdef WITH_SELINUX
+ #include "log.h"
+ #include "port-linux.h"
++#include "key.h"
++#include "hostfile.h"
++#include "auth.h"
+ 
+ #include <selinux/selinux.h>
+ #include <selinux/flask.h>
+ #include <selinux/get_context_list.h>
+ 
++extern Authctxt *the_authctxt;
++
+ /* Wrapper around is_selinux_enabled() to log its return value once only */
+ int
+ ssh_selinux_enabled(void)
+@@ -53,23 +58,36 @@ ssh_selinux_enabled(void)
+ static security_context_t
+ ssh_selinux_getctxbyname(char *pwname)
+ {
+-	security_context_t sc;
+-	char *sename = NULL, *lvl = NULL;
+-	int r;
++	security_context_t sc = NULL;
++	char *sename, *lvl;
++	char *role = NULL;
++	int r = 0;
+ 
++	if (the_authctxt) 
++		role=the_authctxt->role;
+ #ifdef HAVE_GETSEUSERBYNAME
+-	if (getseuserbyname(pwname, &sename, &lvl) != 0)
+-		return NULL;
++	if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
++		sename = NULL;
++		lvl = NULL;
++	}
+ #else
+ 	sename = pwname;
+ 	lvl = NULL;
+ #endif
+ 
++	if (r == 0) {
+ #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
+-	r = get_default_context_with_level(sename, lvl, NULL, &sc);
++		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);
+ #else
+-	r = get_default_context(sename, NULL, &sc);
++		if (role != NULL && role[0])
++			r = get_default_context_with_role(sename, role, NULL, &sc);
++		else
++			r = get_default_context(sename, NULL, &sc);
+ #endif
++	}
+ 
+ 	if (r != 0) {
+ 		switch (security_getenforce()) {
+diff -up openssh-5.2p1/auth.h.selinux openssh-5.2p1/auth.h
+--- openssh-5.2p1/auth.h.selinux	2008-07-02 14:37:30.000000000 +0200
++++ openssh-5.2p1/auth.h	2008-07-23 16:32:13.000000000 +0200
+@@ -58,6 +58,7 @@ struct Authctxt {
+ 	char		*service;
+ 	struct passwd	*pw;		/* set if 'valid' */
+ 	char		*style;
++	char		*role;
+ 	void		*kbdintctxt;
+ 	void		*jpake_ctx;
+ #ifdef BSD_AUTH
 diff -up openssh-5.2p1/auth2.c.selinux openssh-5.2p1/auth2.c
---- openssh-5.2p1/auth2.c.selinux	2008-11-05 06:20:46.000000000 +0100
-+++ openssh-5.2p1/auth2.c	2009-03-10 03:51:55.071216534 +0100
-@@ -215,7 +215,7 @@ input_userauth_request(int type, u_int32
+--- openssh-5.2p1/auth2.c.selinux	2008-07-05 01:44:53.000000000 +0200
++++ openssh-5.2p1/auth2.c	2008-07-23 16:32:13.000000000 +0200
+@@ -209,7 +209,7 @@ input_userauth_request(int type, u_int32
  {
  	Authctxt *authctxt = ctxt;
  	Authmethod *m = NULL;
@@ -42,7 +216,7 @@
  	int authenticated = 0;
  
  	if (authctxt == NULL)
-@@ -227,6 +227,9 @@ input_userauth_request(int type, u_int32
+@@ -221,6 +221,9 @@ input_userauth_request(int type, u_int32
  	debug("userauth-request for user %s service %s method %s", user, service, method);
  	debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
  
@@ -52,7 +226,7 @@
  	if ((style = strchr(user, ':')) != NULL)
  		*style++ = 0;
  
-@@ -252,8 +255,11 @@ input_userauth_request(int type, u_int32
+@@ -246,8 +249,11 @@ input_userauth_request(int type, u_int32
  		    use_privsep ? " [net]" : "");
  		authctxt->service = xstrdup(service);
  		authctxt->style = style ? xstrdup(style) : NULL;
@@ -65,141 +239,10 @@
  		userauth_banner();
  	} else if (strcmp(user, authctxt->user) != 0 ||
  	    strcmp(service, authctxt->service) != 0) {
-diff -up openssh-5.2p1/auth2-hostbased.c.selinux openssh-5.2p1/auth2-hostbased.c
---- openssh-5.2p1/auth2-hostbased.c.selinux	2008-07-17 10:57:19.000000000 +0200
-+++ openssh-5.2p1/auth2-hostbased.c	2009-03-10 03:51:55.052265447 +0100
-@@ -106,7 +106,14 @@ userauth_hostbased(Authctxt *authctxt)
- 	buffer_put_string(&b, session_id2, session_id2_len);
- 	/* reconstruct packet */
- 	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
--	buffer_put_cstring(&b, authctxt->user);
-+	if (authctxt->role) {
-+		buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1);
-+		buffer_append(&b, authctxt->user, strlen(authctxt->user));
-+		buffer_put_char(&b, '/');
-+		buffer_append(&b, authctxt->role, strlen(authctxt->role));
-+	} else {
-+		buffer_put_cstring(&b, authctxt->user);
-+	}
- 	buffer_put_cstring(&b, service);
- 	buffer_put_cstring(&b, "hostbased");
- 	buffer_put_string(&b, pkalg, alen);
-diff -up openssh-5.2p1/auth2-pubkey.c.selinux openssh-5.2p1/auth2-pubkey.c
---- openssh-5.2p1/auth2-pubkey.c.selinux	2008-07-04 04:54:25.000000000 +0200
-+++ openssh-5.2p1/auth2-pubkey.c	2009-03-10 03:51:56.174214480 +0100
-@@ -33,6 +33,7 @@
- #include <stdio.h>
- #include <stdarg.h>
- #include <unistd.h>
-+#include <openssl/fips.h>
- 
- #include "xmalloc.h"
- #include "ssh.h"
-@@ -117,7 +118,14 @@ userauth_pubkey(Authctxt *authctxt)
- 		}
- 		/* reconstruct packet */
- 		buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
--		buffer_put_cstring(&b, authctxt->user);
-+		if (authctxt->role) {
-+			buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1);
-+			buffer_append(&b, authctxt->user, strlen(authctxt->user));
-+			buffer_put_char(&b, '/');
-+			buffer_append(&b, authctxt->role, strlen(authctxt->role));
-+		} else {
-+			buffer_put_cstring(&b, authctxt->user);
-+		}
- 		buffer_put_cstring(&b,
- 		    datafellows & SSH_BUG_PKSERVICE ?
- 		    "ssh-userauth" :
-@@ -236,7 +244,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.2p1/auth.h.selinux openssh-5.2p1/auth.h
---- openssh-5.2p1/auth.h.selinux	2008-11-05 06:20:46.000000000 +0100
-+++ openssh-5.2p1/auth.h	2009-03-10 03:51:55.069276014 +0100
-@@ -58,6 +58,7 @@ struct Authctxt {
- 	char		*service;
- 	struct passwd	*pw;		/* set if 'valid' */
- 	char		*style;
-+	char		*role;
- 	void		*kbdintctxt;
- 	void		*jpake_ctx;
- #ifdef BSD_AUTH
-diff -up openssh-5.2p1/configure.ac.selinux openssh-5.2p1/configure.ac
---- openssh-5.2p1/configure.ac.selinux	2009-03-10 03:51:54.901396765 +0100
-+++ openssh-5.2p1/configure.ac	2009-03-10 03:51:55.850215090 +0100
-@@ -3335,11 +3335,25 @@ AC_ARG_WITH(selinux,
- 		AC_CHECK_LIB(selinux, setexeccon, [ LIBSELINUX="-lselinux" ],
- 		    AC_MSG_ERROR(SELinux support requires libselinux library))
- 		SSHDLIBS="$SSHDLIBS $LIBSELINUX"
-+		LIBS="$LIBS $LIBSELINUX"
- 		AC_CHECK_FUNCS(getseuserbyname get_default_context_with_level)
-+		AC_CHECK_FUNCS(setkeycreatecon)
- 		LIBS="$save_LIBS"
- 	fi ]
- )
- 
-+# Check whether user wants Linux audit support
-+LINUX_AUDIT_MSG="no"
-+AC_ARG_WITH(linux-audit,
-+	[  --with-linux-audit   Enable Linux audit support],
-+	[ if test "x$withval" != "xno" ; then
-+		AC_DEFINE(HAVE_LINUX_AUDIT,1,[Define if you want Linux audit support.])
-+		LINUX_AUDIT_MSG="yes"
-+		AC_CHECK_HEADERS(libaudit.h)
-+		SSHDLIBS="$SSHDLIBS -laudit"
-+	fi ]
-+)
-+
- # Check whether user wants Kerberos 5 support
- KRB5_MSG="no"
- AC_ARG_WITH(kerberos5,
-@@ -3448,6 +3462,20 @@ AC_ARG_WITH(kerberos5,
- 	]
- )
- 
-+# Check whether user wants NSS support
-+LIBNSS_MSG="no"
-+AC_ARG_WITH(nss,
-+	[  --with-nss   Enable NSS support],
-+	[ if test "x$withval" != "xno" ; then
-+		AC_DEFINE(HAVE_LIBNSS,1,[Define if you want NSS support.])
-+		LIBNSS_MSG="yes"
-+		CPPFLAGS="$CPPFLAGS -I/usr/include/nss3 -I/usr/include/nspr4"
-+		AC_CHECK_HEADERS(pk11pub.h)
-+		LIBS="$LIBS -lnss3"
-+	fi
-+	])
-+AC_SUBST(LIBNSS)
-+
- # Looking for programs, paths and files
- 
- PRIVSEP_PATH=/var/empty
-@@ -4168,12 +4196,14 @@ echo "                       PAM support
- echo "                   OSF SIA support: $SIA_MSG"
- echo "                 KerberosV support: $KRB5_MSG"
- echo "                   SELinux support: $SELINUX_MSG"
-+echo "               Linux audit support: $LINUX_AUDIT_MSG"
- echo "                 Smartcard support: $SCARD_MSG"
- echo "                     S/KEY support: $SKEY_MSG"
- echo "              TCP Wrappers support: $TCPW_MSG"
- echo "              MD5 password support: $MD5_MSG"
- echo "                   libedit support: $LIBEDIT_MSG"
- echo "  Solaris process contract support: $SPC_MSG"
-+echo "                       NSS support: $LIBNSS_MSG"
- echo "       IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
- echo "           Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
- echo "                  BSD Auth support: $BSD_AUTH_MSG"
 diff -up openssh-5.2p1/monitor.c.selinux openssh-5.2p1/monitor.c
---- openssh-5.2p1/monitor.c.selinux	2009-02-14 06:33:31.000000000 +0100
-+++ openssh-5.2p1/monitor.c	2009-03-10 03:51:55.099559692 +0100
-@@ -135,6 +135,7 @@ int mm_answer_sign(int, Buffer *);
+--- openssh-5.2p1/monitor.c.selinux	2008-07-11 09:36:48.000000000 +0200
++++ openssh-5.2p1/monitor.c	2008-07-23 16:36:10.000000000 +0200
+@@ -134,6 +134,7 @@ int mm_answer_sign(int, Buffer *);
  int mm_answer_pwnamallow(int, Buffer *);
  int mm_answer_auth2_read_banner(int, Buffer *);
  int mm_answer_authserv(int, Buffer *);
@@ -207,7 +250,7 @@
  int mm_answer_authpassword(int, Buffer *);
  int mm_answer_bsdauthquery(int, Buffer *);
  int mm_answer_bsdauthrespond(int, Buffer *);
-@@ -211,6 +212,7 @@ struct mon_table mon_dispatch_proto20[] 
+@@ -205,6 +206,7 @@ struct mon_table mon_dispatch_proto20[] 
      {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
      {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
      {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
@@ -215,7 +258,7 @@
      {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
      {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
  #ifdef USE_PAM
-@@ -680,6 +682,7 @@ mm_answer_pwnamallow(int sock, Buffer *m
+@@ -658,6 +660,7 @@ mm_answer_pwnamallow(int sock, Buffer *m
  	else {
  		/* Allow service/style information on the auth context */
  		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
@@ -223,7 +266,7 @@
  		monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
  	}
  
-@@ -725,6 +728,23 @@ mm_answer_authserv(int sock, Buffer *m)
+@@ -703,6 +706,23 @@ mm_answer_authserv(int sock, Buffer *m)
  }
  
  int
@@ -247,7 +290,7 @@
  mm_answer_authpassword(int sock, Buffer *m)
  {
  	static int call_count;
-@@ -1102,7 +1122,7 @@ static int
+@@ -1080,7 +1100,7 @@ static int
  monitor_valid_userblob(u_char *data, u_int datalen)
  {
  	Buffer b;
@@ -256,7 +299,7 @@
  	u_int len;
  	int fail = 0;
  
-@@ -1128,6 +1148,8 @@ monitor_valid_userblob(u_char *data, u_i
+@@ -1106,6 +1126,8 @@ monitor_valid_userblob(u_char *data, u_i
  	if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
  		fail++;
  	p = buffer_get_string(&b, NULL);
@@ -265,7 +308,7 @@
  	if (strcmp(authctxt->user, p) != 0) {
  		logit("wrong user name passed to monitor: expected %s != %.100s",
  		    authctxt->user, p);
-@@ -1159,7 +1181,7 @@ monitor_valid_hostbasedblob(u_char *data
+@@ -1137,7 +1159,7 @@ monitor_valid_hostbasedblob(u_char *data
      char *chost)
  {
  	Buffer b;
@@ -274,7 +317,7 @@
  	u_int len;
  	int fail = 0;
  
-@@ -1176,6 +1198,8 @@ monitor_valid_hostbasedblob(u_char *data
+@@ -1154,6 +1176,8 @@ monitor_valid_hostbasedblob(u_char *data
  	if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
  		fail++;
  	p = buffer_get_string(&b, NULL);
@@ -283,489 +326,3 @@
  	if (strcmp(authctxt->user, p) != 0) {
  		logit("wrong user name passed to monitor: expected %s != %.100s",
  		    authctxt->user, p);
-diff -up openssh-5.2p1/monitor.h.selinux openssh-5.2p1/monitor.h
---- openssh-5.2p1/monitor.h.selinux	2008-11-05 06:20:46.000000000 +0100
-+++ openssh-5.2p1/monitor.h	2009-03-10 03:51:55.050519421 +0100
-@@ -30,7 +30,7 @@
- 
- enum monitor_reqtype {
- 	MONITOR_REQ_MODULI, MONITOR_ANS_MODULI,
--	MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV,
-+	MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV,MONITOR_REQ_AUTHROLE,
- 	MONITOR_REQ_SIGN, MONITOR_ANS_SIGN,
- 	MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM,
- 	MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER,
-diff -up openssh-5.2p1/monitor_wrap.c.selinux openssh-5.2p1/monitor_wrap.c
---- openssh-5.2p1/monitor_wrap.c.selinux	2008-11-05 06:20:47.000000000 +0100
-+++ openssh-5.2p1/monitor_wrap.c	2009-03-10 03:51:55.066210099 +0100
-@@ -297,6 +297,23 @@ mm_inform_authserv(char *service, char *
- 	buffer_free(&m);
- }
- 
-+/* Inform the privileged process about role */
-+
-+void
-+mm_inform_authrole(char *role)
-+{
-+	Buffer m;
-+
-+	debug3("%s entering", __func__);
-+
-+	buffer_init(&m);
-+	buffer_put_cstring(&m, role ? role : "");
-+
-+	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m);
-+
-+	buffer_free(&m);
-+}
-+
- /* Do the password authentication */
- int
- mm_auth_password(Authctxt *authctxt, char *password)
-diff -up openssh-5.2p1/monitor_wrap.h.selinux openssh-5.2p1/monitor_wrap.h
---- openssh-5.2p1/monitor_wrap.h.selinux	2008-11-05 06:20:47.000000000 +0100
-+++ openssh-5.2p1/monitor_wrap.h	2009-03-10 03:51:55.048731957 +0100
-@@ -41,6 +41,7 @@ int mm_is_monitor(void);
- DH *mm_choose_dh(int, int, int);
- int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int);
- void mm_inform_authserv(char *, char *);
-+void mm_inform_authrole(char *);
- struct passwd *mm_getpwnamallow(const char *);
- char *mm_auth2_read_banner(void);
- int mm_auth_password(struct Authctxt *, char *);
-diff -up openssh-5.2p1/openbsd-compat/port-linux.c.selinux openssh-5.2p1/openbsd-compat/port-linux.c
---- openssh-5.2p1/openbsd-compat/port-linux.c.selinux	2008-03-26 21:27:21.000000000 +0100
-+++ openssh-5.2p1/openbsd-compat/port-linux.c	2009-03-10 03:51:55.407292576 +0100
-@@ -30,10 +30,28 @@
- #ifdef WITH_SELINUX
- #include "log.h"
- #include "port-linux.h"
-+#include "key.h"
-+#include "hostfile.h"
-+#include "auth.h"
-+#include "xmalloc.h"
-+#include "servconf.h"
- 
- #include <selinux/selinux.h>
- #include <selinux/flask.h>
-+#include <selinux/context.h>
- #include <selinux/get_context_list.h>
-+#include <selinux/get_default_type.h>
-+#include <selinux/av_permissions.h>
-+
-+#ifdef HAVE_LINUX_AUDIT
-+#include <libaudit.h>
-+#include <unistd.h>
-+#endif
-+
-+extern ServerOptions options;
-+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
-@@ -49,42 +67,245 @@ 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;
-+}
-+
-+static void
-+ssh_selinux_get_role_level(char **role, const char **level)
-+{
-+	*role = NULL;
-+	*level = NULL;
-+	if (the_authctxt) {
-+		if (the_authctxt->role != NULL) {
-+			char *slash;
-+			*role = xstrdup(the_authctxt->role);
-+			if ((slash = strchr(*role, '/')) != NULL) {
-+				*slash = '\0';
-+				*level = slash + 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;
--	char *sename = NULL, *lvl = NULL;
--	int r;
-+	char *sename, *lvl;
-+	const char *reqlvl;
-+	char *role;
-+	int r = -1;
-+	context_t con = NULL;
-+
-+	*default_sc = NULL;
-+	*user_sc = NULL;
-+
-+	ssh_selinux_get_role_level(&role, &reqlvl);
- 
- #ifdef HAVE_GETSEUSERBYNAME
--	if (getseuserbyname(pwname, &sename, &lvl) != 0)
--		return NULL;
-+	if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
-+		sename = NULL;
-+		lvl = NULL;
-+	}
- #else
- 	sename = pwname;
--	lvl = NULL;
-+	lvl = "";
- #endif
- 
-+	if (r == 0) {
- #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
--	r = get_default_context_with_level(sename, lvl, NULL, &sc);
-+		r = get_default_context_with_level(sename, lvl, NULL, default_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
-@@ -93,37 +314,114 @@ 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);
-+}
-+
-+/* Setup environment variables for pam_selinux */
-+static int
-+ssh_selinux_setup_pam_variables(void)
-+{
-+	const char *reqlvl;
-+	char *role;
-+	char *use_current;
-+	int rv;
-+
-+	debug3("%s: setting execution context", __func__);
-+
-+	ssh_selinux_get_role_level(&role, &reqlvl);
-+
-+	rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : "");
-+	
-+	if (inetd_flag && !rexeced_flag) {
-+		use_current = "1";
-+	} else {
-+		use_current = "";
-+		rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: "");
-+	}
-+
-+	rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current);
-+
-+	if (role != NULL)
-+		xfree(role);
-+	
-+	return rv;
- }
- 
- /* 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())
- 		return;
- 
-+	if (options.use_pam) {
-+		/* do not compute context, just setup environment for pam_selinux */
-+		if (ssh_selinux_setup_pam_variables()) {
-+			switch (security_getenforce()) {
-+			case -1:
-+				fatal("%s: security_getenforce() failed", __func__);
-+			case 0:
-+				error("%s: SELinux PAM variable setup failure. Continuing in permissive mode.",
-+				    __func__);
-+			break;
-+			default:
-+				fatal("%s: SELinux PAM variable setup failure. Aborting connection.",
-+				    __func__);
-+			}
-+		}
-+		return;
-+	}
-+
- 	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__);
- }
-@@ -141,7 +439,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? */
- 

openssh-5.2p1-vendor.patch:

Index: openssh-5.2p1-vendor.patch
===================================================================
RCS file: /cvs/pkgs/rpms/openssh/devel/openssh-5.2p1-vendor.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- openssh-5.2p1-vendor.patch	10 Mar 2009 11:54:44 -0000	1.1
+++ openssh-5.2p1-vendor.patch	10 Mar 2009 13:39:03 -0000	1.2
@@ -1,54 +1,7 @@
 diff -up openssh-5.2p1/configure.ac.vendor openssh-5.2p1/configure.ac
---- openssh-5.2p1/configure.ac.vendor	2009-03-10 03:51:54.862255585 +0100
-+++ openssh-5.2p1/configure.ac	2009-03-10 03:51:55.850215090 +0100
-@@ -3335,11 +3335,25 @@ AC_ARG_WITH(selinux,
- 		AC_CHECK_LIB(selinux, setexeccon, [ LIBSELINUX="-lselinux" ],
- 		    AC_MSG_ERROR(SELinux support requires libselinux library))
- 		SSHDLIBS="$SSHDLIBS $LIBSELINUX"
-+		LIBS="$LIBS $LIBSELINUX"
- 		AC_CHECK_FUNCS(getseuserbyname get_default_context_with_level)
-+		AC_CHECK_FUNCS(setkeycreatecon)
- 		LIBS="$save_LIBS"
- 	fi ]
- )
- 
-+# Check whether user wants Linux audit support
-+LINUX_AUDIT_MSG="no"
-+AC_ARG_WITH(linux-audit,
-+	[  --with-linux-audit   Enable Linux audit support],
-+	[ if test "x$withval" != "xno" ; then
-+		AC_DEFINE(HAVE_LINUX_AUDIT,1,[Define if you want Linux audit support.])
-+		LINUX_AUDIT_MSG="yes"
-+		AC_CHECK_HEADERS(libaudit.h)
-+		SSHDLIBS="$SSHDLIBS -laudit"
-+	fi ]
-+)
-+
- # Check whether user wants Kerberos 5 support
- KRB5_MSG="no"
- AC_ARG_WITH(kerberos5,
-@@ -3448,6 +3462,20 @@ AC_ARG_WITH(kerberos5,
- 	]
- )
- 
-+# Check whether user wants NSS support
-+LIBNSS_MSG="no"
-+AC_ARG_WITH(nss,
-+	[  --with-nss   Enable NSS support],
-+	[ if test "x$withval" != "xno" ; then
-+		AC_DEFINE(HAVE_LIBNSS,1,[Define if you want NSS support.])
-+		LIBNSS_MSG="yes"
-+		CPPFLAGS="$CPPFLAGS -I/usr/include/nss3 -I/usr/include/nspr4"
-+		AC_CHECK_HEADERS(pk11pub.h)
-+		LIBS="$LIBS -lnss3"
-+	fi
-+	])
-+AC_SUBST(LIBNSS)
-+
- # Looking for programs, paths and files
- 
- PRIVSEP_PATH=/var/empty
-@@ -3916,6 +3944,12 @@ AC_ARG_WITH(lastlog,
+--- openssh-5.2p1/configure.ac.vendor	2008-07-23 14:13:22.000000000 +0200
++++ openssh-5.2p1/configure.ac	2008-07-23 14:13:22.000000000 +0200
+@@ -3890,6 +3890,12 @@ AC_ARG_WITH(lastlog,
  		fi
  	]
  )
@@ -61,19 +14,7 @@
  
  dnl lastlog, [uw]tmpx? detection
  dnl  NOTE: set the paths in the platform section to avoid the
-@@ -4162,16 +4196,19 @@ echo "                       PAM support
- echo "                   OSF SIA support: $SIA_MSG"
- echo "                 KerberosV support: $KRB5_MSG"
- echo "                   SELinux support: $SELINUX_MSG"
-+echo "               Linux audit support: $LINUX_AUDIT_MSG"
- echo "                 Smartcard support: $SCARD_MSG"
- echo "                     S/KEY support: $SKEY_MSG"
- echo "              TCP Wrappers support: $TCPW_MSG"
- echo "              MD5 password support: $MD5_MSG"
- echo "                   libedit support: $LIBEDIT_MSG"
- echo "  Solaris process contract support: $SPC_MSG"
-+echo "                       NSS support: $LIBNSS_MSG"
- echo "       IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
+@@ -4146,6 +4152,7 @@ echo "       IP address in \$DISPLAY hac
  echo "           Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
  echo "                  BSD Auth support: $BSD_AUTH_MSG"
  echo "              Random number source: $RAND_MSG"
@@ -81,9 +22,38 @@
  if test ! -z "$USE_RAND_HELPER" ; then
  echo "     ssh-rand-helper collects from: $RAND_HELPER_MSG"
  fi
+diff -up openssh-5.2p1/sshd_config.5.vendor openssh-5.2p1/sshd_config.5
+--- openssh-5.2p1/sshd_config.5.vendor	2008-07-23 14:13:22.000000000 +0200
++++ openssh-5.2p1/sshd_config.5	2008-07-23 14:19:23.000000000 +0200
+@@ -812,6 +812,14 @@ This option applies to protocol version 
+ .It Cm ServerKeyBits
+ Defines the number of bits in the ephemeral protocol version 1 server key.
+ The minimum value is 512, and the default is 1024.
++.It Cm ShowPatchLevel 
++Specifies whether 
++.Nm sshd 
++will display the patch level of the binary in the identification string. 
++The patch level is set at compile-time. 
++The default is 
++.Dq no . 
++This option applies to protocol version 1 only. 
+ .It Cm StrictModes
+ Specifies whether
+ .Xr sshd 8
+diff -up openssh-5.2p1/servconf.h.vendor openssh-5.2p1/servconf.h
+--- openssh-5.2p1/servconf.h.vendor	2008-06-10 15:01:51.000000000 +0200
++++ openssh-5.2p1/servconf.h	2008-07-23 14:13:22.000000000 +0200
+@@ -126,6 +126,7 @@ typedef struct {
+ 	int	max_authtries;
+ 	int	max_sessions;
+ 	char   *banner;			/* SSH-2 banner message */
++	int	show_patchlevel;	/* Show vendor patch level to clients */
+ 	int	use_dns;
+ 	int	client_alive_interval;	/*
+ 					 * poke the client this often to
 diff -up openssh-5.2p1/servconf.c.vendor openssh-5.2p1/servconf.c
---- openssh-5.2p1/servconf.c.vendor	2009-01-28 06:31:23.000000000 +0100
-+++ openssh-5.2p1/servconf.c	2009-03-10 03:51:54.956273911 +0100
+--- openssh-5.2p1/servconf.c.vendor	2008-07-04 05:51:12.000000000 +0200
++++ openssh-5.2p1/servconf.c	2008-07-23 14:32:27.000000000 +0200
 @@ -117,6 +117,7 @@ initialize_server_options(ServerOptions 
  	options->max_authtries = -1;
  	options->max_sessions = -1;
@@ -138,21 +108,10 @@
  	dump_cfg_fmtint(sUseDNS, o->use_dns);
  	dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
  	dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
-diff -up openssh-5.2p1/servconf.h.vendor openssh-5.2p1/servconf.h
---- openssh-5.2p1/servconf.h.vendor	2009-01-28 06:31:23.000000000 +0100
-+++ openssh-5.2p1/servconf.h	2009-03-10 03:51:54.933236643 +0100
-@@ -128,6 +128,7 @@ typedef struct {
- 	int	max_authtries;
- 	int	max_sessions;
- 	char   *banner;			/* SSH-2 banner message */
-+	int	show_patchlevel;	/* Show vendor patch level to clients */
- 	int	use_dns;
- 	int	client_alive_interval;	/*
- 					 * poke the client this often to
 diff -up openssh-5.2p1/sshd_config.0.vendor openssh-5.2p1/sshd_config.0
---- openssh-5.2p1/sshd_config.0.vendor	2009-03-10 03:51:54.775230993 +0100
-+++ openssh-5.2p1/sshd_config.0	2009-03-10 03:51:54.958364611 +0100
-@@ -467,6 +467,11 @@ DESCRIPTION
+--- openssh-5.2p1/sshd_config.0.vendor	2008-07-23 14:13:22.000000000 +0200
++++ openssh-5.2p1/sshd_config.0	2008-07-23 14:13:22.000000000 +0200
+@@ -466,6 +466,11 @@ DESCRIPTION
               Defines the number of bits in the ephemeral protocol version 1
               server key.  The minimum value is 512, and the default is 1024.
  
@@ -164,27 +123,9 @@
       StrictModes
               Specifies whether sshd(8) should check file modes and ownership
               of the user's files and home directory before accepting login.
-diff -up openssh-5.2p1/sshd_config.5.vendor openssh-5.2p1/sshd_config.5
---- openssh-5.2p1/sshd_config.5.vendor	2009-03-10 03:51:54.785628316 +0100
-+++ openssh-5.2p1/sshd_config.5	2009-03-10 03:51:54.931352756 +0100
-@@ -814,6 +814,14 @@ This option applies to protocol version 
- .It Cm ServerKeyBits
- Defines the number of bits in the ephemeral protocol version 1 server key.
- The minimum value is 512, and the default is 1024.
-+.It Cm ShowPatchLevel 
-+Specifies whether 
-+.Nm sshd 
-+will display the patch level of the binary in the identification string. 
-+The patch level is set at compile-time. 
-+The default is 
-+.Dq no . 
-+This option applies to protocol version 1 only. 
- .It Cm StrictModes
- Specifies whether
- .Xr sshd 8
 diff -up openssh-5.2p1/sshd_config.vendor openssh-5.2p1/sshd_config
---- openssh-5.2p1/sshd_config.vendor	2009-03-10 03:51:54.747256884 +0100
-+++ openssh-5.2p1/sshd_config	2009-03-10 03:51:54.960221540 +0100
+--- openssh-5.2p1/sshd_config.vendor	2008-07-23 14:13:22.000000000 +0200
++++ openssh-5.2p1/sshd_config	2008-07-23 14:13:22.000000000 +0200
 @@ -112,6 +112,7 @@ X11Forwarding yes
  #Compression delayed
  #ClientAliveInterval 0
@@ -194,18 +135,9 @@
  #PidFile /var/run/sshd.pid
  #MaxStartups 10
 diff -up openssh-5.2p1/sshd.c.vendor openssh-5.2p1/sshd.c
---- openssh-5.2p1/sshd.c.vendor	2009-01-28 06:31:23.000000000 +0100
-+++ openssh-5.2p1/sshd.c	2009-03-10 03:51:56.224238563 +0100
-@@ -76,6 +76,8 @@
- #include <openssl/bn.h>
- #include <openssl/md5.h>
- #include <openssl/rand.h>
-+#include <openssl/fips.h>
-+#include <fipscheck.h>
- #include "openbsd-compat/openssl-compat.h"
- 
- #ifdef HAVE_SECUREWARE
-@@ -415,7 +417,7 @@ sshd_exchange_identification(int sock_in
+--- openssh-5.2p1/sshd.c.vendor	2008-07-11 09:36:49.000000000 +0200
++++ openssh-5.2p1/sshd.c	2008-07-23 14:35:43.000000000 +0200
+@@ -416,7 +416,7 @@ sshd_exchange_identification(int sock_in
  		minor = PROTOCOL_MINOR_1;
  	}
  	snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", major, minor,
@@ -214,40 +146,7 @@
  	server_version_string = xstrdup(buf);
  
  	/* Send our protocol version identification. */
-@@ -590,6 +592,10 @@ privsep_preauth_child(void)
- 	/* Demote the private keys to public keys. */
- 	demote_sensitive_data();
- 
-+	/* Open the syslog permanently so the chrooted process still
-+	   can write to syslog. */
-+	open_log();
-+	
- 	/* Change our root directory */
- 	if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1)
- 		fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR,
-@@ -1256,6 +1262,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 */
-@@ -1408,8 +1420,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)
-@@ -1483,7 +1493,8 @@ main(int ac, char **av)
+@@ -1484,7 +1484,8 @@ main(int ac, char **av)
  		exit(1);
  	}
  
@@ -257,33 +156,3 @@
  
  	/* Store privilege separation user for later use if required. */
  	if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
-@@ -1894,6 +1905,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);
-@@ -2174,6 +2188,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]);
-@@ -2183,6 +2200,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] =




More information about the fedora-extras-commits mailing list