mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Unix Pageant: --test-sign client option.
This reads data from standard input, turns it into an SSH-2 sign request, and writes the resulting signature blob to standard output. I don't really anticipate many uses for this other than testing. But it _is_ convenient for testing changes to Pageant itself: it lets me ask for a signature without first having to construct a pointless SSH session that will accept the relevant key.
This commit is contained in:
parent
e0e133b4b0
commit
518c0f0ea1
32
pageant.c
32
pageant.c
@ -2117,6 +2117,38 @@ int pageant_delete_all_keys(char **retstr)
|
||||
return PAGEANT_ACTION_OK;
|
||||
}
|
||||
|
||||
int pageant_sign(struct pageant_pubkey *key, ptrlen message, strbuf *out,
|
||||
uint32_t flags, char **retstr)
|
||||
{
|
||||
strbuf *request;
|
||||
void *response;
|
||||
int resplen;
|
||||
BinarySource src[1];
|
||||
|
||||
request = strbuf_new_for_agent_query();
|
||||
put_byte(request, SSH2_AGENTC_SIGN_REQUEST);
|
||||
put_string(request, key->blob->s, key->blob->len);
|
||||
put_stringpl(request, message);
|
||||
put_uint32(request, flags);
|
||||
pageant_client_query(request, &response, &resplen);
|
||||
strbuf_free(request);
|
||||
BinarySource_BARE_INIT(src, response, resplen);
|
||||
BinarySource_BARE_INIT_PL(src, get_string(src));
|
||||
|
||||
int type = get_byte(src);
|
||||
ptrlen signature = get_string(src);
|
||||
put_datapl(out, signature);
|
||||
sfree(response);
|
||||
|
||||
if (type == SSH2_AGENT_SIGN_RESPONSE && !get_err(src)) {
|
||||
*retstr = NULL;
|
||||
return PAGEANT_ACTION_OK;
|
||||
} else {
|
||||
*retstr = dupstr("Agent failed to create signature");
|
||||
return PAGEANT_ACTION_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
struct pageant_pubkey *pageant_pubkey_copy(struct pageant_pubkey *key)
|
||||
{
|
||||
struct pageant_pubkey *ret = snew(struct pageant_pubkey);
|
||||
|
@ -242,3 +242,5 @@ int pageant_enum_keys(pageant_key_enum_fn_t callback, void *callback_ctx,
|
||||
char **retstr);
|
||||
int pageant_delete_key(struct pageant_pubkey *key, char **retstr);
|
||||
int pageant_delete_all_keys(char **retstr);
|
||||
int pageant_sign(struct pageant_pubkey *key, ptrlen message, strbuf *out,
|
||||
uint32_t flags, char **retstr);
|
||||
|
@ -395,7 +395,8 @@ typedef enum {
|
||||
KEYACT_CLIENT_DEL_ALL,
|
||||
KEYACT_CLIENT_LIST,
|
||||
KEYACT_CLIENT_PUBLIC_OPENSSH,
|
||||
KEYACT_CLIENT_PUBLIC
|
||||
KEYACT_CLIENT_PUBLIC,
|
||||
KEYACT_CLIENT_SIGN,
|
||||
} keyact;
|
||||
struct cmdline_key_action {
|
||||
struct cmdline_key_action *next;
|
||||
@ -409,6 +410,7 @@ bool is_agent_action(keyact action)
|
||||
}
|
||||
|
||||
static struct cmdline_key_action *keyact_head = NULL, *keyact_tail = NULL;
|
||||
static uint32_t sign_flags = 0;
|
||||
|
||||
void add_keyact(keyact action, const char *filename)
|
||||
{
|
||||
@ -762,6 +764,9 @@ void run_client(void)
|
||||
struct pageant_pubkey *key;
|
||||
bool errors = false;
|
||||
char *retstr;
|
||||
LoadedFile *message = lf_new(AGENT_MAX_MSGLEN);
|
||||
bool message_loaded = false, message_ok = false;
|
||||
strbuf *signature = strbuf_new();
|
||||
|
||||
if (!agent_exists()) {
|
||||
fprintf(stderr, "pageant: no agent running to talk to\n");
|
||||
@ -835,11 +840,49 @@ void run_client(void)
|
||||
errors = true;
|
||||
}
|
||||
break;
|
||||
case KEYACT_CLIENT_SIGN:
|
||||
key = NULL;
|
||||
if (!message_loaded) {
|
||||
message_loaded = true;
|
||||
switch(lf_load_fp(message, stdin)) {
|
||||
case LF_TOO_BIG:
|
||||
fprintf(stderr, "pageant: message to sign is too big\n");
|
||||
errors = true;
|
||||
break;
|
||||
case LF_ERROR:
|
||||
fprintf(stderr, "pageant: reading message to sign: %s\n",
|
||||
strerror(errno));
|
||||
errors = true;
|
||||
break;
|
||||
case LF_OK:
|
||||
message_ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!message_ok)
|
||||
break;
|
||||
strbuf_clear(signature);
|
||||
if (!(key = find_key(act->filename, &retstr)) ||
|
||||
pageant_sign(key, ptrlen_from_lf(message), signature,
|
||||
sign_flags, &retstr) == PAGEANT_ACTION_FAILURE) {
|
||||
fprintf(stderr, "pageant: signing with key '%s': %s\n",
|
||||
act->filename, retstr);
|
||||
sfree(retstr);
|
||||
errors = true;
|
||||
} else {
|
||||
fwrite(signature->s, 1, signature->len, stdout);
|
||||
}
|
||||
if (key)
|
||||
pageant_pubkey_free(key);
|
||||
break;
|
||||
default:
|
||||
unreachable("Invalid client action found");
|
||||
}
|
||||
}
|
||||
|
||||
lf_free(message);
|
||||
strbuf_free(signature);
|
||||
|
||||
if (errors)
|
||||
exit(1);
|
||||
}
|
||||
@ -1206,6 +1249,12 @@ int main(int argc, char **argv)
|
||||
}
|
||||
} else if (!strcmp(p, "--debug")) {
|
||||
life = LIFE_DEBUG;
|
||||
} else if (!strcmp(p, "--test-sign")) {
|
||||
curr_keyact = KEYACT_CLIENT_SIGN;
|
||||
sign_flags = 0;
|
||||
} else if (strstartswith(p, "--test-sign-with-flags=")) {
|
||||
curr_keyact = KEYACT_CLIENT_SIGN;
|
||||
sign_flags = atoi(p + strlen("--test-sign-with-flags="));
|
||||
} else if (!strcmp(p, "--permanent")) {
|
||||
life = LIFE_PERM;
|
||||
} else if (!strcmp(p, "--exec")) {
|
||||
|
Loading…
Reference in New Issue
Block a user