2015-05-05 22:16:19 +03:00
|
|
|
/*
|
|
|
|
* pageant.c: cross-platform code to implement Pageant.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
#include "putty.h"
|
Complete rewrite of PuTTY's bignum library.
The old 'Bignum' data type is gone completely, and so is sshbn.c. In
its place is a new thing called 'mp_int', handled by an entirely new
library module mpint.c, with API differences both large and small.
The main aim of this change is that the new library should be free of
timing- and cache-related side channels. I've written the code so that
it _should_ - assuming I haven't made any mistakes - do all of its
work without either control flow or memory addressing depending on the
data words of the input numbers. (Though, being an _arbitrary_
precision library, it does have to at least depend on the sizes of the
numbers - but there's a 'formal' size that can vary separately from
the actual magnitude of the represented integer, so if you want to
keep it secret that your number is actually small, it should work fine
to have a very long mp_int and just happen to store 23 in it.) So I've
done all my conditionalisation by means of computing both answers and
doing bit-masking to swap the right one into place, and all loops over
the words of an mp_int go up to the formal size rather than the actual
size.
I haven't actually tested the constant-time property in any rigorous
way yet (I'm still considering the best way to do it). But this code
is surely at the very least a big improvement on the old version, even
if I later find a few more things to fix.
I've also completely rewritten the low-level elliptic curve arithmetic
from sshecc.c; the new ecc.c is closer to being an adjunct of mpint.c
than it is to the SSH end of the code. The new elliptic curve code
keeps all coordinates in Montgomery-multiplication transformed form to
speed up all the multiplications mod the same prime, and only converts
them back when you ask for the affine coordinates. Also, I adopted
extended coordinates for the Edwards curve implementation.
sshecc.c has also had a near-total rewrite in the course of switching
it over to the new system. While I was there, I've separated ECDSA and
EdDSA more completely - they now have separate vtables, instead of a
single vtable in which nearly every function had a big if statement in
it - and also made the externally exposed types for an ECDSA key and
an ECDH context different.
A minor new feature: since the new arithmetic code includes a modular
square root function, we can now support the compressed point
representation for the NIST curves. We seem to have been getting along
fine without that so far, but it seemed a shame not to put it in,
since it was suddenly easy.
In sshrsa.c, one major change is that I've removed the RSA blinding
step in rsa_privkey_op, in which we randomise the ciphertext before
doing the decryption. The purpose of that was to avoid timing leaks
giving away the plaintext - but the new arithmetic code should take
that in its stride in the course of also being careful enough to avoid
leaking the _private key_, which RSA blinding had no way to do
anything about in any case.
Apart from those specific points, most of the rest of the changes are
more or less mechanical, just changing type names and translating code
into the new API.
2018-12-31 16:53:41 +03:00
|
|
|
#include "mpint.h"
|
2015-05-05 22:16:19 +03:00
|
|
|
#include "ssh.h"
|
2019-02-28 21:05:38 +03:00
|
|
|
#include "sshcr.h"
|
2015-05-05 22:16:19 +03:00
|
|
|
#include "pageant.h"
|
|
|
|
|
|
|
|
/*
|
2018-05-24 10:22:44 +03:00
|
|
|
* We need this to link with the RSA code, because rsa_ssh1_encrypt()
|
|
|
|
* pads its data with random bytes. Since we only use rsa_ssh1_decrypt()
|
2015-05-05 22:16:19 +03:00
|
|
|
* and the signing functions, which are deterministic, this should
|
|
|
|
* never be called.
|
|
|
|
*
|
|
|
|
* If it _is_ called, there is a _serious_ problem, because it
|
|
|
|
* won't generate true random numbers. So we must scream, panic,
|
|
|
|
* and exit immediately if that should happen.
|
|
|
|
*/
|
Replace random_byte() with random_read().
This is in preparation for a PRNG revamp which will want to have a
well defined boundary for any given request-for-randomness, so that it
can destroy the evidence afterwards. So no more looping round calling
random_byte() and then stopping when we feel like it: now you say up
front how many random bytes you want, and call random_read() which
gives you that many in one go.
Most of the call sites that had to be fixed are fairly mechanical, and
quite a few ended up more concise afterwards. A few became more
cumbersome, such as mp_random_bits, in which the new API doesn't let
me load the random bytes directly into the target integer without
triggering undefined behaviour, so instead I have to allocate a
separate temporary buffer.
The _most_ interesting call site was in the PKCS#1 v1.5 padding code
in sshrsa.c (used in SSH-1), in which you need a stream of _nonzero_
random bytes. The previous code just looped on random_byte, retrying
if it got a zero. Now I'm doing a much more interesting thing with an
mpint, essentially scaling a binary fraction repeatedly to extract a
number in the range [0,255) and then adding 1 to it.
2019-01-22 22:43:27 +03:00
|
|
|
void random_read(void *buf, size_t size)
|
2015-05-05 22:16:19 +03:00
|
|
|
{
|
|
|
|
modalfatalbox("Internal error: attempt to use random numbers in Pageant");
|
|
|
|
}
|
|
|
|
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 22:23:19 +03:00
|
|
|
static bool pageant_local = false;
|
2015-05-11 17:06:25 +03:00
|
|
|
|
2020-01-25 20:24:17 +03:00
|
|
|
typedef struct PageantKeySort PageantKeySort;
|
|
|
|
typedef struct PageantKey PageantKey;
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
typedef struct PageantAsyncOp PageantAsyncOp;
|
|
|
|
typedef struct PageantAsyncOpVtable PageantAsyncOpVtable;
|
|
|
|
typedef struct PageantClientRequestNode PageantClientRequestNode;
|
|
|
|
typedef struct PageantKeyRequestNode PageantKeyRequestNode;
|
|
|
|
|
|
|
|
struct PageantClientRequestNode {
|
|
|
|
PageantClientRequestNode *prev, *next;
|
|
|
|
};
|
|
|
|
struct PageantKeyRequestNode {
|
|
|
|
PageantKeyRequestNode *prev, *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PageantClientInfo {
|
|
|
|
PageantClient *pc; /* goes to NULL when client is unregistered */
|
|
|
|
PageantClientRequestNode head;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PageantAsyncOp {
|
|
|
|
const PageantAsyncOpVtable *vt;
|
|
|
|
PageantClientInfo *info;
|
|
|
|
PageantClientRequestNode cr;
|
|
|
|
PageantClientRequestId *reqid;
|
|
|
|
};
|
|
|
|
struct PageantAsyncOpVtable {
|
|
|
|
void (*coroutine)(PageantAsyncOp *pao);
|
|
|
|
void (*free)(PageantAsyncOp *pao);
|
|
|
|
};
|
|
|
|
static inline void pageant_async_op_coroutine(PageantAsyncOp *pao)
|
|
|
|
{ pao->vt->coroutine(pao); }
|
|
|
|
static inline void pageant_async_op_free(PageantAsyncOp *pao)
|
|
|
|
{
|
|
|
|
delete_callbacks_for_context(pao);
|
|
|
|
pao->vt->free(pao);
|
|
|
|
}
|
|
|
|
static inline void pageant_async_op_unlink(PageantAsyncOp *pao)
|
|
|
|
{
|
|
|
|
pao->cr.prev->next = pao->cr.next;
|
|
|
|
pao->cr.next->prev = pao->cr.prev;
|
|
|
|
}
|
|
|
|
static inline void pageant_async_op_unlink_and_free(PageantAsyncOp *pao)
|
|
|
|
{
|
|
|
|
pageant_async_op_unlink(pao);
|
|
|
|
pageant_async_op_free(pao);
|
|
|
|
}
|
|
|
|
static void pageant_async_op_callback(void *vctx)
|
|
|
|
{
|
|
|
|
pageant_async_op_coroutine((PageantAsyncOp *)vctx);
|
|
|
|
}
|
|
|
|
|
2015-05-05 22:16:19 +03:00
|
|
|
/*
|
2020-01-06 23:59:07 +03:00
|
|
|
* Master list of all the keys we have stored, in any form at all.
|
2015-05-05 22:16:19 +03:00
|
|
|
*/
|
2020-01-06 23:59:07 +03:00
|
|
|
static tree234 *keytree;
|
2020-01-25 20:24:17 +03:00
|
|
|
struct PageantKeySort {
|
2020-01-06 23:59:07 +03:00
|
|
|
/* Prefix of the main PageantKey structure which contains all the
|
|
|
|
* data that the sorting order depends on. Also simple enough that
|
|
|
|
* you can construct one for lookup purposes. */
|
|
|
|
int ssh_version; /* 1 or 2; primary sort key */
|
|
|
|
ptrlen public_blob; /* secondary sort key */
|
2020-01-25 20:24:17 +03:00
|
|
|
};
|
|
|
|
struct PageantKey {
|
2020-01-06 23:59:07 +03:00
|
|
|
PageantKeySort sort;
|
|
|
|
strbuf *public_blob; /* the true owner of sort.public_blob */
|
2020-01-10 22:27:07 +03:00
|
|
|
char *comment; /* stored separately, whether or not in rkey/skey */
|
2020-01-06 23:59:07 +03:00
|
|
|
union {
|
|
|
|
RSAKey *rkey; /* if ssh_version == 1 */
|
|
|
|
ssh2_userkey *skey; /* if ssh_version == 2 */
|
|
|
|
};
|
2020-01-25 20:25:28 +03:00
|
|
|
PageantKeyRequestNode blocked_requests;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct PageantSignOp PageantSignOp;
|
|
|
|
struct PageantSignOp {
|
|
|
|
PageantKey *pk;
|
|
|
|
strbuf *data_to_sign;
|
|
|
|
unsigned flags;
|
|
|
|
int crLine;
|
|
|
|
|
|
|
|
PageantKeyRequestNode pkr;
|
|
|
|
PageantAsyncOp pao;
|
2020-01-25 20:24:17 +03:00
|
|
|
};
|
2020-01-06 23:59:07 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
static void failure(PageantClient *pc, PageantClientRequestId *reqid,
|
|
|
|
strbuf *sb, const char *fmt, ...);
|
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
static void pk_free(PageantKey *pk)
|
|
|
|
{
|
|
|
|
if (pk->public_blob) strbuf_free(pk->public_blob);
|
|
|
|
sfree(pk->comment);
|
|
|
|
if (pk->sort.ssh_version == 1 && pk->rkey) {
|
|
|
|
freersakey(pk->rkey);
|
|
|
|
sfree(pk->rkey);
|
|
|
|
}
|
|
|
|
if (pk->sort.ssh_version == 2 && pk->skey) {
|
2020-01-10 22:27:07 +03:00
|
|
|
sfree(pk->skey->comment);
|
2020-01-06 23:59:07 +03:00
|
|
|
ssh_key_free(pk->skey->key);
|
|
|
|
sfree(pk->skey);
|
|
|
|
}
|
2020-01-25 20:25:28 +03:00
|
|
|
while (pk->blocked_requests.next != &pk->blocked_requests) {
|
|
|
|
PageantSignOp *so = container_of(pk->blocked_requests.next,
|
|
|
|
PageantSignOp, pkr);
|
|
|
|
so->pkr.next->prev = so->pkr.prev;
|
|
|
|
so->pkr.prev->next = so->pkr.next;
|
|
|
|
strbuf *sb = strbuf_new();
|
|
|
|
failure(so->pao.info->pc, so->pao.reqid, sb,
|
|
|
|
"key deleted from Pageant while signing request was pending");
|
|
|
|
pageant_client_got_response(so->pao.info->pc, so->pao.reqid,
|
|
|
|
ptrlen_from_strbuf(sb));
|
|
|
|
strbuf_free(sb);
|
|
|
|
pageant_async_op_unlink_and_free(&so->pao);
|
|
|
|
}
|
2020-01-06 23:59:07 +03:00
|
|
|
sfree(pk);
|
|
|
|
}
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
static int cmpkeys(void *av, void *bv)
|
2015-05-05 22:16:19 +03:00
|
|
|
{
|
2020-01-06 23:59:07 +03:00
|
|
|
PageantKeySort *a = (PageantKeySort *)av, *b = (PageantKeySort *)bv;
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
if (a->ssh_version != b->ssh_version)
|
|
|
|
return a->ssh_version < b->ssh_version ? -1 : +1;
|
|
|
|
else
|
|
|
|
return ptrlen_strcmp(a->public_blob, b->public_blob);
|
2015-05-05 22:16:19 +03:00
|
|
|
}
|
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
static inline PageantKeySort keysort(int version, ptrlen blob)
|
2015-05-05 22:16:19 +03:00
|
|
|
{
|
2020-01-06 23:59:07 +03:00
|
|
|
PageantKeySort sort;
|
|
|
|
sort.ssh_version = version;
|
|
|
|
sort.public_blob = blob;
|
|
|
|
return sort;
|
|
|
|
}
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
static strbuf *makeblob1(RSAKey *rkey)
|
|
|
|
{
|
|
|
|
strbuf *blob = strbuf_new();
|
|
|
|
rsa_ssh1_public_blob(BinarySink_UPCAST(blob), rkey,
|
|
|
|
RSA_SSH1_EXPONENT_FIRST);
|
|
|
|
return blob;
|
|
|
|
}
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
static strbuf *makeblob2(ssh2_userkey *skey)
|
|
|
|
{
|
|
|
|
strbuf *blob = strbuf_new();
|
|
|
|
ssh_key_public_blob(skey->key, BinarySink_UPCAST(blob));
|
|
|
|
return blob;
|
2015-05-05 22:16:19 +03:00
|
|
|
}
|
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
static PageantKey *findkey1(RSAKey *reqkey)
|
2015-05-05 22:16:19 +03:00
|
|
|
{
|
2020-01-06 23:59:07 +03:00
|
|
|
strbuf *blob = makeblob1(reqkey);
|
|
|
|
PageantKeySort sort = keysort(1, ptrlen_from_strbuf(blob));
|
|
|
|
PageantKey *toret = find234(keytree, &sort, NULL);
|
|
|
|
strbuf_free(blob);
|
2018-05-24 12:59:39 +03:00
|
|
|
return toret;
|
2015-05-05 22:16:19 +03:00
|
|
|
}
|
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
static PageantKey *findkey2(ptrlen blob)
|
2015-05-05 22:16:19 +03:00
|
|
|
{
|
2020-01-06 23:59:07 +03:00
|
|
|
PageantKeySort sort = keysort(2, blob);
|
|
|
|
return find234(keytree, &sort, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int find_first_key_for_version(int ssh_version)
|
|
|
|
{
|
|
|
|
PageantKeySort sort = keysort(ssh_version, PTRLEN_LITERAL(""));
|
|
|
|
int pos;
|
|
|
|
if (findrelpos234(keytree, &sort, NULL, REL234_GE, &pos))
|
|
|
|
return pos;
|
|
|
|
return count234(keytree);
|
|
|
|
}
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
static int count_keys(int ssh_version)
|
|
|
|
{
|
|
|
|
return (find_first_key_for_version(ssh_version + 1) -
|
|
|
|
find_first_key_for_version(ssh_version));
|
|
|
|
}
|
|
|
|
int pageant_count_ssh1_keys(void) { return count_keys(1); }
|
|
|
|
int pageant_count_ssh2_keys(void) { return count_keys(2); }
|
|
|
|
|
|
|
|
bool pageant_add_ssh1_key(RSAKey *rkey)
|
|
|
|
{
|
|
|
|
PageantKey *pk = snew(PageantKey);
|
|
|
|
memset(pk, 0, sizeof(PageantKey));
|
|
|
|
pk->sort.ssh_version = 1;
|
|
|
|
pk->public_blob = makeblob1(rkey);
|
|
|
|
pk->sort.public_blob = ptrlen_from_strbuf(pk->public_blob);
|
2020-01-25 20:25:28 +03:00
|
|
|
pk->blocked_requests.next = pk->blocked_requests.prev =
|
|
|
|
&pk->blocked_requests;
|
2020-01-06 23:59:07 +03:00
|
|
|
|
|
|
|
if (add234(keytree, pk) == pk) {
|
|
|
|
pk->rkey = rkey;
|
2020-01-10 22:27:07 +03:00
|
|
|
if (rkey->comment)
|
|
|
|
pk->comment = dupstr(rkey->comment);
|
2020-01-06 23:59:07 +03:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
pk_free(pk);
|
|
|
|
return false;
|
2015-05-05 22:16:19 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
bool pageant_add_ssh2_key(ssh2_userkey *skey)
|
|
|
|
{
|
|
|
|
PageantKey *pk = snew(PageantKey);
|
|
|
|
memset(pk, 0, sizeof(PageantKey));
|
|
|
|
pk->sort.ssh_version = 2;
|
|
|
|
pk->public_blob = makeblob2(skey);
|
|
|
|
pk->sort.public_blob = ptrlen_from_strbuf(pk->public_blob);
|
2020-01-25 20:25:28 +03:00
|
|
|
pk->blocked_requests.next = pk->blocked_requests.prev =
|
|
|
|
&pk->blocked_requests;
|
2020-01-06 23:59:07 +03:00
|
|
|
|
|
|
|
if (add234(keytree, pk) == pk) {
|
|
|
|
pk->skey = skey;
|
2020-01-10 22:27:07 +03:00
|
|
|
if (skey->comment)
|
|
|
|
pk->comment = dupstr(skey->comment);
|
2020-01-06 23:59:07 +03:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
pk_free(pk);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void remove_all_keys(int ssh_version)
|
|
|
|
{
|
|
|
|
int start = find_first_key_for_version(ssh_version);
|
|
|
|
int end = find_first_key_for_version(ssh_version + 1);
|
|
|
|
while (end > start) {
|
|
|
|
PageantKey *pk = delpos234(keytree, --end);
|
|
|
|
assert(pk->sort.ssh_version == ssh_version);
|
|
|
|
pk_free(pk);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void list_keys(BinarySink *bs, int ssh_version)
|
2015-05-05 22:16:19 +03:00
|
|
|
{
|
2018-05-24 12:59:39 +03:00
|
|
|
int i;
|
2020-01-06 23:59:07 +03:00
|
|
|
PageantKey *pk;
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
put_uint32(bs, count_keys(ssh_version));
|
|
|
|
for (i = find_first_key_for_version(ssh_version);
|
|
|
|
NULL != (pk = index234(keytree, i)); i++) {
|
|
|
|
if (pk->sort.ssh_version != ssh_version)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (ssh_version > 1)
|
|
|
|
put_stringpl(bs, pk->sort.public_blob);
|
|
|
|
else
|
|
|
|
put_datapl(bs, pk->sort.public_blob); /* no header */
|
|
|
|
|
|
|
|
put_stringpl(bs, ptrlen_from_asciz(pk->comment));
|
2015-05-05 22:16:19 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
void pageant_make_keylist1(BinarySink *bs) { return list_keys(bs, 1); }
|
|
|
|
void pageant_make_keylist2(BinarySink *bs) { return list_keys(bs, 2); }
|
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
void pageant_register_client(PageantClient *pc)
|
|
|
|
{
|
|
|
|
pc->info = snew(PageantClientInfo);
|
|
|
|
pc->info->pc = pc;
|
|
|
|
pc->info->head.prev = pc->info->head.next = &pc->info->head;
|
|
|
|
}
|
2015-05-06 21:32:26 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
void pageant_unregister_client(PageantClient *pc)
|
2015-05-06 21:32:26 +03:00
|
|
|
{
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
PageantClientInfo *info = pc->info;
|
|
|
|
assert(info);
|
|
|
|
assert(info->pc == pc);
|
|
|
|
|
|
|
|
while (pc->info->head.next != &pc->info->head) {
|
|
|
|
PageantAsyncOp *pao = container_of(pc->info->head.next,
|
|
|
|
PageantAsyncOp, cr);
|
|
|
|
pageant_async_op_unlink_and_free(pao);
|
|
|
|
}
|
|
|
|
|
|
|
|
sfree(pc->info);
|
|
|
|
}
|
|
|
|
|
2020-01-26 17:49:31 +03:00
|
|
|
static PRINTF_LIKE(4, 5) void failure(PageantClient *pc,
|
|
|
|
PageantClientRequestId *reqid,
|
|
|
|
strbuf *sb, const char *fmt, ...)
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
{
|
|
|
|
strbuf_clear(sb);
|
|
|
|
put_byte(sb, SSH_AGENT_FAILURE);
|
|
|
|
if (!pc->suppress_logging) {
|
2015-05-06 21:32:26 +03:00
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
char *msg = dupprintf(fmt, ap);
|
2015-05-06 21:32:26 +03:00
|
|
|
va_end(ap);
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "reply: SSH_AGENT_FAILURE (%s)", msg);
|
|
|
|
sfree(msg);
|
2015-05-06 21:32:26 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-25 20:25:28 +03:00
|
|
|
static void signop_free(PageantAsyncOp *pao)
|
|
|
|
{
|
|
|
|
PageantSignOp *so = container_of(pao, PageantSignOp, pao);
|
|
|
|
strbuf_free(so->data_to_sign);
|
|
|
|
sfree(so);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void signop_coroutine(PageantAsyncOp *pao)
|
|
|
|
{
|
|
|
|
PageantSignOp *so = container_of(pao, PageantSignOp, pao);
|
|
|
|
|
|
|
|
crBegin(so->crLine);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we want to request a user interaction, we should set it up;
|
|
|
|
* arrange that when it finishes, it re-queues
|
|
|
|
* pageant_async_op_callback; and then crReturnV so that we resume
|
|
|
|
* from after that.
|
|
|
|
*/
|
|
|
|
if (0) crReturnV;
|
|
|
|
|
|
|
|
strbuf *signature = strbuf_new();
|
|
|
|
ssh_key_sign(so->pk->skey->key, ptrlen_from_strbuf(so->data_to_sign),
|
|
|
|
so->flags, BinarySink_UPCAST(signature));
|
|
|
|
|
|
|
|
strbuf *response = strbuf_new();
|
|
|
|
put_byte(response, SSH2_AGENT_SIGN_RESPONSE);
|
|
|
|
put_stringsb(response, signature);
|
|
|
|
pageant_client_got_response(so->pao.info->pc, so->pao.reqid,
|
|
|
|
ptrlen_from_strbuf(response));
|
|
|
|
strbuf_free(response);
|
|
|
|
|
|
|
|
pageant_async_op_unlink_and_free(&so->pao);
|
|
|
|
crFinishFreedV;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct PageantAsyncOpVtable signop_vtable = {
|
|
|
|
signop_coroutine,
|
|
|
|
signop_free,
|
|
|
|
};
|
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
typedef struct PageantImmOp PageantImmOp;
|
|
|
|
struct PageantImmOp {
|
|
|
|
int crLine;
|
|
|
|
strbuf *response;
|
|
|
|
|
|
|
|
PageantAsyncOp pao;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void immop_free(PageantAsyncOp *pao)
|
|
|
|
{
|
|
|
|
PageantImmOp *io = container_of(pao, PageantImmOp, pao);
|
|
|
|
strbuf_free(io->response);
|
|
|
|
sfree(io);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void immop_coroutine(PageantAsyncOp *pao)
|
|
|
|
{
|
|
|
|
PageantImmOp *io = container_of(pao, PageantImmOp, pao);
|
|
|
|
|
|
|
|
crBegin(io->crLine);
|
|
|
|
|
|
|
|
if (0) crReturnV;
|
|
|
|
|
|
|
|
pageant_client_got_response(io->pao.info->pc, io->pao.reqid,
|
|
|
|
ptrlen_from_strbuf(io->response));
|
|
|
|
pageant_async_op_unlink_and_free(&io->pao);
|
|
|
|
crFinishFreedV;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct PageantAsyncOpVtable immop_vtable = {
|
|
|
|
immop_coroutine,
|
|
|
|
immop_free,
|
|
|
|
};
|
|
|
|
|
|
|
|
void pageant_handle_msg(PageantClient *pc, PageantClientRequestId *reqid,
|
|
|
|
ptrlen msgpl)
|
2015-05-05 22:16:19 +03:00
|
|
|
{
|
2018-05-28 01:47:40 +03:00
|
|
|
BinarySource msg[1];
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
strbuf *sb = strbuf_new_nm();
|
2015-05-05 22:16:19 +03:00
|
|
|
int type;
|
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
BinarySource_BARE_INIT_PL(msg, msgpl);
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2018-05-28 01:47:40 +03:00
|
|
|
type = get_byte(msg);
|
|
|
|
if (get_err(msg)) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "message contained no type code");
|
|
|
|
goto responded;
|
2015-05-06 21:32:26 +03:00
|
|
|
}
|
2015-05-05 22:16:19 +03:00
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case SSH1_AGENTC_REQUEST_RSA_IDENTITIES:
|
2019-09-08 22:29:00 +03:00
|
|
|
/*
|
|
|
|
* Reply with SSH1_AGENT_RSA_IDENTITIES_ANSWER.
|
|
|
|
*/
|
|
|
|
{
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid,
|
|
|
|
"request: SSH1_AGENTC_REQUEST_RSA_IDENTITIES");
|
2015-05-06 21:32:26 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
put_byte(sb, SSH1_AGENT_RSA_IDENTITIES_ANSWER);
|
|
|
|
pageant_make_keylist1(BinarySink_UPCAST(sb));
|
2015-05-06 21:32:26 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid,
|
|
|
|
"reply: SSH1_AGENT_RSA_IDENTITIES_ANSWER");
|
|
|
|
if (!pc->suppress_logging) {
|
2015-05-06 21:32:26 +03:00
|
|
|
int i;
|
2019-01-04 09:51:44 +03:00
|
|
|
RSAKey *rkey;
|
2015-05-06 21:32:26 +03:00
|
|
|
for (i = 0; NULL != (rkey = pageant_nth_ssh1_key(i)); i++) {
|
2018-06-03 10:08:53 +03:00
|
|
|
char *fingerprint = rsa_ssh1_fingerprint(rkey);
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "returned key: %s",
|
|
|
|
fingerprint);
|
2018-06-03 10:08:53 +03:00
|
|
|
sfree(fingerprint);
|
2015-05-06 21:32:26 +03:00
|
|
|
}
|
|
|
|
}
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
break;
|
2015-05-05 22:16:19 +03:00
|
|
|
case SSH2_AGENTC_REQUEST_IDENTITIES:
|
2019-09-08 22:29:00 +03:00
|
|
|
/*
|
|
|
|
* Reply with SSH2_AGENT_IDENTITIES_ANSWER.
|
|
|
|
*/
|
|
|
|
{
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid,
|
|
|
|
"request: SSH2_AGENTC_REQUEST_IDENTITIES");
|
2015-05-06 21:32:26 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
put_byte(sb, SSH2_AGENT_IDENTITIES_ANSWER);
|
|
|
|
pageant_make_keylist2(BinarySink_UPCAST(sb));
|
2015-05-06 21:32:26 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid,
|
|
|
|
"reply: SSH2_AGENT_IDENTITIES_ANSWER");
|
|
|
|
if (!pc->suppress_logging) {
|
2015-05-06 21:32:26 +03:00
|
|
|
int i;
|
2019-01-04 09:51:44 +03:00
|
|
|
ssh2_userkey *skey;
|
2015-05-06 21:32:26 +03:00
|
|
|
for (i = 0; NULL != (skey = pageant_nth_ssh2_key(i)); i++) {
|
2018-06-03 14:58:05 +03:00
|
|
|
char *fingerprint = ssh2_fingerprint(skey->key);
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "returned key: %s %s",
|
|
|
|
fingerprint, skey->comment);
|
2015-05-06 21:32:26 +03:00
|
|
|
sfree(fingerprint);
|
|
|
|
}
|
|
|
|
}
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
break;
|
2015-05-05 22:16:19 +03:00
|
|
|
case SSH1_AGENTC_RSA_CHALLENGE:
|
2019-09-08 22:29:00 +03:00
|
|
|
/*
|
|
|
|
* Reply with either SSH1_AGENT_RSA_RESPONSE or
|
|
|
|
* SSH_AGENT_FAILURE, depending on whether we have that key
|
|
|
|
* or not.
|
|
|
|
*/
|
|
|
|
{
|
2020-01-06 23:59:07 +03:00
|
|
|
RSAKey reqkey;
|
|
|
|
PageantKey *pk;
|
2019-09-08 22:29:00 +03:00
|
|
|
mp_int *challenge, *response;
|
2018-05-28 01:47:40 +03:00
|
|
|
ptrlen session_id;
|
|
|
|
unsigned response_type;
|
2019-09-08 22:29:00 +03:00
|
|
|
unsigned char response_md5[16];
|
|
|
|
int i;
|
2015-05-05 22:16:19 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid,
|
|
|
|
"request: SSH1_AGENTC_RSA_CHALLENGE");
|
2015-05-06 21:32:26 +03:00
|
|
|
|
2018-05-28 01:47:40 +03:00
|
|
|
response = NULL;
|
|
|
|
memset(&reqkey, 0, sizeof(reqkey));
|
2018-05-24 15:23:17 +03:00
|
|
|
|
2018-06-03 10:23:07 +03:00
|
|
|
get_rsa_ssh1_pub(msg, &reqkey, RSA_SSH1_EXPONENT_FIRST);
|
2018-05-28 01:47:40 +03:00
|
|
|
challenge = get_mp_ssh1(msg);
|
|
|
|
session_id = get_data(msg, 16);
|
2019-09-08 22:29:00 +03:00
|
|
|
response_type = get_uint32(msg);
|
2018-05-28 01:47:40 +03:00
|
|
|
|
|
|
|
if (get_err(msg)) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "unable to decode request");
|
2018-05-24 15:23:17 +03:00
|
|
|
goto challenge1_cleanup;
|
2015-05-06 21:32:26 +03:00
|
|
|
}
|
2018-05-28 01:47:40 +03:00
|
|
|
if (response_type != 1) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb,
|
|
|
|
"response type other than 1 not supported");
|
2018-05-24 15:23:17 +03:00
|
|
|
goto challenge1_cleanup;
|
2015-05-06 21:32:26 +03:00
|
|
|
}
|
2018-05-28 01:47:40 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
if (!pc->suppress_logging) {
|
2018-06-03 10:08:53 +03:00
|
|
|
char *fingerprint;
|
2015-05-06 21:32:26 +03:00
|
|
|
reqkey.comment = NULL;
|
2018-06-03 10:08:53 +03:00
|
|
|
fingerprint = rsa_ssh1_fingerprint(&reqkey);
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "requested key: %s",
|
|
|
|
fingerprint);
|
2018-06-03 10:08:53 +03:00
|
|
|
sfree(fingerprint);
|
2015-05-06 21:32:26 +03:00
|
|
|
}
|
2020-01-06 23:59:07 +03:00
|
|
|
|
|
|
|
if ((pk = findkey1(&reqkey)) == NULL) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "key not found");
|
2018-05-24 15:23:17 +03:00
|
|
|
goto challenge1_cleanup;
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
2020-01-06 23:59:07 +03:00
|
|
|
response = rsa_ssh1_decrypt(challenge, pk->rkey);
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2019-01-20 19:15:14 +03:00
|
|
|
{
|
|
|
|
ssh_hash *h = ssh_hash_new(&ssh_md5);
|
|
|
|
for (i = 0; i < 32; i++)
|
|
|
|
put_byte(h, mp_get_byte(response, 31 - i));
|
|
|
|
put_datapl(h, session_id);
|
|
|
|
ssh_hash_final(h, response_md5);
|
|
|
|
}
|
2015-05-05 22:16:19 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
put_byte(sb, SSH1_AGENT_RSA_RESPONSE);
|
|
|
|
put_data(sb, response_md5, 16);
|
2015-05-06 21:32:26 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "reply: SSH1_AGENT_RSA_RESPONSE");
|
2018-05-24 15:23:17 +03:00
|
|
|
|
|
|
|
challenge1_cleanup:
|
2018-05-28 01:47:40 +03:00
|
|
|
if (response)
|
Complete rewrite of PuTTY's bignum library.
The old 'Bignum' data type is gone completely, and so is sshbn.c. In
its place is a new thing called 'mp_int', handled by an entirely new
library module mpint.c, with API differences both large and small.
The main aim of this change is that the new library should be free of
timing- and cache-related side channels. I've written the code so that
it _should_ - assuming I haven't made any mistakes - do all of its
work without either control flow or memory addressing depending on the
data words of the input numbers. (Though, being an _arbitrary_
precision library, it does have to at least depend on the sizes of the
numbers - but there's a 'formal' size that can vary separately from
the actual magnitude of the represented integer, so if you want to
keep it secret that your number is actually small, it should work fine
to have a very long mp_int and just happen to store 23 in it.) So I've
done all my conditionalisation by means of computing both answers and
doing bit-masking to swap the right one into place, and all loops over
the words of an mp_int go up to the formal size rather than the actual
size.
I haven't actually tested the constant-time property in any rigorous
way yet (I'm still considering the best way to do it). But this code
is surely at the very least a big improvement on the old version, even
if I later find a few more things to fix.
I've also completely rewritten the low-level elliptic curve arithmetic
from sshecc.c; the new ecc.c is closer to being an adjunct of mpint.c
than it is to the SSH end of the code. The new elliptic curve code
keeps all coordinates in Montgomery-multiplication transformed form to
speed up all the multiplications mod the same prime, and only converts
them back when you ask for the affine coordinates. Also, I adopted
extended coordinates for the Edwards curve implementation.
sshecc.c has also had a near-total rewrite in the course of switching
it over to the new system. While I was there, I've separated ECDSA and
EdDSA more completely - they now have separate vtables, instead of a
single vtable in which nearly every function had a big if statement in
it - and also made the externally exposed types for an ECDSA key and
an ECDH context different.
A minor new feature: since the new arithmetic code includes a modular
square root function, we can now support the compressed point
representation for the NIST curves. We seem to have been getting along
fine without that so far, but it seemed a shame not to put it in,
since it was suddenly easy.
In sshrsa.c, one major change is that I've removed the RSA blinding
step in rsa_privkey_op, in which we randomise the ciphertext before
doing the decryption. The purpose of that was to avoid timing leaks
giving away the plaintext - but the new arithmetic code should take
that in its stride in the course of also being careful enough to avoid
leaking the _private key_, which RSA blinding had no way to do
anything about in any case.
Apart from those specific points, most of the rest of the changes are
more or less mechanical, just changing type names and translating code
into the new API.
2018-12-31 16:53:41 +03:00
|
|
|
mp_free(response);
|
|
|
|
mp_free(challenge);
|
2018-12-14 22:42:47 +03:00
|
|
|
freersakey(&reqkey);
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
break;
|
2015-05-05 22:16:19 +03:00
|
|
|
case SSH2_AGENTC_SIGN_REQUEST:
|
2019-09-08 22:29:00 +03:00
|
|
|
/*
|
|
|
|
* Reply with either SSH2_AGENT_SIGN_RESPONSE or
|
|
|
|
* SSH_AGENT_FAILURE, depending on whether we have that key
|
|
|
|
* or not.
|
|
|
|
*/
|
|
|
|
{
|
2020-01-06 23:59:07 +03:00
|
|
|
PageantKey *pk;
|
2018-05-28 01:47:40 +03:00
|
|
|
ptrlen keyblob, sigdata;
|
2018-11-19 23:24:37 +03:00
|
|
|
uint32_t flags, supported_flags;
|
2015-05-05 22:16:19 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "request: SSH2_AGENTC_SIGN_REQUEST");
|
2015-05-06 21:32:26 +03:00
|
|
|
|
2018-05-28 01:47:40 +03:00
|
|
|
keyblob = get_string(msg);
|
|
|
|
sigdata = get_string(msg);
|
2018-11-19 23:20:00 +03:00
|
|
|
|
|
|
|
if (get_err(msg)) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "unable to decode request");
|
|
|
|
goto responded;
|
2018-11-19 23:20:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Later versions of the agent protocol added a flags word
|
|
|
|
* on the end of the sign request. That hasn't always been
|
|
|
|
* there, so we don't complain if we don't find it.
|
|
|
|
*
|
|
|
|
* get_uint32 will default to returning zero if no data is
|
|
|
|
* available.
|
|
|
|
*/
|
|
|
|
bool have_flags = false;
|
|
|
|
flags = get_uint32(msg);
|
|
|
|
if (!get_err(msg))
|
|
|
|
have_flags = true;
|
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
if (!pc->suppress_logging) {
|
2019-02-06 23:48:03 +03:00
|
|
|
char *fingerprint = ssh2_fingerprint_blob(keyblob);
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "requested key: %s",
|
|
|
|
fingerprint);
|
2015-05-06 21:32:26 +03:00
|
|
|
sfree(fingerprint);
|
|
|
|
}
|
2020-01-06 23:59:07 +03:00
|
|
|
if ((pk = findkey2(keyblob)) == NULL) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "key not found");
|
|
|
|
goto responded;
|
2015-05-06 21:32:26 +03:00
|
|
|
}
|
2018-05-24 15:23:17 +03:00
|
|
|
|
2018-11-19 23:20:00 +03:00
|
|
|
if (have_flags)
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "signature flags = 0x%08"PRIx32,
|
|
|
|
flags);
|
2018-11-19 23:20:00 +03:00
|
|
|
else
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "no signature flags");
|
2018-11-19 23:20:00 +03:00
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
supported_flags = ssh_key_alg(pk->skey->key)->supported_flags;
|
2018-11-19 23:24:37 +03:00
|
|
|
if (flags & ~supported_flags) {
|
2018-11-19 23:20:00 +03:00
|
|
|
/*
|
|
|
|
* We MUST reject any message containing flags we
|
|
|
|
* don't understand.
|
|
|
|
*/
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "unsupported flag bits 0x%08"PRIx32,
|
|
|
|
flags & ~supported_flags);
|
|
|
|
goto responded;
|
2018-11-19 23:20:00 +03:00
|
|
|
}
|
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
char *invalid = ssh_key_invalid(pk->skey->key, flags);
|
2019-02-10 11:44:59 +03:00
|
|
|
if (invalid) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "key invalid: %s", invalid);
|
2019-02-10 11:44:59 +03:00
|
|
|
sfree(invalid);
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
goto responded;
|
2019-02-10 11:44:59 +03:00
|
|
|
}
|
|
|
|
|
2020-01-25 20:25:28 +03:00
|
|
|
strbuf_free(sb); /* no immediate response */
|
|
|
|
|
|
|
|
PageantSignOp *so = snew(PageantSignOp);
|
|
|
|
so->pao.vt = &signop_vtable;
|
|
|
|
so->pao.info = pc->info;
|
|
|
|
so->pao.cr.prev = pc->info->head.prev;
|
|
|
|
so->pao.cr.next = &pc->info->head;
|
|
|
|
so->pao.reqid = reqid;
|
|
|
|
so->pk = pk;
|
|
|
|
so->pkr.prev = pk->blocked_requests.prev;
|
|
|
|
so->pkr.next = &pk->blocked_requests;
|
|
|
|
so->pkr.prev->next = so->pkr.next;
|
|
|
|
so->pkr.next->prev = so->pkr.prev;
|
|
|
|
so->data_to_sign = strbuf_new();
|
|
|
|
put_datapl(so->data_to_sign, sigdata);
|
|
|
|
so->flags = flags;
|
|
|
|
so->crLine = 0;
|
|
|
|
queue_toplevel_callback(pageant_async_op_callback, &so->pao);
|
|
|
|
return;
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
break;
|
2015-05-05 22:16:19 +03:00
|
|
|
case SSH1_AGENTC_ADD_RSA_IDENTITY:
|
2019-09-08 22:29:00 +03:00
|
|
|
/*
|
|
|
|
* Add to the list and return SSH_AGENT_SUCCESS, or
|
|
|
|
* SSH_AGENT_FAILURE if the key was malformed.
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
RSAKey *key;
|
2015-05-05 22:16:19 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid,
|
|
|
|
"request: SSH1_AGENTC_ADD_RSA_IDENTITY");
|
2015-05-06 21:32:26 +03:00
|
|
|
|
2019-12-15 23:12:36 +03:00
|
|
|
key = get_rsa_ssh1_priv_agent(msg);
|
2019-09-08 22:29:00 +03:00
|
|
|
key->comment = mkstr(get_string(msg));
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2018-05-28 01:47:40 +03:00
|
|
|
if (get_err(msg)) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "unable to decode request");
|
2018-05-28 01:47:40 +03:00
|
|
|
goto add1_cleanup;
|
|
|
|
}
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2018-05-26 20:00:23 +03:00
|
|
|
if (!rsa_verify(key)) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "key is invalid");
|
2019-09-08 22:29:00 +03:00
|
|
|
goto add1_cleanup;
|
2018-05-26 20:00:23 +03:00
|
|
|
}
|
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
if (!pc->suppress_logging) {
|
2018-06-03 10:08:53 +03:00
|
|
|
char *fingerprint = rsa_ssh1_fingerprint(key);
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid,
|
|
|
|
"submitted key: %s", fingerprint);
|
2018-06-03 10:08:53 +03:00
|
|
|
sfree(fingerprint);
|
2015-05-06 21:32:26 +03:00
|
|
|
}
|
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
if (pageant_add_ssh1_key(key)) {
|
2019-09-08 22:29:00 +03:00
|
|
|
keylist_update();
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
put_byte(sb, SSH_AGENT_SUCCESS);
|
|
|
|
pageant_client_log(pc, reqid, "reply: SSH_AGENT_SUCCESS");
|
2018-05-24 15:23:17 +03:00
|
|
|
key = NULL; /* don't free it in cleanup */
|
2019-09-08 22:29:00 +03:00
|
|
|
} else {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "key already present");
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
2018-05-24 15:23:17 +03:00
|
|
|
|
|
|
|
add1_cleanup:
|
|
|
|
if (key) {
|
2019-09-08 22:29:00 +03:00
|
|
|
freersakey(key);
|
|
|
|
sfree(key);
|
2018-05-24 15:23:17 +03:00
|
|
|
}
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
break;
|
2015-05-05 22:16:19 +03:00
|
|
|
case SSH2_AGENTC_ADD_IDENTITY:
|
2019-09-08 22:29:00 +03:00
|
|
|
/*
|
|
|
|
* Add to the list and return SSH_AGENT_SUCCESS, or
|
|
|
|
* SSH_AGENT_FAILURE if the key was malformed.
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
ssh2_userkey *key = NULL;
|
2018-06-03 14:58:05 +03:00
|
|
|
ptrlen algpl;
|
|
|
|
const ssh_keyalg *alg;
|
2015-05-05 22:16:19 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "request: SSH2_AGENTC_ADD_IDENTITY");
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2018-06-03 14:58:05 +03:00
|
|
|
algpl = get_string(msg);
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
key = snew(ssh2_userkey);
|
2018-06-03 14:58:05 +03:00
|
|
|
key->key = NULL;
|
2018-05-24 15:23:17 +03:00
|
|
|
key->comment = NULL;
|
2018-06-03 14:58:05 +03:00
|
|
|
alg = find_pubkey_alg_len(algpl);
|
2019-09-08 22:29:00 +03:00
|
|
|
if (!alg) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "algorithm unknown");
|
2019-09-08 22:29:00 +03:00
|
|
|
goto add2_cleanup;
|
|
|
|
}
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2018-06-03 14:58:05 +03:00
|
|
|
key->key = ssh_key_new_priv_openssh(alg, msg);
|
2018-05-28 01:47:40 +03:00
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
if (!key->key) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "key setup failed");
|
2019-09-08 22:29:00 +03:00
|
|
|
goto add2_cleanup;
|
|
|
|
}
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
key->comment = mkstr(get_string(msg));
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2018-05-28 01:47:40 +03:00
|
|
|
if (get_err(msg)) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "unable to decode request");
|
2018-05-28 01:47:40 +03:00
|
|
|
goto add2_cleanup;
|
|
|
|
}
|
2015-05-05 22:16:19 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
if (!pc->suppress_logging) {
|
2018-06-03 14:58:05 +03:00
|
|
|
char *fingerprint = ssh2_fingerprint(key->key);
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "submitted key: %s %s",
|
|
|
|
fingerprint, key->comment);
|
2015-05-06 21:32:26 +03:00
|
|
|
sfree(fingerprint);
|
|
|
|
}
|
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
if (pageant_add_ssh2_key(key)) {
|
2019-09-08 22:29:00 +03:00
|
|
|
keylist_update();
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
put_byte(sb, SSH_AGENT_SUCCESS);
|
2015-05-06 21:32:26 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "reply: SSH_AGENT_SUCCESS");
|
2015-05-06 21:32:26 +03:00
|
|
|
|
2018-05-24 15:23:17 +03:00
|
|
|
key = NULL; /* don't clean it up */
|
2019-09-08 22:29:00 +03:00
|
|
|
} else {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "key already present");
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
2018-05-24 15:23:17 +03:00
|
|
|
|
|
|
|
add2_cleanup:
|
|
|
|
if (key) {
|
2018-06-03 14:58:05 +03:00
|
|
|
if (key->key)
|
|
|
|
ssh_key_free(key->key);
|
2018-05-24 15:23:17 +03:00
|
|
|
if (key->comment)
|
|
|
|
sfree(key->comment);
|
2019-09-08 22:29:00 +03:00
|
|
|
sfree(key);
|
2018-05-24 15:23:17 +03:00
|
|
|
}
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
break;
|
2015-05-05 22:16:19 +03:00
|
|
|
case SSH1_AGENTC_REMOVE_RSA_IDENTITY:
|
2019-09-08 22:29:00 +03:00
|
|
|
/*
|
|
|
|
* Remove from the list and return SSH_AGENT_SUCCESS, or
|
|
|
|
* perhaps SSH_AGENT_FAILURE if it wasn't in the list to
|
|
|
|
* start with.
|
|
|
|
*/
|
|
|
|
{
|
2020-01-06 23:59:07 +03:00
|
|
|
RSAKey reqkey;
|
|
|
|
PageantKey *pk;
|
2015-05-05 22:16:19 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid,
|
|
|
|
"request: SSH1_AGENTC_REMOVE_RSA_IDENTITY");
|
2015-05-06 21:32:26 +03:00
|
|
|
|
2018-12-14 22:42:47 +03:00
|
|
|
memset(&reqkey, 0, sizeof(reqkey));
|
2018-06-03 10:23:07 +03:00
|
|
|
get_rsa_ssh1_pub(msg, &reqkey, RSA_SSH1_EXPONENT_FIRST);
|
2018-05-28 01:47:40 +03:00
|
|
|
|
|
|
|
if (get_err(msg)) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "unable to decode request");
|
2018-12-14 22:42:47 +03:00
|
|
|
freersakey(&reqkey);
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
goto responded;
|
2015-05-06 21:32:26 +03:00
|
|
|
}
|
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
if (!pc->suppress_logging) {
|
2018-06-03 10:08:53 +03:00
|
|
|
char *fingerprint;
|
2015-05-06 21:32:26 +03:00
|
|
|
reqkey.comment = NULL;
|
2018-06-03 10:08:53 +03:00
|
|
|
fingerprint = rsa_ssh1_fingerprint(&reqkey);
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "unwanted key: %s", fingerprint);
|
2018-06-03 10:37:17 +03:00
|
|
|
sfree(fingerprint);
|
2015-05-06 21:32:26 +03:00
|
|
|
}
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
pk = findkey1(&reqkey);
|
2018-12-14 22:42:47 +03:00
|
|
|
freersakey(&reqkey);
|
2020-01-06 23:59:07 +03:00
|
|
|
if (pk) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "found with comment: %s",
|
|
|
|
pk->rkey->comment);
|
2015-05-06 21:32:26 +03:00
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
del234(keytree, pk);
|
2019-09-08 22:29:00 +03:00
|
|
|
keylist_update();
|
2020-01-06 23:59:07 +03:00
|
|
|
pk_free(pk);
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
put_byte(sb, SSH_AGENT_SUCCESS);
|
2015-05-06 21:32:26 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "reply: SSH_AGENT_SUCCESS");
|
2019-09-08 22:29:00 +03:00
|
|
|
} else {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "key not found");
|
2015-05-06 21:32:26 +03:00
|
|
|
}
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
break;
|
2015-05-05 22:16:19 +03:00
|
|
|
case SSH2_AGENTC_REMOVE_IDENTITY:
|
2019-09-08 22:29:00 +03:00
|
|
|
/*
|
|
|
|
* Remove from the list and return SSH_AGENT_SUCCESS, or
|
|
|
|
* perhaps SSH_AGENT_FAILURE if it wasn't in the list to
|
|
|
|
* start with.
|
|
|
|
*/
|
|
|
|
{
|
2020-01-06 23:59:07 +03:00
|
|
|
PageantKey *pk;
|
2018-05-28 01:47:40 +03:00
|
|
|
ptrlen blob;
|
2015-05-05 22:16:19 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid,
|
|
|
|
"request: SSH2_AGENTC_REMOVE_IDENTITY");
|
2015-05-06 21:32:26 +03:00
|
|
|
|
2018-05-28 01:47:40 +03:00
|
|
|
blob = get_string(msg);
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2018-05-28 01:47:40 +03:00
|
|
|
if (get_err(msg)) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "unable to decode request");
|
|
|
|
goto responded;
|
2015-05-06 21:32:26 +03:00
|
|
|
}
|
2015-05-05 22:16:19 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
if (!pc->suppress_logging) {
|
2019-02-06 23:48:03 +03:00
|
|
|
char *fingerprint = ssh2_fingerprint_blob(blob);
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "unwanted key: %s", fingerprint);
|
2015-05-06 21:32:26 +03:00
|
|
|
sfree(fingerprint);
|
|
|
|
}
|
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
pk = findkey2(blob);
|
|
|
|
if (!pk) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
failure(pc, reqid, sb, "key not found");
|
|
|
|
goto responded;
|
2015-05-06 21:32:26 +03:00
|
|
|
}
|
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid,
|
|
|
|
"found with comment: %s", pk->skey->comment);
|
2015-05-05 22:16:19 +03:00
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
del234(keytree, pk);
|
2015-05-06 21:32:26 +03:00
|
|
|
keylist_update();
|
2020-01-06 23:59:07 +03:00
|
|
|
pk_free(pk);
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
put_byte(sb, SSH_AGENT_SUCCESS);
|
2015-05-06 21:32:26 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "reply: SSH_AGENT_SUCCESS");
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
break;
|
2015-05-05 22:16:19 +03:00
|
|
|
case SSH1_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
|
2019-09-08 22:29:00 +03:00
|
|
|
/*
|
|
|
|
* Remove all SSH-1 keys. Always returns success.
|
|
|
|
*/
|
|
|
|
{
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "request:"
|
|
|
|
" SSH1_AGENTC_REMOVE_ALL_RSA_IDENTITIES");
|
2015-05-06 21:32:26 +03:00
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
remove_all_keys(1);
|
2019-09-08 22:29:00 +03:00
|
|
|
keylist_update();
|
2015-05-05 22:16:19 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
put_byte(sb, SSH_AGENT_SUCCESS);
|
2015-05-06 21:32:26 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "reply: SSH_AGENT_SUCCESS");
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
break;
|
2015-05-05 22:16:19 +03:00
|
|
|
case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
|
2019-09-08 22:29:00 +03:00
|
|
|
/*
|
|
|
|
* Remove all SSH-2 keys. Always returns success.
|
|
|
|
*/
|
|
|
|
{
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid,
|
|
|
|
"request: SSH2_AGENTC_REMOVE_ALL_IDENTITIES");
|
2015-05-06 21:32:26 +03:00
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
remove_all_keys(2);
|
2019-09-08 22:29:00 +03:00
|
|
|
keylist_update();
|
2015-05-05 22:16:19 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
put_byte(sb, SSH_AGENT_SUCCESS);
|
2015-05-06 21:32:26 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "reply: SSH_AGENT_SUCCESS");
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
break;
|
2015-05-05 22:16:19 +03:00
|
|
|
default:
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_client_log(pc, reqid, "request: unknown message type %d",
|
|
|
|
type);
|
|
|
|
failure(pc, reqid, sb, "unrecognised message");
|
2019-09-08 22:29:00 +03:00
|
|
|
break;
|
2015-05-05 22:16:19 +03:00
|
|
|
}
|
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
responded:;
|
|
|
|
|
|
|
|
PageantImmOp *io = snew(PageantImmOp);
|
|
|
|
io->pao.vt = &immop_vtable;
|
|
|
|
io->pao.info = pc->info;
|
|
|
|
io->pao.cr.prev = pc->info->head.prev;
|
|
|
|
io->pao.cr.next = &pc->info->head;
|
|
|
|
io->pao.reqid = reqid;
|
|
|
|
io->response = sb;
|
|
|
|
io->crLine = 0;
|
|
|
|
queue_toplevel_callback(pageant_async_op_callback, &io->pao);
|
2015-05-05 22:16:19 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void pageant_init(void)
|
|
|
|
{
|
2018-10-29 22:50:29 +03:00
|
|
|
pageant_local = true;
|
2020-01-06 23:59:07 +03:00
|
|
|
keytree = newtree234(cmpkeys);
|
2015-05-05 22:16:19 +03:00
|
|
|
}
|
|
|
|
|
2019-01-04 09:51:44 +03:00
|
|
|
RSAKey *pageant_nth_ssh1_key(int i)
|
2015-05-05 22:16:19 +03:00
|
|
|
{
|
2020-01-06 23:59:07 +03:00
|
|
|
PageantKey *pk = index234(keytree, find_first_key_for_version(1) + i);
|
|
|
|
if (pk && pk->sort.ssh_version == 1)
|
|
|
|
return pk->rkey;
|
|
|
|
else
|
|
|
|
return NULL;
|
2015-05-05 22:16:19 +03:00
|
|
|
}
|
|
|
|
|
2019-01-04 09:51:44 +03:00
|
|
|
ssh2_userkey *pageant_nth_ssh2_key(int i)
|
2015-05-05 22:16:19 +03:00
|
|
|
{
|
2020-01-06 23:59:07 +03:00
|
|
|
PageantKey *pk = index234(keytree, find_first_key_for_version(2) + i);
|
|
|
|
if (pk && pk->sort.ssh_version == 2)
|
|
|
|
return pk->skey;
|
|
|
|
else
|
|
|
|
return NULL;
|
2015-05-05 22:16:19 +03:00
|
|
|
}
|
|
|
|
|
2019-01-04 09:51:44 +03:00
|
|
|
bool pageant_delete_ssh1_key(RSAKey *rkey)
|
2015-05-05 22:16:19 +03:00
|
|
|
{
|
2020-01-06 23:59:07 +03:00
|
|
|
strbuf *blob = makeblob1(rkey);
|
|
|
|
PageantKeySort sort = keysort(1, ptrlen_from_strbuf(blob));
|
|
|
|
PageantKey *deleted = del234(keytree, &sort);
|
|
|
|
strbuf_free(blob);
|
|
|
|
|
2015-05-05 22:16:19 +03:00
|
|
|
if (!deleted)
|
2018-10-29 22:50:29 +03:00
|
|
|
return false;
|
2020-01-06 23:59:07 +03:00
|
|
|
assert(deleted->sort.ssh_version == 1);
|
|
|
|
assert(deleted->rkey == rkey);
|
2018-10-29 22:50:29 +03:00
|
|
|
return true;
|
2015-05-05 22:16:19 +03:00
|
|
|
}
|
|
|
|
|
2019-01-04 09:51:44 +03:00
|
|
|
bool pageant_delete_ssh2_key(ssh2_userkey *skey)
|
2015-05-05 22:16:19 +03:00
|
|
|
{
|
2020-01-06 23:59:07 +03:00
|
|
|
strbuf *blob = makeblob2(skey);
|
|
|
|
PageantKeySort sort = keysort(2, ptrlen_from_strbuf(blob));
|
|
|
|
PageantKey *deleted = del234(keytree, &sort);
|
|
|
|
strbuf_free(blob);
|
|
|
|
|
2015-05-05 22:16:19 +03:00
|
|
|
if (!deleted)
|
2018-10-29 22:50:29 +03:00
|
|
|
return false;
|
2020-01-06 23:59:07 +03:00
|
|
|
assert(deleted->sort.ssh_version == 2);
|
|
|
|
assert(deleted->skey == skey);
|
2018-10-29 22:50:29 +03:00
|
|
|
return true;
|
2015-05-05 22:16:19 +03:00
|
|
|
}
|
2015-05-05 22:16:20 +03:00
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
* The agent plug.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2019-02-28 21:05:38 +03:00
|
|
|
* An extra coroutine macro, specific to this code which is consuming
|
|
|
|
* 'const char *data'.
|
2015-05-05 22:16:20 +03:00
|
|
|
*/
|
|
|
|
#define crGetChar(c) do \
|
|
|
|
{ \
|
|
|
|
while (len == 0) { \
|
2016-06-03 01:03:24 +03:00
|
|
|
*crLine =__LINE__; return; case __LINE__:; \
|
2015-05-05 22:16:20 +03:00
|
|
|
} \
|
|
|
|
len--; \
|
|
|
|
(c) = (unsigned char)*data++; \
|
|
|
|
} while (0)
|
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
struct pageant_conn_queued_response {
|
|
|
|
struct pageant_conn_queued_response *next, *prev;
|
|
|
|
size_t req_index; /* for indexing requests in log messages */
|
|
|
|
strbuf *sb;
|
|
|
|
PageantClientRequestId reqid;
|
|
|
|
};
|
|
|
|
|
2015-05-05 22:16:20 +03:00
|
|
|
struct pageant_conn_state {
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 21:10:23 +03:00
|
|
|
Socket *connsock;
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
PageantListenerClient *plc;
|
2015-05-05 22:16:20 +03:00
|
|
|
unsigned char lenbuf[4], pktbuf[AGENT_MAX_MSGLEN];
|
|
|
|
unsigned len, got;
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 22:23:19 +03:00
|
|
|
bool real_packet;
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
size_t conn_index; /* for indexing connections in log messages */
|
|
|
|
size_t req_index; /* for indexing requests in log messages */
|
2015-05-05 22:16:20 +03:00
|
|
|
int crLine; /* for coroutine in pageant_conn_receive */
|
2018-05-27 11:29:33 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
struct pageant_conn_queued_response response_queue;
|
|
|
|
|
|
|
|
PageantClient pc;
|
2018-10-05 09:24:16 +03:00
|
|
|
Plug plug;
|
2015-05-05 22:16:20 +03:00
|
|
|
};
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 21:10:23 +03:00
|
|
|
static void pageant_conn_closing(Plug *plug, const char *error_msg,
|
2019-09-08 22:29:00 +03:00
|
|
|
int error_code, bool calling_back)
|
2015-05-05 22:16:20 +03:00
|
|
|
{
|
2018-10-06 01:49:08 +03:00
|
|
|
struct pageant_conn_state *pc = container_of(
|
2018-10-05 09:24:16 +03:00
|
|
|
plug, struct pageant_conn_state, plug);
|
2015-05-06 21:32:26 +03:00
|
|
|
if (error_msg)
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_listener_client_log(pc->plc, "c#%zu: error: %s",
|
|
|
|
pc->conn_index, error_msg);
|
2015-05-06 21:32:26 +03:00
|
|
|
else
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_listener_client_log(pc->plc, "c#%zu: connection closed",
|
|
|
|
pc->conn_index);
|
2015-05-05 22:16:20 +03:00
|
|
|
sk_close(pc->connsock);
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_unregister_client(&pc->pc);
|
2015-05-05 22:16:20 +03:00
|
|
|
sfree(pc);
|
|
|
|
}
|
|
|
|
|
2019-02-06 23:42:44 +03:00
|
|
|
static void pageant_conn_sent(Plug *plug, size_t bufsize)
|
2015-05-05 22:16:20 +03:00
|
|
|
{
|
2018-10-06 01:49:08 +03:00
|
|
|
/* struct pageant_conn_state *pc = container_of(
|
2018-10-05 09:24:16 +03:00
|
|
|
plug, struct pageant_conn_state, plug); */
|
2015-05-05 22:16:20 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We do nothing here, because we expect that there won't be a
|
|
|
|
* need to throttle and unthrottle the connection to an agent -
|
|
|
|
* clients will typically not send many requests, and will wait
|
|
|
|
* until they receive each reply before sending a new request.
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
static void pageant_conn_log(PageantClient *pc, PageantClientRequestId *reqid,
|
|
|
|
const char *fmt, va_list ap)
|
2015-05-06 21:32:26 +03:00
|
|
|
{
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
struct pageant_conn_state *pcs =
|
|
|
|
container_of(pc, struct pageant_conn_state, pc);
|
|
|
|
struct pageant_conn_queued_response *qr =
|
|
|
|
container_of(reqid, struct pageant_conn_queued_response, reqid);
|
|
|
|
|
2015-05-06 21:32:26 +03:00
|
|
|
char *formatted = dupvprintf(fmt, ap);
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_listener_client_log(pcs->plc, "c#%zu,r#%zu: %s",
|
|
|
|
pcs->conn_index, qr->req_index, formatted);
|
2015-05-06 21:32:26 +03:00
|
|
|
sfree(formatted);
|
|
|
|
}
|
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
static void pageant_conn_got_response(
|
|
|
|
PageantClient *pc, PageantClientRequestId *reqid, ptrlen response)
|
|
|
|
{
|
|
|
|
struct pageant_conn_state *pcs =
|
|
|
|
container_of(pc, struct pageant_conn_state, pc);
|
|
|
|
struct pageant_conn_queued_response *qr =
|
|
|
|
container_of(reqid, struct pageant_conn_queued_response, reqid);
|
|
|
|
|
|
|
|
qr->sb = strbuf_new_nm();
|
|
|
|
put_stringpl(qr->sb, response);
|
|
|
|
|
|
|
|
while (pcs->response_queue.next != &pcs->response_queue &&
|
|
|
|
pcs->response_queue.next->sb) {
|
|
|
|
qr = pcs->response_queue.next;
|
|
|
|
sk_write(pcs->connsock, qr->sb->u, qr->sb->len);
|
|
|
|
qr->next->prev = qr->prev;
|
|
|
|
qr->prev->next = qr->next;
|
|
|
|
strbuf_free(qr->sb);
|
|
|
|
sfree(qr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct PageantClientVtable pageant_connection_clientvt = {
|
|
|
|
pageant_conn_log,
|
|
|
|
pageant_conn_got_response,
|
|
|
|
};
|
|
|
|
|
2019-02-06 23:18:19 +03:00
|
|
|
static void pageant_conn_receive(
|
2019-02-06 23:42:44 +03:00
|
|
|
Plug *plug, int urgent, const char *data, size_t len)
|
2015-05-05 22:16:20 +03:00
|
|
|
{
|
2018-10-06 01:49:08 +03:00
|
|
|
struct pageant_conn_state *pc = container_of(
|
2018-10-05 09:24:16 +03:00
|
|
|
plug, struct pageant_conn_state, plug);
|
2015-05-05 22:16:20 +03:00
|
|
|
char c;
|
|
|
|
|
|
|
|
crBegin(pc->crLine);
|
|
|
|
|
|
|
|
while (len > 0) {
|
|
|
|
pc->got = 0;
|
|
|
|
while (pc->got < 4) {
|
|
|
|
crGetChar(c);
|
|
|
|
pc->lenbuf[pc->got++] = c;
|
|
|
|
}
|
|
|
|
|
2019-02-04 10:39:03 +03:00
|
|
|
pc->len = GET_32BIT_MSB_FIRST(pc->lenbuf);
|
2015-05-05 22:16:20 +03:00
|
|
|
pc->got = 0;
|
|
|
|
pc->real_packet = (pc->len < AGENT_MAX_MSGLEN-4);
|
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
{
|
|
|
|
struct pageant_conn_queued_response *qr =
|
|
|
|
snew(struct pageant_conn_queued_response);
|
|
|
|
qr->prev = pc->response_queue.prev;
|
|
|
|
qr->next = &pc->response_queue;
|
|
|
|
qr->prev->next = qr->next->prev = qr;
|
|
|
|
qr->sb = NULL;
|
|
|
|
qr->req_index = pc->req_index++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!pc->real_packet) {
|
|
|
|
/*
|
|
|
|
* Send failure immediately, before consuming the packet
|
|
|
|
* data. That way we notify the client reasonably early
|
|
|
|
* even if the data channel has just started spewing
|
|
|
|
* nonsense.
|
|
|
|
*/
|
|
|
|
pageant_client_log(&pc->pc, &pc->response_queue.prev->reqid,
|
|
|
|
"early reply: SSH_AGENT_FAILURE "
|
|
|
|
"(overlong message, length %u)", pc->len);
|
|
|
|
static const unsigned char failure[] = { SSH_AGENT_FAILURE };
|
|
|
|
pageant_conn_got_response(&pc->pc, &pc->response_queue.prev->reqid,
|
|
|
|
make_ptrlen(failure, lenof(failure)));
|
|
|
|
}
|
|
|
|
|
2015-05-05 22:16:20 +03:00
|
|
|
while (pc->got < pc->len) {
|
|
|
|
crGetChar(c);
|
|
|
|
if (pc->real_packet)
|
|
|
|
pc->pktbuf[pc->got] = c;
|
|
|
|
pc->got++;
|
|
|
|
}
|
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
if (pc->real_packet)
|
|
|
|
pageant_handle_msg(&pc->pc, &pc->response_queue.prev->reqid,
|
|
|
|
make_ptrlen(pc->pktbuf, pc->len));
|
2015-05-05 22:16:20 +03:00
|
|
|
}
|
|
|
|
|
2016-06-03 01:03:24 +03:00
|
|
|
crFinishV;
|
2015-05-05 22:16:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
struct pageant_listen_state {
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 21:10:23 +03:00
|
|
|
Socket *listensock;
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
PageantListenerClient *plc;
|
|
|
|
size_t conn_index; /* for indexing connections in log messages */
|
2018-05-27 11:29:33 +03:00
|
|
|
|
2018-10-05 09:24:16 +03:00
|
|
|
Plug plug;
|
2015-05-05 22:16:20 +03:00
|
|
|
};
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 21:10:23 +03:00
|
|
|
static void pageant_listen_closing(Plug *plug, const char *error_msg,
|
2019-09-08 22:29:00 +03:00
|
|
|
int error_code, bool calling_back)
|
2015-05-05 22:16:20 +03:00
|
|
|
{
|
2018-10-06 01:49:08 +03:00
|
|
|
struct pageant_listen_state *pl = container_of(
|
2018-10-05 09:24:16 +03:00
|
|
|
plug, struct pageant_listen_state, plug);
|
2015-05-06 21:32:26 +03:00
|
|
|
if (error_msg)
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_listener_client_log(pl->plc, "listening socket: error: %s",
|
|
|
|
error_msg);
|
2015-05-05 22:16:20 +03:00
|
|
|
sk_close(pl->listensock);
|
|
|
|
pl->listensock = NULL;
|
|
|
|
}
|
|
|
|
|
2018-10-05 09:03:46 +03:00
|
|
|
static const PlugVtable pageant_connection_plugvt = {
|
2018-05-27 11:29:33 +03:00
|
|
|
NULL, /* no log function, because that's for outgoing connections */
|
|
|
|
pageant_conn_closing,
|
|
|
|
pageant_conn_receive,
|
|
|
|
pageant_conn_sent,
|
|
|
|
NULL /* no accepting function, because we've already done it */
|
|
|
|
};
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 21:10:23 +03:00
|
|
|
static int pageant_listen_accepting(Plug *plug,
|
2015-05-05 22:16:20 +03:00
|
|
|
accept_fn_t constructor, accept_ctx_t ctx)
|
|
|
|
{
|
2018-10-06 01:49:08 +03:00
|
|
|
struct pageant_listen_state *pl = container_of(
|
2018-10-05 09:24:16 +03:00
|
|
|
plug, struct pageant_listen_state, plug);
|
2015-05-05 22:16:20 +03:00
|
|
|
struct pageant_conn_state *pc;
|
|
|
|
const char *err;
|
2018-10-18 22:06:42 +03:00
|
|
|
SocketPeerInfo *peerinfo;
|
2015-05-05 22:16:20 +03:00
|
|
|
|
|
|
|
pc = snew(struct pageant_conn_state);
|
2018-10-05 09:24:16 +03:00
|
|
|
pc->plug.vt = &pageant_connection_plugvt;
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pc->pc.vt = &pageant_connection_clientvt;
|
|
|
|
pc->plc = pl->plc;
|
|
|
|
pc->response_queue.next = pc->response_queue.prev = &pc->response_queue;
|
|
|
|
pc->conn_index = pl->conn_index++;
|
|
|
|
pc->req_index = 0;
|
2015-05-05 22:16:20 +03:00
|
|
|
pc->crLine = 0;
|
|
|
|
|
2018-10-05 09:24:16 +03:00
|
|
|
pc->connsock = constructor(ctx, &pc->plug);
|
2015-05-05 22:16:20 +03:00
|
|
|
if ((err = sk_socket_error(pc->connsock)) != NULL) {
|
|
|
|
sk_close(pc->connsock);
|
|
|
|
sfree(pc);
|
2019-09-08 22:29:00 +03:00
|
|
|
return 1;
|
2015-05-05 22:16:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
sk_set_frozen(pc->connsock, 0);
|
|
|
|
|
2015-05-18 15:57:45 +03:00
|
|
|
peerinfo = sk_peer_info(pc->connsock);
|
2018-10-18 22:06:42 +03:00
|
|
|
if (peerinfo && peerinfo->log_text) {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_listener_client_log(pl->plc, "c#%zu: new connection from %s",
|
|
|
|
pc->conn_index, peerinfo->log_text);
|
2015-05-18 15:57:45 +03:00
|
|
|
} else {
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_listener_client_log(pl->plc, "c#%zu: new connection",
|
|
|
|
pc->conn_index);
|
2015-05-18 15:57:45 +03:00
|
|
|
}
|
2018-10-18 22:06:42 +03:00
|
|
|
sk_free_peer_info(peerinfo);
|
2015-05-05 22:16:20 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pageant_register_client(&pc->pc);
|
|
|
|
|
2015-05-05 22:16:20 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-10-05 09:03:46 +03:00
|
|
|
static const PlugVtable pageant_listener_plugvt = {
|
2018-05-27 11:29:33 +03:00
|
|
|
NULL, /* no log function, because that's for outgoing connections */
|
|
|
|
pageant_listen_closing,
|
|
|
|
NULL, /* no receive function on a listening socket */
|
|
|
|
NULL, /* no sent function on a listening socket */
|
|
|
|
pageant_listen_accepting
|
|
|
|
};
|
2015-05-05 22:16:20 +03:00
|
|
|
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
struct pageant_listen_state *pageant_listener_new(
|
|
|
|
Plug **plug, PageantListenerClient *plc)
|
2018-05-27 11:29:33 +03:00
|
|
|
{
|
2015-05-05 22:16:20 +03:00
|
|
|
struct pageant_listen_state *pl = snew(struct pageant_listen_state);
|
2018-10-05 09:24:16 +03:00
|
|
|
pl->plug.vt = &pageant_listener_plugvt;
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pl->plc = plc;
|
2015-05-05 22:16:20 +03:00
|
|
|
pl->listensock = NULL;
|
Pageant: new asynchronous internal APIs.
This is a pure refactoring: no functional change expected.
This commit introduces two new small vtable-style APIs. One is
PageantClient, which identifies a particular client of the Pageant
'core' (meaning the code that handles each individual request). This
changes pageant_handle_msg into an asynchronous operation: you pass in
an agent request message and an identifier, and at some later point,
the got_response method in your PageantClient will be called with the
answer (and the same identifier, to allow you to match requests to
responses). The trait vtable also contains a logging system.
The main importance of PageantClient, and the reason why it has to
exist instead of just passing pageant_handle_msg a bare callback
function pointer and context parameter, is that it provides robustness
if a client stops existing while a request is still pending. You call
pageant_unregister_client, and any unfinished requests associated with
that client in the Pageant core will be cleaned up, so that you're
guaranteed that after the unregister operation, no stray callbacks
will happen with a stale pointer to that client.
The WM_COPYDATA interface of Windows Pageant is a direct client of
this API. The other client is PageantListener, the system that lives
in pageant.c and handles stream-based agent connections for both Unix
Pageant and the new Windows named-pipe IPC. More specifically, each
individual connection to the listening socket is a separate
PageantClient, which means that if a socket is closed abruptly or
suffers an OS error, that client can be unregistered and any pending
requests cancelled without disrupting other connections.
Users of PageantListener have a second client vtable they can use,
called PageantListenerClient. That contains _only_ logging facilities,
and at the moment, only Unix Pageant bothers to use it (and even that
only in debugging mode).
Finally, internally to the Pageant core, there's a new trait called
PageantAsyncOp which describes an agent request in the process of
being handled. But at the moment, it has only one trivial
implementation, which is handed the full response message already
constructed, and on the next toplevel callback, passes it back to the
PageantClient.
2020-01-25 20:24:28 +03:00
|
|
|
pl->conn_index = 0;
|
2018-10-05 09:24:16 +03:00
|
|
|
*plug = &pl->plug;
|
2015-05-05 22:16:20 +03:00
|
|
|
return pl;
|
|
|
|
}
|
|
|
|
|
Get rid of lots of implicit pointer types.
All the main backend structures - Ssh, Telnet, Pty, Serial etc - now
describe structure types themselves rather than pointers to them. The
same goes for the codebase-wide trait types Socket and Plug, and the
supporting types SockAddr and Pinger.
All those things that were typedefed as pointers are older types; the
newer ones have the explicit * at the point of use, because that's
what I now seem to be preferring. But whichever one of those is
better, inconsistently using a mixture of the two styles is worse, so
let's make everything consistent.
A few types are still implicitly pointers, such as Bignum and some of
the GSSAPI types; generally this is either because they have to be
void *, or because they're typedefed differently on different
platforms and aren't always pointers at all. Can't be helped. But I've
got rid of the main ones, at least.
2018-10-04 21:10:23 +03:00
|
|
|
void pageant_listener_got_socket(struct pageant_listen_state *pl, Socket *sock)
|
2015-05-05 22:16:20 +03:00
|
|
|
{
|
|
|
|
pl->listensock = sock;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pageant_listener_free(struct pageant_listen_state *pl)
|
|
|
|
{
|
|
|
|
if (pl->listensock)
|
|
|
|
sk_close(pl->listensock);
|
|
|
|
sfree(pl);
|
|
|
|
}
|
2015-05-11 17:06:25 +03:00
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------
|
|
|
|
* Code to perform agent operations either as a client, or within the
|
|
|
|
* same process as the running agent.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static tree234 *passphrases = NULL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* After processing a list of filenames, we want to forget the
|
|
|
|
* passphrases.
|
|
|
|
*/
|
|
|
|
void pageant_forget_passphrases(void)
|
|
|
|
{
|
2015-05-14 11:16:26 +03:00
|
|
|
if (!passphrases) /* in case we never set it up at all */
|
|
|
|
return;
|
|
|
|
|
2015-05-11 17:06:25 +03:00
|
|
|
while (count234(passphrases) > 0) {
|
2019-09-08 22:29:00 +03:00
|
|
|
char *pp = index234(passphrases, 0);
|
|
|
|
smemclr(pp, strlen(pp));
|
|
|
|
delpos234(passphrases, 0);
|
|
|
|
sfree(pp);
|
2015-05-11 17:06:25 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void *pageant_get_keylist1(int *length)
|
|
|
|
{
|
|
|
|
void *ret;
|
|
|
|
|
|
|
|
if (!pageant_local) {
|
2018-05-24 15:18:13 +03:00
|
|
|
strbuf *request;
|
2019-09-08 22:29:00 +03:00
|
|
|
unsigned char *response;
|
|
|
|
void *vresponse;
|
|
|
|
int resplen;
|
2017-01-29 23:24:15 +03:00
|
|
|
|
2018-05-24 15:18:13 +03:00
|
|
|
request = strbuf_new_for_agent_query();
|
2019-09-08 22:29:00 +03:00
|
|
|
put_byte(request, SSH1_AGENTC_REQUEST_RSA_IDENTITIES);
|
2018-05-24 15:18:13 +03:00
|
|
|
agent_query_synchronous(request, &vresponse, &resplen);
|
|
|
|
strbuf_free(request);
|
2015-05-11 17:06:25 +03:00
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
response = vresponse;
|
|
|
|
if (resplen < 5 || response[4] != SSH1_AGENT_RSA_IDENTITIES_ANSWER) {
|
2015-05-11 17:06:25 +03:00
|
|
|
sfree(response);
|
2019-09-08 22:29:00 +03:00
|
|
|
return NULL;
|
2015-05-11 17:06:25 +03:00
|
|
|
}
|
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
ret = snewn(resplen-5, unsigned char);
|
|
|
|
memcpy(ret, response+5, resplen-5);
|
|
|
|
sfree(response);
|
2015-05-11 17:06:25 +03:00
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
if (length)
|
|
|
|
*length = resplen-5;
|
2015-05-11 17:06:25 +03:00
|
|
|
} else {
|
2018-05-24 15:23:17 +03:00
|
|
|
strbuf *buf = strbuf_new();
|
2019-09-08 22:29:00 +03:00
|
|
|
pageant_make_keylist1(BinarySink_UPCAST(buf));
|
2018-05-24 15:23:17 +03:00
|
|
|
*length = buf->len;
|
|
|
|
ret = strbuf_to_str(buf);
|
2015-05-11 17:06:25 +03:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *pageant_get_keylist2(int *length)
|
|
|
|
{
|
|
|
|
void *ret;
|
|
|
|
|
|
|
|
if (!pageant_local) {
|
2018-05-24 15:18:13 +03:00
|
|
|
strbuf *request;
|
2019-09-08 22:29:00 +03:00
|
|
|
unsigned char *response;
|
|
|
|
void *vresponse;
|
|
|
|
int resplen;
|
2015-05-11 17:06:25 +03:00
|
|
|
|
2018-05-24 15:18:13 +03:00
|
|
|
request = strbuf_new_for_agent_query();
|
2019-09-08 22:29:00 +03:00
|
|
|
put_byte(request, SSH2_AGENTC_REQUEST_IDENTITIES);
|
2018-05-24 15:18:13 +03:00
|
|
|
agent_query_synchronous(request, &vresponse, &resplen);
|
|
|
|
strbuf_free(request);
|
2015-05-11 17:06:25 +03:00
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
response = vresponse;
|
|
|
|
if (resplen < 5 || response[4] != SSH2_AGENT_IDENTITIES_ANSWER) {
|
2015-05-11 17:06:25 +03:00
|
|
|
sfree(response);
|
2019-09-08 22:29:00 +03:00
|
|
|
return NULL;
|
2015-05-11 17:06:25 +03:00
|
|
|
}
|
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
ret = snewn(resplen-5, unsigned char);
|
|
|
|
memcpy(ret, response+5, resplen-5);
|
|
|
|
sfree(response);
|
2015-05-11 17:06:25 +03:00
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
if (length)
|
|
|
|
*length = resplen-5;
|
2015-05-11 17:06:25 +03:00
|
|
|
} else {
|
2018-05-24 15:23:17 +03:00
|
|
|
strbuf *buf = strbuf_new();
|
2019-09-08 22:29:00 +03:00
|
|
|
pageant_make_keylist2(BinarySink_UPCAST(buf));
|
2018-05-24 15:23:17 +03:00
|
|
|
*length = buf->len;
|
|
|
|
ret = strbuf_to_str(buf);
|
2015-05-11 17:06:25 +03:00
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int pageant_add_keyfile(Filename *filename, const char *passphrase,
|
|
|
|
char **retstr)
|
|
|
|
{
|
2019-01-04 09:51:44 +03:00
|
|
|
RSAKey *rkey = NULL;
|
|
|
|
ssh2_userkey *skey = NULL;
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 22:23:19 +03:00
|
|
|
bool needs_pass;
|
2015-05-11 17:06:25 +03:00
|
|
|
int ret;
|
|
|
|
int attempts;
|
|
|
|
char *comment;
|
|
|
|
const char *this_passphrase;
|
|
|
|
const char *error = NULL;
|
|
|
|
int type;
|
|
|
|
|
|
|
|
if (!passphrases) {
|
|
|
|
passphrases = newtree234(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
*retstr = NULL;
|
|
|
|
|
|
|
|
type = key_type(filename);
|
|
|
|
if (type != SSH_KEYTYPE_SSH1 && type != SSH_KEYTYPE_SSH2) {
|
2019-09-08 22:29:00 +03:00
|
|
|
*retstr = dupprintf("Couldn't load this key (%s)",
|
2015-05-11 17:06:25 +03:00
|
|
|
key_type_to_str(type));
|
2019-09-08 22:29:00 +03:00
|
|
|
return PAGEANT_ACTION_FAILURE;
|
2015-05-11 17:06:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* See if the key is already loaded (in the primary Pageant,
|
|
|
|
* which may or may not be us).
|
|
|
|
*/
|
|
|
|
{
|
2019-09-08 22:29:00 +03:00
|
|
|
strbuf *blob = strbuf_new();
|
|
|
|
unsigned char *keylist, *p;
|
|
|
|
int i, nkeys, keylistlen;
|
2015-05-11 17:06:25 +03:00
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
if (type == SSH_KEYTYPE_SSH1) {
|
2020-01-05 13:28:45 +03:00
|
|
|
if (!rsa1_loadpub_f(filename, BinarySink_UPCAST(blob),
|
|
|
|
NULL, &error)) {
|
2015-05-11 17:06:25 +03:00
|
|
|
*retstr = dupprintf("Couldn't load private key (%s)", error);
|
2018-05-24 12:59:39 +03:00
|
|
|
strbuf_free(blob);
|
2015-05-11 17:06:25 +03:00
|
|
|
return PAGEANT_ACTION_FAILURE;
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
keylist = pageant_get_keylist1(&keylistlen);
|
|
|
|
} else {
|
|
|
|
/* For our purposes we want the blob prefixed with its
|
2018-05-24 12:59:39 +03:00
|
|
|
* length, so add a placeholder here to fill in
|
|
|
|
* afterwards */
|
|
|
|
put_uint32(blob, 0);
|
2020-01-05 13:28:45 +03:00
|
|
|
if (!ppk_loadpub_f(filename, NULL, BinarySink_UPCAST(blob),
|
|
|
|
NULL, &error)) {
|
2015-05-11 17:06:25 +03:00
|
|
|
*retstr = dupprintf("Couldn't load private key (%s)", error);
|
2018-05-24 12:59:39 +03:00
|
|
|
strbuf_free(blob);
|
2019-09-08 22:29:00 +03:00
|
|
|
return PAGEANT_ACTION_FAILURE;
|
|
|
|
}
|
|
|
|
PUT_32BIT_MSB_FIRST(blob->s, blob->len - 4);
|
|
|
|
keylist = pageant_get_keylist2(&keylistlen);
|
|
|
|
}
|
|
|
|
if (keylist) {
|
|
|
|
if (keylistlen < 4) {
|
|
|
|
*retstr = dupstr("Received broken key list from agent");
|
2017-02-15 08:31:51 +03:00
|
|
|
sfree(keylist);
|
2018-05-24 12:59:39 +03:00
|
|
|
strbuf_free(blob);
|
2019-09-08 22:29:00 +03:00
|
|
|
return PAGEANT_ACTION_FAILURE;
|
|
|
|
}
|
|
|
|
nkeys = toint(GET_32BIT_MSB_FIRST(keylist));
|
|
|
|
if (nkeys < 0) {
|
|
|
|
*retstr = dupstr("Received broken key list from agent");
|
2017-02-15 08:31:51 +03:00
|
|
|
sfree(keylist);
|
2018-05-24 12:59:39 +03:00
|
|
|
strbuf_free(blob);
|
2019-09-08 22:29:00 +03:00
|
|
|
return PAGEANT_ACTION_FAILURE;
|
|
|
|
}
|
|
|
|
p = keylist + 4;
|
|
|
|
keylistlen -= 4;
|
|
|
|
|
|
|
|
for (i = 0; i < nkeys; i++) {
|
|
|
|
if (!memcmp(blob->s, p, blob->len)) {
|
|
|
|
/* Key is already present; we can now leave. */
|
|
|
|
sfree(keylist);
|
|
|
|
strbuf_free(blob);
|
2015-05-11 17:06:25 +03:00
|
|
|
return PAGEANT_ACTION_OK;
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
/* Now skip over public blob */
|
|
|
|
if (type == SSH_KEYTYPE_SSH1) {
|
|
|
|
int n = rsa_ssh1_public_blob_len(
|
2019-01-02 00:07:48 +03:00
|
|
|
make_ptrlen(p, keylistlen));
|
2019-09-08 22:29:00 +03:00
|
|
|
if (n < 0) {
|
2015-05-11 17:06:25 +03:00
|
|
|
*retstr = dupstr("Received broken key list from agent");
|
2017-02-14 23:42:26 +03:00
|
|
|
sfree(keylist);
|
2018-05-24 12:59:39 +03:00
|
|
|
strbuf_free(blob);
|
2015-05-11 17:06:25 +03:00
|
|
|
return PAGEANT_ACTION_FAILURE;
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
p += n;
|
|
|
|
keylistlen -= n;
|
|
|
|
} else {
|
|
|
|
int n;
|
|
|
|
if (keylistlen < 4) {
|
2015-05-11 17:06:25 +03:00
|
|
|
*retstr = dupstr("Received broken key list from agent");
|
2017-02-14 23:42:26 +03:00
|
|
|
sfree(keylist);
|
2018-05-24 12:59:39 +03:00
|
|
|
strbuf_free(blob);
|
2015-05-11 17:06:25 +03:00
|
|
|
return PAGEANT_ACTION_FAILURE;
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
n = GET_32BIT_MSB_FIRST(p);
|
Tweak bounds checks in pageant_add_keyfile.
When we're going through the response from an SSH agent we asked for a
list of keys, and processing the string lengths in the SSH-2 sequence
of (public blob, comment) pairs, we were adding 4 to each string
length, and although we checked if the result came out to a negative
value (if interpreted as a signed integer) or a positive one going
beyond the end of the response buffer, we didn't check if it wrapped
round to a positive value less than 4. As a result, if an agent
returned malformed data sent a length field of 0xFFFFFFFC, the pointer
would advance no distance at all through the buffer, and the next
iteration of the loop would check the same length field again.
(However, this would only consume CPU pointlessly for a limited time,
because the outer loop up to 'nkeys' would still terminate sooner or
later. Also, I don't think this can sensibly be classed as a serious
security hazard - it's arguably a borderline DoS, but it requires a
hostile SSH _agent_ if data of that type is to be sent on purpose, and
an untrusted SSH agent is not part of the normal security model!)
2017-01-23 23:08:18 +03:00
|
|
|
p += 4;
|
|
|
|
keylistlen -= 4;
|
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
if (n < 0 || n > keylistlen) {
|
2015-05-11 17:06:25 +03:00
|
|
|
*retstr = dupstr("Received broken key list from agent");
|
2017-02-14 23:42:26 +03:00
|
|
|
sfree(keylist);
|
2018-05-24 12:59:39 +03:00
|
|
|
strbuf_free(blob);
|
2015-05-11 17:06:25 +03:00
|
|
|
return PAGEANT_ACTION_FAILURE;
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
p += n;
|
|
|
|
keylistlen -= n;
|
|
|
|
}
|
|
|
|
/* Now skip over comment field */
|
|
|
|
{
|
|
|
|
int n;
|
|
|
|
if (keylistlen < 4) {
|
2015-05-11 17:06:25 +03:00
|
|
|
*retstr = dupstr("Received broken key list from agent");
|
2017-02-14 23:42:26 +03:00
|
|
|
sfree(keylist);
|
2018-05-24 12:59:39 +03:00
|
|
|
strbuf_free(blob);
|
2015-05-11 17:06:25 +03:00
|
|
|
return PAGEANT_ACTION_FAILURE;
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
n = GET_32BIT_MSB_FIRST(p);
|
Tweak bounds checks in pageant_add_keyfile.
When we're going through the response from an SSH agent we asked for a
list of keys, and processing the string lengths in the SSH-2 sequence
of (public blob, comment) pairs, we were adding 4 to each string
length, and although we checked if the result came out to a negative
value (if interpreted as a signed integer) or a positive one going
beyond the end of the response buffer, we didn't check if it wrapped
round to a positive value less than 4. As a result, if an agent
returned malformed data sent a length field of 0xFFFFFFFC, the pointer
would advance no distance at all through the buffer, and the next
iteration of the loop would check the same length field again.
(However, this would only consume CPU pointlessly for a limited time,
because the outer loop up to 'nkeys' would still terminate sooner or
later. Also, I don't think this can sensibly be classed as a serious
security hazard - it's arguably a borderline DoS, but it requires a
hostile SSH _agent_ if data of that type is to be sent on purpose, and
an untrusted SSH agent is not part of the normal security model!)
2017-01-23 23:08:18 +03:00
|
|
|
p += 4;
|
|
|
|
keylistlen -= 4;
|
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
if (n < 0 || n > keylistlen) {
|
2015-05-11 17:06:25 +03:00
|
|
|
*retstr = dupstr("Received broken key list from agent");
|
2017-02-14 23:42:26 +03:00
|
|
|
sfree(keylist);
|
2018-05-24 12:59:39 +03:00
|
|
|
strbuf_free(blob);
|
2015-05-11 17:06:25 +03:00
|
|
|
return PAGEANT_ACTION_FAILURE;
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
|
|
|
p += n;
|
|
|
|
keylistlen -= n;
|
|
|
|
}
|
|
|
|
}
|
2015-05-11 17:06:25 +03:00
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
sfree(keylist);
|
|
|
|
}
|
2015-05-11 17:06:25 +03:00
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
strbuf_free(blob);
|
2015-05-11 17:06:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
error = NULL;
|
|
|
|
if (type == SSH_KEYTYPE_SSH1)
|
2020-01-05 13:28:45 +03:00
|
|
|
needs_pass = rsa1_encrypted_f(filename, &comment);
|
2015-05-11 17:06:25 +03:00
|
|
|
else
|
2020-01-05 13:28:45 +03:00
|
|
|
needs_pass = ppk_encrypted_f(filename, &comment);
|
2015-05-11 17:06:25 +03:00
|
|
|
attempts = 0;
|
|
|
|
if (type == SSH_KEYTYPE_SSH1)
|
2019-09-08 22:29:00 +03:00
|
|
|
rkey = snew(RSAKey);
|
2015-05-11 17:06:25 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Loop round repeatedly trying to load the key, until we either
|
|
|
|
* succeed, fail for some serious reason, or run out of
|
|
|
|
* passphrases to try.
|
|
|
|
*/
|
|
|
|
while (1) {
|
2019-09-08 22:29:00 +03:00
|
|
|
if (needs_pass) {
|
2015-05-11 17:06:25 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If we've been given a passphrase on input, try using
|
|
|
|
* it. Otherwise, try one from our tree234 of previously
|
|
|
|
* useful passphrases.
|
|
|
|
*/
|
|
|
|
if (passphrase) {
|
|
|
|
this_passphrase = (attempts == 0 ? passphrase : NULL);
|
|
|
|
} else {
|
|
|
|
this_passphrase = (const char *)index234(passphrases, attempts);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this_passphrase) {
|
|
|
|
/*
|
|
|
|
* Run out of passphrases to try.
|
|
|
|
*/
|
|
|
|
*retstr = comment;
|
2017-02-14 23:42:26 +03:00
|
|
|
sfree(rkey);
|
2015-05-11 17:06:25 +03:00
|
|
|
return PAGEANT_ACTION_NEED_PP;
|
|
|
|
}
|
2019-09-08 22:29:00 +03:00
|
|
|
} else
|
|
|
|
this_passphrase = "";
|
|
|
|
|
|
|
|
if (type == SSH_KEYTYPE_SSH1)
|
2020-01-05 13:28:45 +03:00
|
|
|
ret = rsa1_load_f(filename, rkey, this_passphrase, &error);
|
2019-09-08 22:29:00 +03:00
|
|
|
else {
|
2020-01-05 13:28:45 +03:00
|
|
|
skey = ppk_load_f(filename, this_passphrase, &error);
|
2019-09-08 22:29:00 +03:00
|
|
|
if (skey == SSH2_WRONG_PASSPHRASE)
|
|
|
|
ret = -1;
|
|
|
|
else if (!skey)
|
|
|
|
ret = 0;
|
|
|
|
else
|
|
|
|
ret = 1;
|
|
|
|
}
|
2015-05-11 17:06:25 +03:00
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
/*
|
|
|
|
* Failed to load the key file, for some reason other than
|
|
|
|
* a bad passphrase.
|
|
|
|
*/
|
|
|
|
*retstr = dupstr(error);
|
2017-02-14 23:42:26 +03:00
|
|
|
sfree(rkey);
|
2019-05-04 18:19:13 +03:00
|
|
|
if (comment)
|
|
|
|
sfree(comment);
|
2015-05-11 17:06:25 +03:00
|
|
|
return PAGEANT_ACTION_FAILURE;
|
|
|
|
} else if (ret == 1) {
|
|
|
|
/*
|
|
|
|
* Successfully loaded the key file.
|
|
|
|
*/
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Passphrase wasn't right; go round again.
|
|
|
|
*/
|
|
|
|
attempts++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2017-04-15 11:06:22 +03:00
|
|
|
* If we get here, we've successfully loaded the key into
|
2015-05-11 17:06:25 +03:00
|
|
|
* rkey/skey, but not yet added it to the agent.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the key was successfully decrypted, save the passphrase for
|
|
|
|
* use with other keys we try to load.
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
char *pp_copy = dupstr(this_passphrase);
|
2019-09-08 22:29:00 +03:00
|
|
|
if (addpos234(passphrases, pp_copy, 0) != pp_copy) {
|
2015-05-11 17:06:25 +03:00
|
|
|
/* No need; it was already there. */
|
|
|
|
smemclr(pp_copy, strlen(pp_copy));
|
|
|
|
sfree(pp_copy);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (comment)
|
2019-09-08 22:29:00 +03:00
|
|
|
sfree(comment);
|
2015-05-11 17:06:25 +03:00
|
|
|
|
|
|
|
if (type == SSH_KEYTYPE_SSH1) {
|
2019-09-08 22:29:00 +03:00
|
|
|
if (!pageant_local) {
|
2018-05-24 15:18:13 +03:00
|
|
|
strbuf *request;
|
2019-09-08 22:29:00 +03:00
|
|
|
unsigned char *response;
|
|
|
|
void *vresponse;
|
|
|
|
int resplen;
|
|
|
|
|
|
|
|
request = strbuf_new_for_agent_query();
|
|
|
|
put_byte(request, SSH1_AGENTC_ADD_RSA_IDENTITY);
|
2020-01-09 22:16:29 +03:00
|
|
|
rsa_ssh1_private_blob_agent(BinarySink_UPCAST(request), rkey);
|
2019-09-08 22:29:00 +03:00
|
|
|
put_stringz(request, rkey->comment);
|
|
|
|
agent_query_synchronous(request, &vresponse, &resplen);
|
2018-05-24 15:18:13 +03:00
|
|
|
strbuf_free(request);
|
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
response = vresponse;
|
|
|
|
if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS) {
|
|
|
|
*retstr = dupstr("The already running Pageant "
|
2015-05-11 17:06:25 +03:00
|
|
|
"refused to add the key.");
|
2017-02-14 23:42:26 +03:00
|
|
|
freersakey(rkey);
|
|
|
|
sfree(rkey);
|
|
|
|
sfree(response);
|
2015-05-11 17:06:25 +03:00
|
|
|
return PAGEANT_ACTION_FAILURE;
|
|
|
|
}
|
2017-02-14 23:42:26 +03:00
|
|
|
freersakey(rkey);
|
|
|
|
sfree(rkey);
|
2019-09-08 22:29:00 +03:00
|
|
|
sfree(response);
|
|
|
|
} else {
|
|
|
|
if (!pageant_add_ssh1_key(rkey)) {
|
2017-02-14 23:42:26 +03:00
|
|
|
freersakey(rkey);
|
2019-09-08 22:29:00 +03:00
|
|
|
sfree(rkey); /* already present, don't waste RAM */
|
2015-05-11 17:06:25 +03:00
|
|
|
}
|
2019-09-08 22:29:00 +03:00
|
|
|
}
|
2015-05-11 17:06:25 +03:00
|
|
|
} else {
|
2019-09-08 22:29:00 +03:00
|
|
|
if (!pageant_local) {
|
|
|
|
strbuf *request;
|
2018-05-24 15:18:13 +03:00
|
|
|
unsigned char *response;
|
2019-09-08 22:29:00 +03:00
|
|
|
void *vresponse;
|
|
|
|
int resplen;
|
2018-05-24 15:18:13 +03:00
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
request = strbuf_new_for_agent_query();
|
|
|
|
put_byte(request, SSH2_AGENTC_ADD_IDENTITY);
|
|
|
|
put_stringz(request, ssh_key_ssh_id(skey->key));
|
2018-06-03 14:58:05 +03:00
|
|
|
ssh_key_openssh_blob(skey->key, BinarySink_UPCAST(request));
|
2019-09-08 22:29:00 +03:00
|
|
|
put_stringz(request, skey->comment);
|
|
|
|
agent_query_synchronous(request, &vresponse, &resplen);
|
2018-05-24 15:18:13 +03:00
|
|
|
strbuf_free(request);
|
|
|
|
|
2019-09-08 22:29:00 +03:00
|
|
|
response = vresponse;
|
|
|
|
if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS) {
|
|
|
|
*retstr = dupstr("The already running Pageant "
|
2015-05-11 17:06:25 +03:00
|
|
|
"refused to add the key.");
|
2017-02-14 23:42:26 +03:00
|
|
|
sfree(response);
|
2015-05-11 17:06:25 +03:00
|
|
|
return PAGEANT_ACTION_FAILURE;
|
|
|
|
}
|
|
|
|
|
2019-05-04 18:19:13 +03:00
|
|
|
ssh_key_free(skey->key);
|
|
|
|
sfree(skey);
|
2019-09-08 22:29:00 +03:00
|
|
|
sfree(response);
|
|
|
|
} else {
|
|
|
|
if (!pageant_add_ssh2_key(skey)) {
|
2018-06-03 14:58:05 +03:00
|
|
|
ssh_key_free(skey->key);
|
2019-09-08 22:29:00 +03:00
|
|
|
sfree(skey); /* already present, don't waste RAM */
|
|
|
|
}
|
|
|
|
}
|
2015-05-11 17:06:25 +03:00
|
|
|
}
|
|
|
|
return PAGEANT_ACTION_OK;
|
|
|
|
}
|
2015-05-11 20:34:45 +03:00
|
|
|
|
|
|
|
int pageant_enum_keys(pageant_key_enum_fn_t callback, void *callback_ctx,
|
|
|
|
char **retstr)
|
|
|
|
{
|
2018-05-28 01:58:20 +03:00
|
|
|
unsigned char *keylist;
|
2015-05-11 20:34:45 +03:00
|
|
|
int i, nkeys, keylistlen;
|
2018-05-28 01:58:20 +03:00
|
|
|
ptrlen comment;
|
2015-05-12 15:27:33 +03:00
|
|
|
struct pageant_pubkey cbkey;
|
2018-05-28 01:58:20 +03:00
|
|
|
BinarySource src[1];
|
2015-05-11 20:34:45 +03:00
|
|
|
|
|
|
|
keylist = pageant_get_keylist1(&keylistlen);
|
2018-05-28 01:58:20 +03:00
|
|
|
if (!keylist) {
|
|
|
|
*retstr = dupstr("Did not receive an SSH-1 key list from agent");
|
2015-05-11 20:34:45 +03:00
|
|
|
return PAGEANT_ACTION_FAILURE;
|
|
|
|
}
|
2018-05-28 01:58:20 +03:00
|
|
|
BinarySource_BARE_INIT(src, keylist, keylistlen);
|
2015-05-11 20:34:45 +03:00
|
|
|
|
2018-05-28 01:58:20 +03:00
|
|
|
nkeys = toint(get_uint32(src));
|
2015-05-11 20:34:45 +03:00
|
|
|
for (i = 0; i < nkeys; i++) {
|
2019-01-04 09:51:44 +03:00
|
|
|
RSAKey rkey;
|
2018-06-03 10:08:53 +03:00
|
|
|
char *fingerprint;
|
2015-05-11 20:34:45 +03:00
|
|
|
|
|
|
|
/* public blob and fingerprint */
|
|
|
|
memset(&rkey, 0, sizeof(rkey));
|
2018-06-03 10:23:07 +03:00
|
|
|
get_rsa_ssh1_pub(src, &rkey, RSA_SSH1_EXPONENT_FIRST);
|
2018-05-28 01:58:20 +03:00
|
|
|
comment = get_string(src);
|
2015-05-11 20:34:45 +03:00
|
|
|
|
2018-05-28 01:58:20 +03:00
|
|
|
if (get_err(src)) {
|
2015-05-11 20:34:45 +03:00
|
|
|
*retstr = dupstr("Received broken SSH-1 key list from agent");
|
|
|
|
freersakey(&rkey);
|
|
|
|
sfree(keylist);
|
|
|
|
return PAGEANT_ACTION_FAILURE;
|
|
|
|
}
|
2018-05-28 01:58:20 +03:00
|
|
|
|
2018-06-03 10:08:53 +03:00
|
|
|
fingerprint = rsa_ssh1_fingerprint(&rkey);
|
2015-05-11 20:34:45 +03:00
|
|
|
|
2020-01-06 23:59:07 +03:00
|
|
|
cbkey.blob = makeblob1(&rkey);
|
2018-05-28 01:58:20 +03:00
|
|
|
cbkey.comment = mkstr(comment);
|
2015-05-12 15:27:33 +03:00
|
|
|
cbkey.ssh_version = 1;
|
2018-05-28 01:58:20 +03:00
|
|
|
callback(callback_ctx, fingerprint, cbkey.comment, &cbkey);
|
2018-05-24 12:59:39 +03:00
|
|
|
strbuf_free(cbkey.blob);
|
2015-05-11 20:34:45 +03:00
|
|
|
freersakey(&rkey);
|
2018-05-28 01:58:20 +03:00
|
|
|
sfree(cbkey.comment);
|
2018-06-03 10:08:53 +03:00
|
|
|
sfree(fingerprint);
|
2015-05-11 20:34:45 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
sfree(keylist);
|
|
|
|
|
2018-05-28 01:58:20 +03:00
|
|
|
if (get_err(src) || get_avail(src) != 0) {
|
2015-05-11 20:34:45 +03:00
|
|
|
*retstr = dupstr("Received broken SSH-1 key list from agent");
|
|
|
|
return PAGEANT_ACTION_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
keylist = pageant_get_keylist2(&keylistlen);
|
2018-05-28 01:58:20 +03:00
|
|
|
if (!keylist) {
|
|
|
|
*retstr = dupstr("Did not receive an SSH-2 key list from agent");
|
2015-05-11 20:34:45 +03:00
|
|
|
return PAGEANT_ACTION_FAILURE;
|
|
|
|
}
|
2018-05-28 01:58:20 +03:00
|
|
|
BinarySource_BARE_INIT(src, keylist, keylistlen);
|
2015-05-11 20:34:45 +03:00
|
|
|
|
2018-05-28 01:58:20 +03:00
|
|
|
nkeys = toint(get_uint32(src));
|
2015-05-11 20:34:45 +03:00
|
|
|
for (i = 0; i < nkeys; i++) {
|
2018-05-28 01:58:20 +03:00
|
|
|
ptrlen pubblob;
|
2015-05-11 20:34:45 +03:00
|
|
|
char *fingerprint;
|
|
|
|
|
2018-05-28 01:58:20 +03:00
|
|
|
pubblob = get_string(src);
|
|
|
|
comment = get_string(src);
|
2015-05-11 20:34:45 +03:00
|
|
|
|
2018-05-28 01:58:20 +03:00
|
|
|
if (get_err(src)) {
|
2015-05-11 20:34:45 +03:00
|
|
|
*retstr = dupstr("Received broken SSH-2 key list from agent");
|
|
|
|
sfree(keylist);
|
|
|
|
return PAGEANT_ACTION_FAILURE;
|
|
|
|
}
|
2018-05-28 01:58:20 +03:00
|
|
|
|
2019-02-06 23:48:03 +03:00
|
|
|
fingerprint = ssh2_fingerprint_blob(pubblob);
|
2018-05-28 01:58:20 +03:00
|
|
|
cbkey.blob = strbuf_new();
|
2019-01-01 22:00:19 +03:00
|
|
|
put_datapl(cbkey.blob, pubblob);
|
2015-05-11 20:34:45 +03:00
|
|
|
|
2015-05-12 15:27:33 +03:00
|
|
|
cbkey.ssh_version = 2;
|
2018-05-28 01:58:20 +03:00
|
|
|
cbkey.comment = mkstr(comment);
|
|
|
|
callback(callback_ctx, fingerprint, cbkey.comment, &cbkey);
|
2015-05-11 20:34:45 +03:00
|
|
|
sfree(fingerprint);
|
2018-05-28 01:58:20 +03:00
|
|
|
sfree(cbkey.comment);
|
2015-05-11 20:34:45 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
sfree(keylist);
|
|
|
|
|
2018-05-28 01:58:20 +03:00
|
|
|
if (get_err(src) || get_avail(src) != 0) {
|
2018-05-25 16:01:59 +03:00
|
|
|
*retstr = dupstr("Received broken SSH-2 key list from agent");
|
2015-05-11 20:34:45 +03:00
|
|
|
return PAGEANT_ACTION_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return PAGEANT_ACTION_OK;
|
|
|
|
}
|
2015-05-12 15:27:33 +03:00
|
|
|
|
|
|
|
int pageant_delete_key(struct pageant_pubkey *key, char **retstr)
|
|
|
|
{
|
2018-05-24 15:18:13 +03:00
|
|
|
strbuf *request;
|
|
|
|
unsigned char *response;
|
|
|
|
int resplen, ret;
|
2015-05-12 15:27:33 +03:00
|
|
|
void *vresponse;
|
|
|
|
|
2018-05-24 15:18:13 +03:00
|
|
|
request = strbuf_new_for_agent_query();
|
|
|
|
|
2015-05-12 15:27:33 +03:00
|
|
|
if (key->ssh_version == 1) {
|
2018-05-24 15:18:13 +03:00
|
|
|
put_byte(request, SSH1_AGENTC_REMOVE_RSA_IDENTITY);
|
|
|
|
put_data(request, key->blob->s, key->blob->len);
|
2015-05-12 15:27:33 +03:00
|
|
|
} else {
|
2018-05-24 15:18:13 +03:00
|
|
|
put_byte(request, SSH2_AGENTC_REMOVE_IDENTITY);
|
|
|
|
put_string(request, key->blob->s, key->blob->len);
|
2015-05-12 15:27:33 +03:00
|
|
|
}
|
|
|
|
|
2018-05-24 15:18:13 +03:00
|
|
|
agent_query_synchronous(request, &vresponse, &resplen);
|
|
|
|
strbuf_free(request);
|
|
|
|
|
2015-05-12 15:27:33 +03:00
|
|
|
response = vresponse;
|
|
|
|
if (resplen < 5 || response[4] != SSH_AGENT_SUCCESS) {
|
|
|
|
*retstr = dupstr("Agent failed to delete key");
|
|
|
|
ret = PAGEANT_ACTION_FAILURE;
|
|
|
|
} else {
|
|
|
|
*retstr = NULL;
|
|
|
|
ret = PAGEANT_ACTION_OK;
|
|
|
|
}
|
|
|
|
sfree(response);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-05-12 16:55:44 +03:00
|
|
|
int pageant_delete_all_keys(char **retstr)
|
|
|
|
{
|
2018-05-24 15:18:13 +03:00
|
|
|
strbuf *request;
|
|
|
|
unsigned char *response;
|
Convert a lot of 'int' variables to 'bool'.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 22:23:19 +03:00
|
|
|
int resplen;
|
|
|
|
bool success;
|
2015-05-12 16:55:44 +03:00
|
|
|
void *vresponse;
|
|
|
|
|
2018-05-24 15:18:13 +03:00
|
|
|
request = strbuf_new_for_agent_query();
|
|
|
|
put_byte(request, SSH2_AGENTC_REMOVE_ALL_IDENTITIES);
|
|
|
|
agent_query_synchronous(request, &vresponse, &resplen);
|
|
|
|
strbuf_free(request);
|
2015-05-12 16:55:44 +03:00
|
|
|
response = vresponse;
|
|
|
|
success = (resplen >= 4 && response[4] == SSH_AGENT_SUCCESS);
|
|
|
|
sfree(response);
|
|
|
|
if (!success) {
|
|
|
|
*retstr = dupstr("Agent failed to delete SSH-2 keys");
|
|
|
|
return PAGEANT_ACTION_FAILURE;
|
|
|
|
}
|
|
|
|
|
2018-05-24 15:18:13 +03:00
|
|
|
request = strbuf_new_for_agent_query();
|
|
|
|
put_byte(request, SSH1_AGENTC_REMOVE_ALL_RSA_IDENTITIES);
|
|
|
|
agent_query_synchronous(request, &vresponse, &resplen);
|
|
|
|
strbuf_free(request);
|
2015-05-12 16:55:44 +03:00
|
|
|
response = vresponse;
|
|
|
|
success = (resplen >= 4 && response[4] == SSH_AGENT_SUCCESS);
|
|
|
|
sfree(response);
|
|
|
|
if (!success) {
|
|
|
|
*retstr = dupstr("Agent failed to delete SSH-1 keys");
|
|
|
|
return PAGEANT_ACTION_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
*retstr = NULL;
|
|
|
|
return PAGEANT_ACTION_OK;
|
|
|
|
}
|
|
|
|
|
2015-05-12 15:27:33 +03:00
|
|
|
struct pageant_pubkey *pageant_pubkey_copy(struct pageant_pubkey *key)
|
|
|
|
{
|
|
|
|
struct pageant_pubkey *ret = snew(struct pageant_pubkey);
|
2018-05-24 12:59:39 +03:00
|
|
|
ret->blob = strbuf_new();
|
|
|
|
put_data(ret->blob, key->blob->s, key->blob->len);
|
2015-05-12 16:48:32 +03:00
|
|
|
ret->comment = key->comment ? dupstr(key->comment) : NULL;
|
2015-05-12 15:27:33 +03:00
|
|
|
ret->ssh_version = key->ssh_version;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void pageant_pubkey_free(struct pageant_pubkey *key)
|
|
|
|
{
|
2015-05-12 16:48:32 +03:00
|
|
|
sfree(key->comment);
|
2018-05-24 12:59:39 +03:00
|
|
|
strbuf_free(key->blob);
|
2015-05-12 15:27:33 +03:00
|
|
|
sfree(key);
|
|
|
|
}
|