# HG changeset patch
# Parent 1f5547f74053e9e304cf2759379f91d4f7d5f04e

diff --git a/openssh-5.1p1/converter/Makefile b/openssh-5.1p1/converter/Makefile
new file mode 100644
--- /dev/null
+++ b/openssh-5.1p1/converter/Makefile
@@ -0,0 +1,17 @@
+
+bindir=/usr/bin
+mandir=/usr/share/man
+
+all :	ssh-keyconverter
+
+ssh-keyconverter.o: ssh-keyconverter.c ../key.h ../authfile.h ../misc.h ../xmalloc.h
+	gcc $(RPM_OPT_FLAGS) -c -I../ $< -o $@
+
+ssh-keyconverter: ssh-keyconverter.o ../libssh.a ../openbsd-compat/libopenbsd-compat.a
+	gcc $< -L../ -L../openbsd-compat/ -lssh -lopenbsd-compat -lssh -lpam -ldl -lwrap -lutil -lz -lnsl -lcrypt -lssl -o $@
+
+install: ssh-keyconverter ssh-keyconverter.1
+	if [ ! -d $(DESTDIR)$(bindir) ]; then install -d -m 755 $(DESTDIR)$(bindir); fi
+	install -m 755 ssh-keyconverter $(DESTDIR)$(bindir)
+	if [ ! -d $(DESTDIR)$(mandir)/man1 ]; then install -d -m 755 $(DESTDIR)$(mandir)/man1; fi
+	install -m 644 ssh-keyconverter.1 $(DESTDIR)$(mandir)/man1
diff --git a/openssh-5.1p1/converter/ssh-keyconverter.1 b/openssh-5.1p1/converter/ssh-keyconverter.1
new file mode 100644
--- /dev/null
+++ b/openssh-5.1p1/converter/ssh-keyconverter.1
@@ -0,0 +1,155 @@
+.\" Manpage for ssh-keyconverter
+.\"
+.Dd February 2, 2002
+.Dt SSH-KEYCONVER 1
+.Os
+.Sh NAME
+.Nm ssh-keyconvert
+.Nd convert ssh v1 keys and authorization files
+.Sh SYNOPSIS
+.Nm ssh-keyconvert
+.Op Fl k
+.Op Fl o Ar output_file
+.Ar identity_file ...
+.Nm ssh-keyconvert
+.Op Fl a
+.Op Fl o Ar output_file
+.Ar authorization_file ...
+.Sh DESCRIPTION
+.Nm
+converts RSA public and private keys used for public key based
+user authentication with protocol version 1 to the format
+used with protocol version 2.
+.Pp
+When using RSA user authentication with SSH protocol version 1,
+the client uses the private key from
+.Pa $HOME/.ssh/identity
+to provide its identity to the server. The server grants or denies
+access based on whether the public part of this key is listed in
+.Pa $HOME/.ssh/authorized_keys .
+.Pp
+SSH protocol version 2 supports both DSA and RSA keys, but the
+way RSA keys are stored are differently. On the client, the default
+file name is
+.Pa .ssh/id_rsa
+rather than
+.Pa .ssh/identity ,
+and the file's format is different as well. On the server, the
+public porting of the key can still be stored in
+.Pa .ssh/authorized_keys ,
+but the key notation has changed as well.
+Therefore, when switching from protocol version 1
+to version 2, you either have to create a new identity key using
+.Xr ssh-keygen 1
+and add that key to the server's
+.Pa authorized_keys
+file, or you need to convert your keys using
+.Nm ssh-keyconvert .
+.Pp
+By default,
+.Nm
+will try to guess the type of file that is to be converted.
+If it fails to guess correctly, you can tell if what type of
+conversion to perform by specifying the
+.Fl k
+option to convert the private key, or the
+.Fl a
+option to convert an authorisation file.
+.Pp
+When converting your private keys stored in
+.Pa .ssh/identity ,
+.Nm
+will read the private key, prompting you for the pass phrase
+if the key is protected by a pass phrase. If the
+.Fl o
+option is given, it will write the private key to the specified
+file, using version 2 syntax. If the key was protected by a
+pass phrase, it will use the same pass phrase to protect the new
+file.
+It will also write the public portion of the key to a second file,
+using the specified file name with
+.Dq .pub
+appended.
+If the 
+.Fl o
+option was not given, private and public key will be written to
+.Pa id_rsa
+and
+.Pa id_rsa.pub ,
+respectively, relative to the directory of the input key file.
+.Pp
+If the destination file already exists,
+.Nm
+will prompt the user for confirmation before overwriting the
+file, unless the
+.Fl f
+option is given.
+.Pp
+When converting your
+.Pa authorized_keys
+file,
+.Nm
+will ignore any keys in SSH version 2 format. Any public keys
+in version 1 format will be converted and appended to the output file
+using the new syntax. If the
+.Fl o
+option is given, keys are appended to the specified file. If it
+is not given,
+.Nm
+will append all keys to the input file.
+.Pp
+Note that
+.Nm
+does not check for duplicate keys, so if you run it on
+.Pa .ssh/authorized_keys
+more several times, the converted keys will show up several times.
+.Sh OPTIONS
+.Bl -tag -width Ds
+.It Fl k
+Convert private key file(s). The default is to guess the
+type of file that should be converted.
+.It Fl a
+Convert 
+.Pa authorized_keys
+file(s). The default is to guess the
+type of file that should be converted.
+.It Fl o Ar outfile
+Specify the name of the output file.
+When converting an authorization file, all public keys will
+be appended to this file.
+For private key conversion, the private and public components of
+the key will be stored in
+.Pa outfile
+and
+.Pa outfile.pub ,
+respectively.
+Note that since every key must be stored in a separate file, you
+cannot use this option when you specify several input files.
+.It Fl f
+When converting a key file, and the output file already exists,
+.Nm
+will ask the user whether to overwrite the file. Using this option
+forces overwriting.
+.El
+.Sh AUTHORS
+OpenSSH is a derivative of the original and free
+ssh 1.2.12 release by Tatu Ylonen.
+Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
+Theo de Raadt and Dug Song
+removed many bugs, re-added newer features and
+created OpenSSH.
+.Nm
+was contributed by Olaf Kirch.
+.Sh SEE ALSO
+.Xr ssh 1 ,
+.Xr ssh-add 1 ,
+.Xr ssh-agent 1 ,
+.Xr sshd 8
+.Rs
+.%A J. Galbraith
+.%A R. Thayer
+.%T "SECSH Public Key File Format"
+.%N draft-ietf-secsh-publickeyfile-01.txt
+.%D March 2001
+.%O work in progress material
+.Re
diff --git a/openssh-5.1p1/converter/ssh-keyconverter.c b/openssh-5.1p1/converter/ssh-keyconverter.c
new file mode 100644
--- /dev/null
+++ b/openssh-5.1p1/converter/ssh-keyconverter.c
@@ -0,0 +1,345 @@
+/*
+ * SSH v1 to v2 RSA key converter.
+ *
+ * Instead of a manpage:
+ *
+ *	ssh-keyconverter ~/.ssh/identity
+ *		will put the old RSA key in ~/.ssh/id_rsa and id_rsa.pub
+ *		If a "-o foofah" is given, the keys will be written to
+ *		foofah and foofah.pub, respectively.
+ *
+ *	ssh-keyconverter ~/.ssh/authorized_keys
+ *		will convert all old RSA keys and add them to the
+ *		input file. The -o foofah option will direct
+ *		output to a different file.
+ *		(Note that it's harmless to specify the same file
+ *		as input and output, as ssh-keyconverter will ignore
+ *		any v2 keys, and output is always appended, never
+ *		replacing the original file).
+ *
+ * To compile:
+ *
+ *  gcc -g -Wall -o ssh-keyconverter converter.c \
+ *		-L. -Lopenbsd-compat/  -lssh -lopenbsd-compat -lssh \
+ *		-lpam -ldl -lwrap -lutil -lz -lnsl \
+ *		-Wl,-Bstatic -lcrypto -Wl,-dy
+ *
+ * Enjoy. --okir
+ */
+
+#include <stdio.h>
+#include <getopt.h>
+#include <string.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include "key.h"
+#include "authfile.h"
+#include "misc.h"
+#include "xmalloc.h"
+
+#define TYPE_KEY		0
+#define TYPE_AUTHKEYS		1
+
+#define PASSPHRASE_ATTEMPTS	3
+
+static int	opt_verbose = 0;
+static int	opt_force = 0;
+
+static void	convert(int, const char *, const char *);
+static void	convert_private_key(const char *, const char *);
+static void	convert_authorized_keys(const char *, const char *);
+static int	fileok(const char *, char *, size_t);
+static int	guess_type(const char *);
+
+int
+main(int argc, char **argv)
+{
+	int	opt_type = -1;
+	char	*opt_outfile = NULL;
+	int	c;
+
+	while ((c = getopt(argc, argv, "afko:")) != -1) {
+		switch (c) {
+		case 'a':
+			opt_type = TYPE_AUTHKEYS;
+			break;
+		case 'f':
+			opt_force = 1;
+			break;
+		case 'k':
+			opt_type = TYPE_KEY;
+			break;
+		case 'o':
+			opt_outfile = optarg;
+			break;
+		case 'v':
+			opt_verbose++;
+			break;
+		default:
+			fprintf(stderr,
+				"usage: ssh-keyconvert [-a | -k] "
+				"[-o filename] [-v] ...\n");
+			exit(1);
+		}
+	}
+
+	/* Warning, nanny code follows */
+#if 0
+	if (opt_outfile && (argc - optind) > 1 && opt_type != TYPE_AUTHKEY) {
+		fprintf(stderr,
+			"Output file ambiguous: more than two "
+			"input files given. Abort.\n");
+		exit(1);
+	}
+#endif
+
+	if (optind == argc) {
+		fprintf(stderr,
+			"Missing input file(s).\n");
+		exit(1);
+	}
+
+	for (; optind < argc; optind++) {
+		char	*name = argv[optind];
+		int	type;
+
+		if ((type = opt_type) < 0)
+			type = guess_type(name);
+		convert(type, name, opt_outfile);
+	}
+
+	return 0;
+}
+
+static void
+convert(int type, const char *iname, const char *oname)
+{
+	if (type == TYPE_KEY) {
+		convert_private_key(iname, oname);
+	} else if (type == TYPE_AUTHKEYS) {
+		convert_authorized_keys(iname, oname);
+	} else {
+		fprintf(stderr,
+			"Conversion type not yet implemented.\n");
+		exit(1);
+	}
+}
+
+static void
+convert_private_key(const char *iname, const char *oname)
+{
+	char	prompt[1024], privname[PATH_MAX], pubname[PATH_MAX];
+	char	*comment = NULL, *passphrase;
+	Key	*key = NULL, *pk = NULL;
+	int	i;
+	FILE	*pf = NULL;
+
+	passphrase = xstrdup("");
+	snprintf(prompt, sizeof(prompt),
+		"Enter passphrase for key '%.100s': ",iname);
+	for (i = 0; !key && i < PASSPHRASE_ATTEMPTS; i++) {
+		if (i) {
+			/* Zap old pass phrase */
+			memset(passphrase, 0, strlen(passphrase));
+			xfree(passphrase);
+
+			/* Get a pass phrase from the user */
+			passphrase = read_passphrase(prompt, 0);
+		}
+		key = key_load_private(iname, passphrase, &comment);
+		if (!key && i)
+			printf("Bad passphrase, please try again.\n");
+	}
+
+	if (oname != NULL) {
+		strcpy(privname, oname);
+	} else {
+		const char	*s;
+
+		if ((s = strrchr(iname, '/')) != NULL) {
+			int	n = s + 1 - iname;
+
+			strncpy(privname, iname, n);
+			privname[n++] = '\0';
+		}
+		strcat(privname, "id_rsa");
+	}
+
+	if (!fileok("private", privname, sizeof(privname)))
+		goto out;
+
+	sprintf(pubname, "%s.pub", privname);
+	if (!fileok("public",  pubname, sizeof(pubname)))
+		goto out;
+
+	/* "convert" from RSA1 to RSA */
+	key->type = KEY_RSA;
+	pk = key_from_private(key);
+
+	/* Now write the key in earnest */
+	if (!key_save_private(key, privname, passphrase, comment)) {
+		fprintf(stderr,
+			"Failed to save private key to %s: %m.\n", privname);
+		goto out;
+	}
+
+	if (!(pf = fopen(pubname, "w"))) {
+		fprintf(stderr,
+			"Failed to save public key to %s: %m.\n", pubname);
+		goto out;
+	}
+	if (!key_write(pk, pf)) {
+		fprintf(stderr,
+			"Failed to save public key to %s: %m.\n", pubname);
+		goto out;
+	}
+	if (comment)
+		fprintf(pf, " %s\n", comment);
+
+out:
+	memset(passphrase, 0, strlen(passphrase));
+	xfree(passphrase);
+	if (key)
+		key_free(key);
+	if (pk)
+		key_free(pk);
+	if (pf)
+		fclose(pf);
+}
+
+static void
+convert_authorized_keys(const char *iname, const char *oname)
+{
+	char	line[1024];
+	FILE	*ifp, *ofp;
+	Key	*key;
+
+	if (!(ifp = fopen(iname, "r"))) {
+		perror(iname);
+		exit(1);
+	}
+
+	if (oname == NULL)
+		oname = iname;
+
+	if (!strcmp(oname, "-")) {
+		ofp = stdout;
+	} else {
+		if ((ofp = fopen(oname, "a")) == NULL) {
+			perror(oname);
+			exit(1);
+		}
+	}
+	setlinebuf(ofp);
+
+#define whitespace(c)	((c) == ' ' || (c) == '\t')
+	while (fgets(line, sizeof(line), ifp) != NULL) {
+		char	*cp = line, *options = NULL;
+
+		while (whitespace(*cp))
+			cp++;
+		if (!*cp || *cp == '\n' || *cp == '#')
+			continue;
+
+		key = key_new(KEY_RSA1);
+		if (key_read(key, &cp) != 1) {
+			/* Skip options, if any */
+			int	quoted = 0;
+
+			options = cp;
+			for (; *cp && (quoted || !whitespace(*cp)); cp++) {
+				if (cp[0] == '\\' && cp[1] == '"')
+					++cp;
+				else if (*cp == '"')
+					quoted = !quoted;
+			}
+			if (quoted)
+				goto next;
+			*cp++ = '\0';
+			while (whitespace(*cp))
+				cp++;
+			if (key_read(key, &cp) != 1) 
+				goto next;
+		}
+
+		if (options)
+			fprintf(ofp, "%s ", options);
+		/* "convert" from RSA1 to RSA */
+		key->type = KEY_RSA;
+		key_write(key, ofp);
+		fputs(cp, ofp);
+		key_free(key);
+
+	next:
+		;
+	}
+}
+
+/* if file exists, ask user whether to overwrite it */
+static int
+fileok(const char *what, char *filename, size_t size)
+{
+	char	buffer[PATH_MAX];
+	int	n;
+
+checkagain:
+	if (access(filename, F_OK) < 0)
+		return 1;
+	printf("%s key file %s already exists.\n", what, filename);
+	if (opt_force) {
+		printf("Overwriting because of -f option...\n");
+		return 1;
+	}
+
+tryagain:
+	printf("Please enter a different filename, "
+		"or return to overwrite: ");
+	fflush(stdout);
+
+	n = read(0, buffer, sizeof(buffer)-1);
+	if (n <= 0)
+		printf("\n");
+	if (n < 0) {
+		perror("read failed");
+		exit(1);
+	}
+	if (n == 0) {
+		fprintf(stderr, "EOF from standard input. Bye.\n");
+		exit(1);
+	}
+	buffer[n] = '\0';
+	while (n && buffer[n-1] == '\n')
+		buffer[--n] = '\0';
+	if (n == 0)
+		return 1;
+	if (n >= size) {
+		fprintf(stderr, "Filename too long.\n");
+		goto tryagain;
+	}
+	strcpy(filename, buffer);
+	goto checkagain;
+}
+
+/*
+ * Guess the type of file to be converted.
+ * XXX: should look at the file; v1 key files
+ * start with "SSH PRIVATE KEY FILE"
+ */
+static int
+guess_type(const char *name)
+{
+	printf("%s... ", name);
+	if (strstr(name, "identity")) {
+		printf("looks like a key file\n");
+		return TYPE_KEY;
+	}
+	if (strstr(name, "authorized_keys")) {
+		printf("looks like an authorized_keys file\n");
+		return TYPE_AUTHKEYS;
+	}
+
+	if (opt_verbose)
+		printf("unable to identify.");
+	fprintf(stderr, "Please specify the file type for %s. Abort.\n", name);
+	exit(1);
+}
