mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 09:58:01 +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;
|
char *infile = NULL;
|
||||||
Filename *infilename = NULL, *outfilename = NULL;
|
Filename *infilename = NULL, *outfilename = NULL;
|
||||||
|
LoadedFile *infile_lf = NULL;
|
||||||
|
BinarySource *infile_bs = NULL;
|
||||||
enum { NOKEYGEN, RSA1, RSA2, DSA, ECDSA, ED25519 } keytype = NOKEYGEN;
|
enum { NOKEYGEN, RSA1, RSA2, DSA, ECDSA, ED25519 } keytype = NOKEYGEN;
|
||||||
char *outfile = NULL, *outfiletmp = NULL;
|
char *outfile = NULL, *outfiletmp = NULL;
|
||||||
enum { PRIVATE, PUBLIC, PUBLICO, FP, OPENSSH_AUTO,
|
enum { PRIVATE, PUBLIC, PUBLICO, FP, OPENSSH_AUTO,
|
||||||
@ -256,7 +258,7 @@ int main(int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
while (--argc) {
|
while (--argc) {
|
||||||
char *p = *++argv;
|
char *p = *++argv;
|
||||||
if (*p == '-') {
|
if (p[0] == '-' && p[1]) {
|
||||||
/*
|
/*
|
||||||
* An option.
|
* An option.
|
||||||
*/
|
*/
|
||||||
@ -562,9 +564,23 @@ int main(int argc, char **argv)
|
|||||||
* course of action.
|
* course of action.
|
||||||
*/
|
*/
|
||||||
if (infile) {
|
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) {
|
switch (intype) {
|
||||||
case SSH_KEYTYPE_UNOPENABLE:
|
case SSH_KEYTYPE_UNOPENABLE:
|
||||||
@ -751,11 +767,13 @@ int main(int argc, char **argv)
|
|||||||
* Find out whether the input key is encrypted.
|
* Find out whether the input key is encrypted.
|
||||||
*/
|
*/
|
||||||
if (intype == SSH_KEYTYPE_SSH1)
|
if (intype == SSH_KEYTYPE_SSH1)
|
||||||
encrypted = rsa1_encrypted_f(infilename, &origcomment);
|
encrypted = rsa1_encrypted_s(infile_bs, &origcomment);
|
||||||
else if (intype == SSH_KEYTYPE_SSH2)
|
else if (intype == SSH_KEYTYPE_SSH2)
|
||||||
encrypted = ppk_encrypted_f(infilename, &origcomment);
|
encrypted = ppk_encrypted_s(infile_bs, &origcomment);
|
||||||
else
|
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.
|
* If so, ask for a passphrase.
|
||||||
@ -799,7 +817,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
blob = strbuf_new();
|
blob = strbuf_new();
|
||||||
|
|
||||||
ret = rsa1_loadpub_f(infilename, BinarySink_UPCAST(blob),
|
ret = rsa1_loadpub_s(infile_bs, BinarySink_UPCAST(blob),
|
||||||
&origcomment, &error);
|
&origcomment, &error);
|
||||||
BinarySource_BARE_INIT(src, blob->u, blob->len);
|
BinarySource_BARE_INIT(src, blob->u, blob->len);
|
||||||
get_rsa_ssh1_pub(src, ssh1key, RSA_SSH1_EXPONENT_FIRST);
|
get_rsa_ssh1_pub(src, ssh1key, RSA_SSH1_EXPONENT_FIRST);
|
||||||
@ -811,8 +829,9 @@ int main(int argc, char **argv)
|
|||||||
ssh1key->q = NULL;
|
ssh1key->q = NULL;
|
||||||
ssh1key->iqmp = NULL;
|
ssh1key->iqmp = NULL;
|
||||||
} else {
|
} 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)
|
if (ret > 0)
|
||||||
error = NULL;
|
error = NULL;
|
||||||
else if (!error)
|
else if (!error)
|
||||||
@ -826,7 +845,7 @@ int main(int argc, char **argv)
|
|||||||
sfree(origcomment);
|
sfree(origcomment);
|
||||||
origcomment = NULL;
|
origcomment = NULL;
|
||||||
ssh2blob = strbuf_new();
|
ssh2blob = strbuf_new();
|
||||||
if (ppk_loadpub_f(infilename, &ssh2alg,
|
if (ppk_loadpub_s(infile_bs, &ssh2alg,
|
||||||
BinarySink_UPCAST(ssh2blob),
|
BinarySink_UPCAST(ssh2blob),
|
||||||
&origcomment, &error)) {
|
&origcomment, &error)) {
|
||||||
const ssh_keyalg *alg = find_pubkey_alg(ssh2alg);
|
const ssh_keyalg *alg = find_pubkey_alg(ssh2alg);
|
||||||
@ -841,8 +860,9 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
sfree(ssh2alg);
|
sfree(ssh2alg);
|
||||||
} else {
|
} 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)
|
if ((ssh2key && ssh2key != SSH2_WRONG_PASSPHRASE) || ssh2blob)
|
||||||
error = NULL;
|
error = NULL;
|
||||||
else if (!error) {
|
else if (!error) {
|
||||||
@ -856,7 +876,7 @@ int main(int argc, char **argv)
|
|||||||
case SSH_KEYTYPE_OPENSSH_PEM:
|
case SSH_KEYTYPE_OPENSSH_PEM:
|
||||||
case SSH_KEYTYPE_OPENSSH_NEW:
|
case SSH_KEYTYPE_OPENSSH_NEW:
|
||||||
case SSH_KEYTYPE_SSHCOM:
|
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) {
|
||||||
if (ssh2key != SSH2_WRONG_PASSPHRASE)
|
if (ssh2key != SSH2_WRONG_PASSPHRASE)
|
||||||
error = NULL;
|
error = NULL;
|
||||||
@ -1105,6 +1125,8 @@ int main(int argc, char **argv)
|
|||||||
sfree(origcomment);
|
sfree(origcomment);
|
||||||
if (infilename)
|
if (infilename)
|
||||||
filename_free(infilename);
|
filename_free(infilename);
|
||||||
|
if (infile_lf)
|
||||||
|
lf_free(infile_lf);
|
||||||
if (outfilename)
|
if (outfilename)
|
||||||
filename_free(outfilename);
|
filename_free(outfilename);
|
||||||
sfree(outfiletmp);
|
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_blob(ptrlen);
|
||||||
char *ssh2_fingerprint(ssh_key *key);
|
char *ssh2_fingerprint(ssh_key *key);
|
||||||
int key_type(const Filename *filename);
|
int key_type(const Filename *filename);
|
||||||
|
int key_type_s(BinarySource *src);
|
||||||
const char *key_type_to_str(int type);
|
const char *key_type_to_str(int type);
|
||||||
|
|
||||||
bool import_possible(int type);
|
bool import_possible(int type);
|
||||||
|
@ -146,8 +146,6 @@ LoadedFile *lf_load_keyfile_fp(FILE *fp, const char **errptr)
|
|||||||
return lf;
|
return lf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int key_type_s(BinarySource *src);
|
|
||||||
|
|
||||||
static bool expect_signature(BinarySource *src, ptrlen realsig)
|
static bool expect_signature(BinarySource *src, ptrlen realsig)
|
||||||
{
|
{
|
||||||
ptrlen thissig = get_data(src, realsig.len);
|
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 */
|
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);
|
int toret = key_type_s_internal(src);
|
||||||
BinarySource_REWIND(src);
|
BinarySource_REWIND(src);
|
||||||
|
Loading…
Reference in New Issue
Block a user