mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 09:27:59 +00:00
Allow cmdgen to read keys from standard input.
This reworks the cmdgen main program so that it loads the input file into a LoadedFile right at the start, and then every time it needs to do something with the contents, it calls one of the API functions taking a BinarySource instead of one taking a Filename. The usefulness of this is that now we can read from things that aren't regular files, and can't be rewound or reopened. In particular, the filename "-" is now taken (per the usual convention) to mean standard input. So now you can pipe a public or private key file into cmdgen's standard input and have it do something useful. For example, I was recently experimenting with the SFTP-only SSH server that comes with 'proftpd', which keeps its authorized_keys file in RFC 4716 format instead of the OpenSSH one-liner format, and I found I wanted to do grep 'my-key-comment' ~/.ssh/authorized_keys | puttygen -p - to quickly get hold of my existing public key to put in that file. But I had to go via a temporary file to make that work, because puttygen couldn't read from standard input. Next time, it will be able to!
This commit is contained in:
parent
36d214c50b
commit
7599a57a33
44
cmdgen.c
44
cmdgen.c
@ -215,6 +215,8 @@ int main(int argc, char **argv)
|
||||
{
|
||||
char *infile = NULL;
|
||||
Filename *infilename = NULL, *outfilename = NULL;
|
||||
LoadedFile *infile_lf = NULL;
|
||||
BinarySource *infile_bs = NULL;
|
||||
enum { NOKEYGEN, RSA1, RSA2, DSA, ECDSA, ED25519 } keytype = NOKEYGEN;
|
||||
char *outfile = NULL, *outfiletmp = NULL;
|
||||
enum { PRIVATE, PUBLIC, PUBLICO, FP, OPENSSH_AUTO,
|
||||
@ -256,7 +258,7 @@ int main(int argc, char **argv)
|
||||
*/
|
||||
while (--argc) {
|
||||
char *p = *++argv;
|
||||
if (*p == '-') {
|
||||
if (p[0] == '-' && p[1]) {
|
||||
/*
|
||||
* An option.
|
||||
*/
|
||||
@ -562,9 +564,23 @@ int main(int argc, char **argv)
|
||||
* course of action.
|
||||
*/
|
||||
if (infile) {
|
||||
infilename = filename_from_str(infile);
|
||||
const char *load_error;
|
||||
|
||||
intype = key_type(infilename);
|
||||
infilename = filename_from_str(infile);
|
||||
if (!strcmp(infile, "-"))
|
||||
infile_lf = lf_load_keyfile_fp(stdin, &load_error);
|
||||
else
|
||||
infile_lf = lf_load_keyfile(infilename, &load_error);
|
||||
|
||||
if (!infile_lf) {
|
||||
fprintf(stderr, "puttygen: unable to load file `%s': %s\n",
|
||||
infile, load_error);
|
||||
RETURN(1);
|
||||
}
|
||||
|
||||
infile_bs = BinarySource_UPCAST(infile_lf);
|
||||
intype = key_type_s(infile_bs);
|
||||
BinarySource_REWIND(infile_bs);
|
||||
|
||||
switch (intype) {
|
||||
case SSH_KEYTYPE_UNOPENABLE:
|
||||
@ -751,11 +767,13 @@ int main(int argc, char **argv)
|
||||
* Find out whether the input key is encrypted.
|
||||
*/
|
||||
if (intype == SSH_KEYTYPE_SSH1)
|
||||
encrypted = rsa1_encrypted_f(infilename, &origcomment);
|
||||
encrypted = rsa1_encrypted_s(infile_bs, &origcomment);
|
||||
else if (intype == SSH_KEYTYPE_SSH2)
|
||||
encrypted = ppk_encrypted_f(infilename, &origcomment);
|
||||
encrypted = ppk_encrypted_s(infile_bs, &origcomment);
|
||||
else
|
||||
encrypted = import_encrypted(infilename, intype, &origcomment);
|
||||
encrypted = import_encrypted_s(infilename, infile_bs,
|
||||
intype, &origcomment);
|
||||
BinarySource_REWIND(infile_bs);
|
||||
|
||||
/*
|
||||
* If so, ask for a passphrase.
|
||||
@ -799,7 +817,7 @@ int main(int argc, char **argv)
|
||||
|
||||
blob = strbuf_new();
|
||||
|
||||
ret = rsa1_loadpub_f(infilename, BinarySink_UPCAST(blob),
|
||||
ret = rsa1_loadpub_s(infile_bs, BinarySink_UPCAST(blob),
|
||||
&origcomment, &error);
|
||||
BinarySource_BARE_INIT(src, blob->u, blob->len);
|
||||
get_rsa_ssh1_pub(src, ssh1key, RSA_SSH1_EXPONENT_FIRST);
|
||||
@ -811,8 +829,9 @@ int main(int argc, char **argv)
|
||||
ssh1key->q = NULL;
|
||||
ssh1key->iqmp = NULL;
|
||||
} else {
|
||||
ret = rsa1_load_f(infilename, ssh1key, old_passphrase, &error);
|
||||
ret = rsa1_load_s(infile_bs, ssh1key, old_passphrase, &error);
|
||||
}
|
||||
BinarySource_REWIND(infile_bs);
|
||||
if (ret > 0)
|
||||
error = NULL;
|
||||
else if (!error)
|
||||
@ -826,7 +845,7 @@ int main(int argc, char **argv)
|
||||
sfree(origcomment);
|
||||
origcomment = NULL;
|
||||
ssh2blob = strbuf_new();
|
||||
if (ppk_loadpub_f(infilename, &ssh2alg,
|
||||
if (ppk_loadpub_s(infile_bs, &ssh2alg,
|
||||
BinarySink_UPCAST(ssh2blob),
|
||||
&origcomment, &error)) {
|
||||
const ssh_keyalg *alg = find_pubkey_alg(ssh2alg);
|
||||
@ -841,8 +860,9 @@ int main(int argc, char **argv)
|
||||
}
|
||||
sfree(ssh2alg);
|
||||
} else {
|
||||
ssh2key = ppk_load_f(infilename, old_passphrase, &error);
|
||||
ssh2key = ppk_load_s(infile_bs, old_passphrase, &error);
|
||||
}
|
||||
BinarySource_REWIND(infile_bs);
|
||||
if ((ssh2key && ssh2key != SSH2_WRONG_PASSPHRASE) || ssh2blob)
|
||||
error = NULL;
|
||||
else if (!error) {
|
||||
@ -856,7 +876,7 @@ int main(int argc, char **argv)
|
||||
case SSH_KEYTYPE_OPENSSH_PEM:
|
||||
case SSH_KEYTYPE_OPENSSH_NEW:
|
||||
case SSH_KEYTYPE_SSHCOM:
|
||||
ssh2key = import_ssh2(infilename, intype, old_passphrase, &error);
|
||||
ssh2key = import_ssh2_s(infile_bs, intype, old_passphrase, &error);
|
||||
if (ssh2key) {
|
||||
if (ssh2key != SSH2_WRONG_PASSPHRASE)
|
||||
error = NULL;
|
||||
@ -1105,6 +1125,8 @@ int main(int argc, char **argv)
|
||||
sfree(origcomment);
|
||||
if (infilename)
|
||||
filename_free(infilename);
|
||||
if (infile_lf)
|
||||
lf_free(infile_lf);
|
||||
if (outfilename)
|
||||
filename_free(outfilename);
|
||||
sfree(outfiletmp);
|
||||
|
1
ssh.h
1
ssh.h
@ -1260,6 +1260,7 @@ void ssh2_write_pubkey(FILE *fp, const char *comment,
|
||||
char *ssh2_fingerprint_blob(ptrlen);
|
||||
char *ssh2_fingerprint(ssh_key *key);
|
||||
int key_type(const Filename *filename);
|
||||
int key_type_s(BinarySource *src);
|
||||
const char *key_type_to_str(int type);
|
||||
|
||||
bool import_possible(int type);
|
||||
|
@ -146,8 +146,6 @@ LoadedFile *lf_load_keyfile_fp(FILE *fp, const char **errptr)
|
||||
return lf;
|
||||
}
|
||||
|
||||
static int key_type_s(BinarySource *src);
|
||||
|
||||
static bool expect_signature(BinarySource *src, ptrlen realsig)
|
||||
{
|
||||
ptrlen thissig = get_data(src, realsig.len);
|
||||
@ -1678,7 +1676,7 @@ static int key_type_s_internal(BinarySource *src)
|
||||
return SSH_KEYTYPE_UNKNOWN; /* unrecognised or EOF */
|
||||
}
|
||||
|
||||
static int key_type_s(BinarySource *src)
|
||||
int key_type_s(BinarySource *src)
|
||||
{
|
||||
int toret = key_type_s_internal(src);
|
||||
BinarySource_REWIND(src);
|
||||
|
Loading…
Reference in New Issue
Block a user