mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Unix Pageant: -E option to load key files encrypted.
This applies to both server modes ('pageant -E key.ppk [lifetime]') and client mode ('pageant -a -E key.ppk'). I'm not completely confident that the CLI syntax is actually right yet, but for the moment, it's enough that it _exists_. Now I don't have to test the encrypted-key loading via manually mocked-up agent requests.
This commit is contained in:
parent
8677ee00fb
commit
55005a08ea
39
pageant.c
39
pageant.c
@ -1604,7 +1604,7 @@ void *pageant_get_keylist2(int *length)
|
||||
}
|
||||
|
||||
int pageant_add_keyfile(Filename *filename, const char *passphrase,
|
||||
char **retstr)
|
||||
char **retstr, bool add_encrypted)
|
||||
{
|
||||
RSAKey *rkey = NULL;
|
||||
ssh2_userkey *skey = NULL;
|
||||
@ -1629,6 +1629,11 @@ int pageant_add_keyfile(Filename *filename, const char *passphrase,
|
||||
return PAGEANT_ACTION_FAILURE;
|
||||
}
|
||||
|
||||
if (add_encrypted && type == SSH_KEYTYPE_SSH1) {
|
||||
*retstr = dupprintf("Can't add SSH-1 keys in encrypted form");
|
||||
return PAGEANT_ACTION_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if the key is already loaded (in the primary Pageant,
|
||||
* which may or may not be us).
|
||||
@ -1747,6 +1752,38 @@ int pageant_add_keyfile(Filename *filename, const char *passphrase,
|
||||
strbuf_free(blob);
|
||||
}
|
||||
|
||||
if (add_encrypted) {
|
||||
const char *load_error;
|
||||
LoadedFile *lf = lf_load_keyfile(filename, &load_error);
|
||||
if (!lf) {
|
||||
*retstr = dupstr(load_error);
|
||||
return PAGEANT_ACTION_FAILURE;
|
||||
}
|
||||
|
||||
strbuf *request = strbuf_new_for_agent_query();
|
||||
put_byte(request, SSH2_AGENTC_EXTENSION);
|
||||
put_stringpl(request, PUTTYEXT("add-ppk"));
|
||||
put_string(request, lf->data, lf->len);
|
||||
|
||||
lf_free(lf);
|
||||
|
||||
void *vresponse;
|
||||
int resplen;
|
||||
pageant_client_query(request, &vresponse, &resplen);
|
||||
strbuf_free(request);
|
||||
|
||||
unsigned char *response = vresponse;
|
||||
if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS) {
|
||||
*retstr = dupstr("The already running Pageant "
|
||||
"refused to add the key.");
|
||||
sfree(response);
|
||||
return PAGEANT_ACTION_FAILURE;
|
||||
}
|
||||
|
||||
sfree(response);
|
||||
return PAGEANT_ACTION_OK;
|
||||
}
|
||||
|
||||
error = NULL;
|
||||
if (type == SSH_KEYTYPE_SSH1)
|
||||
needs_pass = rsa1_encrypted_f(filename, &comment);
|
||||
|
@ -220,7 +220,7 @@ enum {
|
||||
PAGEANT_ACTION_NEED_PP /* need passphrase: *retstr is key comment */
|
||||
};
|
||||
int pageant_add_keyfile(Filename *filename, const char *passphrase,
|
||||
char **retstr);
|
||||
char **retstr, bool add_encrypted);
|
||||
void pageant_forget_passphrases(void);
|
||||
|
||||
struct pageant_pubkey {
|
||||
|
@ -312,7 +312,10 @@ static void tty_life_timer(void *ctx, unsigned long now)
|
||||
|
||||
typedef enum {
|
||||
KEYACT_AGENT_LOAD,
|
||||
KEYACT_CLIENT_ADD,
|
||||
KEYACT_AGENT_LOAD_ENCRYPTED,
|
||||
KEYACT_CLIENT_BASE,
|
||||
KEYACT_CLIENT_ADD = KEYACT_CLIENT_BASE,
|
||||
KEYACT_CLIENT_ADD_ENCRYPTED,
|
||||
KEYACT_CLIENT_DEL,
|
||||
KEYACT_CLIENT_DEL_ALL,
|
||||
KEYACT_CLIENT_LIST,
|
||||
@ -327,7 +330,7 @@ struct cmdline_key_action {
|
||||
|
||||
bool is_agent_action(keyact action)
|
||||
{
|
||||
return action == KEYACT_AGENT_LOAD;
|
||||
return action < KEYACT_CLIENT_BASE;
|
||||
}
|
||||
|
||||
static struct cmdline_key_action *keyact_head = NULL, *keyact_tail = NULL;
|
||||
@ -438,7 +441,7 @@ static char *askpass(const char *prompt)
|
||||
}
|
||||
}
|
||||
|
||||
static bool unix_add_keyfile(const char *filename_str)
|
||||
static bool unix_add_keyfile(const char *filename_str, bool add_encrypted)
|
||||
{
|
||||
Filename *filename = filename_from_str(filename_str);
|
||||
int status;
|
||||
@ -450,7 +453,7 @@ static bool unix_add_keyfile(const char *filename_str)
|
||||
/*
|
||||
* Try without a passphrase.
|
||||
*/
|
||||
status = pageant_add_keyfile(filename, NULL, &err);
|
||||
status = pageant_add_keyfile(filename, NULL, &err, add_encrypted);
|
||||
if (status == PAGEANT_ACTION_OK) {
|
||||
goto cleanup;
|
||||
} else if (status == PAGEANT_ACTION_FAILURE) {
|
||||
@ -472,7 +475,8 @@ static bool unix_add_keyfile(const char *filename_str)
|
||||
if (!passphrase)
|
||||
break;
|
||||
|
||||
status = pageant_add_keyfile(filename, passphrase, &err);
|
||||
status = pageant_add_keyfile(filename, passphrase, &err,
|
||||
add_encrypted);
|
||||
|
||||
smemclr(passphrase, strlen(passphrase));
|
||||
sfree(passphrase);
|
||||
@ -692,7 +696,9 @@ void run_client(void)
|
||||
for (act = keyact_head; act; act = act->next) {
|
||||
switch (act->action) {
|
||||
case KEYACT_CLIENT_ADD:
|
||||
if (!unix_add_keyfile(act->filename))
|
||||
case KEYACT_CLIENT_ADD_ENCRYPTED:
|
||||
if (!unix_add_keyfile(act->filename,
|
||||
act->action == KEYACT_CLIENT_ADD_ENCRYPTED))
|
||||
errors = true;
|
||||
break;
|
||||
case KEYACT_CLIENT_LIST:
|
||||
@ -875,8 +881,10 @@ void run_agent(FILE *logfp, const char *symlink_path)
|
||||
* Start by loading any keys provided on the command line.
|
||||
*/
|
||||
for (act = keyact_head; act; act = act->next) {
|
||||
assert(act->action == KEYACT_AGENT_LOAD);
|
||||
if (!unix_add_keyfile(act->filename))
|
||||
assert(act->action == KEYACT_AGENT_LOAD ||
|
||||
act->action == KEYACT_AGENT_LOAD_ENCRYPTED);
|
||||
if (!unix_add_keyfile(act->filename,
|
||||
act->action == KEYACT_AGENT_LOAD_ENCRYPTED))
|
||||
errors = true;
|
||||
}
|
||||
if (errors)
|
||||
@ -1097,6 +1105,16 @@ int main(int argc, char **argv)
|
||||
life = LIFE_X11;
|
||||
} else if (!strcmp(p, "-T")) {
|
||||
life = LIFE_TTY;
|
||||
} else if (!strcmp(p, "-E")) {
|
||||
if (curr_keyact == KEYACT_AGENT_LOAD)
|
||||
curr_keyact = KEYACT_AGENT_LOAD_ENCRYPTED;
|
||||
else if (curr_keyact == KEYACT_CLIENT_ADD)
|
||||
curr_keyact = KEYACT_CLIENT_ADD_ENCRYPTED;
|
||||
else {
|
||||
fprintf(stderr, "pageant: unexpected -E while not adding "
|
||||
"keys\n");
|
||||
exit(1);
|
||||
}
|
||||
} else if (!strcmp(p, "--debug")) {
|
||||
life = LIFE_DEBUG;
|
||||
} else if (!strcmp(p, "--permanent")) {
|
||||
|
@ -373,7 +373,7 @@ static void win_add_keyfile(Filename *filename)
|
||||
* _new_ passphrase; pageant_add_keyfile will take care of trying
|
||||
* all the passphrases we've already stored.)
|
||||
*/
|
||||
ret = pageant_add_keyfile(filename, NULL, &err);
|
||||
ret = pageant_add_keyfile(filename, NULL, &err, false);
|
||||
if (ret == PAGEANT_ACTION_OK) {
|
||||
goto done;
|
||||
} else if (ret == PAGEANT_ACTION_FAILURE) {
|
||||
@ -401,7 +401,7 @@ static void win_add_keyfile(Filename *filename)
|
||||
|
||||
assert(passphrase != NULL);
|
||||
|
||||
ret = pageant_add_keyfile(filename, passphrase, &err);
|
||||
ret = pageant_add_keyfile(filename, passphrase, &err, false);
|
||||
if (ret == PAGEANT_ACTION_OK) {
|
||||
goto done;
|
||||
} else if (ret == PAGEANT_ACTION_FAILURE) {
|
||||
|
Loading…
Reference in New Issue
Block a user