Fixed issue #3815: TortoiseGitMerge crashes on Win7 on startup when winrt libraries...
[TortoiseGit.git] / src / TortoisePlink / pageant.h
blob9f050c93bde3bc51a3f86ca75bd08b45b81970d0
1 /*
2 * pageant.h: header for pageant.c.
3 */
5 #include <stdarg.h>
7 /*
8 * Upper limit on length of any agent message. Used as a basic sanity
9 * check on messages' length fields, and used by the Windows Pageant
10 * client IPC to decide how large a file mapping to allocate.
12 #define AGENT_MAX_MSGLEN 262144
14 typedef struct PageantClientVtable PageantClientVtable;
15 typedef struct PageantClient PageantClient;
16 typedef struct PageantClientInfo PageantClientInfo;
17 typedef struct PageantClientRequestId PageantClientRequestId;
18 typedef struct PageantClientDialogId PageantClientDialogId;
19 struct PageantClient {
20 const struct PageantClientVtable *vt;
21 PageantClientInfo *info; /* used by the central Pageant code */
23 /* Setting this flag prevents the 'log' vtable entry from ever
24 * being called, so that it's safe to make it NULL. This also
25 * allows optimisations in the core code (it can avoid entire
26 * loops that are only used for logging purposes). So you can also
27 * set it dynamically if you find out at run time that you're not
28 * doing logging. */
29 bool suppress_logging;
31 struct PageantClientVtable {
32 void (*log)(PageantClient *pc, PageantClientRequestId *reqid,
33 const char *fmt, va_list ap);
34 void (*got_response)(PageantClient *pc, PageantClientRequestId *reqid,
35 ptrlen response);
36 bool (*ask_passphrase)(PageantClient *pc, PageantClientDialogId *dlgid,
37 const char *key_comment);
40 static inline void pageant_client_log_v(
41 PageantClient *pc, PageantClientRequestId *reqid,
42 const char *fmt, va_list ap)
44 if (!pc->suppress_logging)
45 pc->vt->log(pc, reqid, fmt, ap);
47 static inline PRINTF_LIKE(3, 4) void pageant_client_log(
48 PageantClient *pc, PageantClientRequestId *reqid, const char *fmt, ...)
50 if (!pc->suppress_logging) {
51 va_list ap;
52 va_start(ap, fmt);
53 pc->vt->log(pc, reqid, fmt, ap);
54 va_end(ap);
57 static inline void pageant_client_got_response(
58 PageantClient *pc, PageantClientRequestId *reqid, ptrlen response)
59 { pc->vt->got_response(pc, reqid, response); }
60 static inline bool pageant_client_ask_passphrase(
61 PageantClient *pc, PageantClientDialogId *dlgid, const char *comment)
62 { return pc->vt->ask_passphrase(pc, dlgid, comment); }
64 /* PageantClientRequestId is used to match up responses to the agent
65 * requests they refer to. A client may allocate one of these for each
66 * call to pageant_handle_request, (probably as a subfield of some
67 * larger struct on the client side) and expect the same pointer to be
68 * passed back in pageant_client_got_response. */
69 struct PageantClientRequestId { int unused_; };
72 * Initial setup.
74 void pageant_init(void);
77 * Register and unregister PageantClients. This is necessary so that
78 * when a PageantClient goes away, any unfinished asynchronous
79 * requests can be cleaned up.
81 * pageant_register_client will fill in pc->id. The client itself
82 * should not touch that field.
84 void pageant_register_client(PageantClient *pc);
85 void pageant_unregister_client(PageantClient *pc);
88 * The main agent function that answers messages.
90 * Expects a message/length pair as input, minus its initial length
91 * field but still with its type code on the front.
93 * When a response is ready, the got_response method in the
94 * PageantClient vtable will be passed it in the form of a ptrlen,
95 * again minus its length field.
97 void pageant_handle_msg(PageantClient *pc, PageantClientRequestId *reqid,
98 ptrlen msg);
101 * Send the core Pageant code a response to a passphrase request.
103 void pageant_passphrase_request_success(PageantClientDialogId *dlgid,
104 ptrlen passphrase);
105 void pageant_passphrase_request_refused(PageantClientDialogId *dlgid);
108 * Construct a list of public keys, just as the two LIST_IDENTITIES
109 * requests would have returned them.
111 void pageant_make_keylist1(BinarySink *);
112 void pageant_make_keylist2(BinarySink *);
115 * Accessor functions for Pageant's internal key lists, used by GUI
116 * Pageant, to count the keys, to delete a key, or to re-encrypt a
117 * decrypted-on-demand key (SSH-2 only).
119 int pageant_count_ssh1_keys(void);
120 int pageant_count_ssh2_keys(void);
121 bool pageant_delete_nth_ssh1_key(int i);
122 bool pageant_delete_nth_ssh2_key(int i);
123 bool pageant_reencrypt_nth_ssh2_key(int i);
124 void pageant_delete_all(void);
125 void pageant_reencrypt_all(void);
128 * This callback must be provided by the Pageant front end code.
129 * pageant_handle_msg calls it to indicate that the message it's just
130 * handled has changed the list of keys held by the agent. Front ends
131 * which expose that key list through dedicated UI may need to refresh
132 * that UI's state in this function; other front ends can leave it
133 * empty.
135 void keylist_update(void);
138 * Functions to establish a listening socket speaking the SSH agent
139 * protocol. Call pageant_listener_new() to set up a state; then
140 * create a socket using the returned Plug; then call
141 * pageant_listener_got_socket() to give the listening state its own
142 * socket pointer. Also, provide a logging function later if you want
143 * to.
145 typedef struct PageantListenerClientVtable PageantListenerClientVtable;
146 typedef struct PageantListenerClient PageantListenerClient;
147 struct PageantListenerClient {
148 const PageantListenerClientVtable *vt;
149 /* suppress_logging flag works similarly to the one in
150 * PageantClient, but it is only read when a new connection comes
151 * in. So if you do need to change it in mid-run, expect existing
152 * agent connections to still use the old value. */
153 bool suppress_logging;
155 struct PageantListenerClientVtable {
156 void (*log)(PageantListenerClient *, const char *fmt, va_list ap);
157 bool (*ask_passphrase)(PageantListenerClient *pc,
158 PageantClientDialogId *dlgid,
159 const char *key_comment);
162 static inline void pageant_listener_client_log_v(
163 PageantListenerClient *plc, const char *fmt, va_list ap)
165 if (!plc->suppress_logging)
166 plc->vt->log(plc, fmt, ap);
168 static inline PRINTF_LIKE(2, 3) void pageant_listener_client_log(
169 PageantListenerClient *plc, const char *fmt, ...)
171 if (!plc->suppress_logging) {
172 va_list ap;
173 va_start(ap, fmt);
174 plc->vt->log(plc, fmt, ap);
175 va_end(ap);
178 static inline bool pageant_listener_client_ask_passphrase(
179 PageantListenerClient *plc, PageantClientDialogId *dlgid,
180 const char *comment)
181 { return plc->vt->ask_passphrase(plc, dlgid, comment); }
183 struct pageant_listen_state;
184 struct pageant_listen_state *pageant_listener_new(
185 Plug **plug, PageantListenerClient *plc);
186 void pageant_listener_got_socket(struct pageant_listen_state *pl, Socket *);
187 void pageant_listener_free(struct pageant_listen_state *pl);
190 * Functions to perform specific key actions, either as a client of an
191 * ssh-agent running elsewhere, or directly on the agent state in this
192 * process. (On at least one platform we want to do this in an
193 * agnostic way between the two situations.)
195 * pageant_add_keyfile() is used to load a private key from a file and
196 * add it to the agent. Initially, you should call it with passphrase
197 * NULL, and it will check if the key is already in the agent, and
198 * whether a passphrase is required. Return values are given in the
199 * enum below. On return, *retstr will either be NULL, or a
200 * dynamically allocated string containing a key comment or an error
201 * message.
203 * pageant_add_keyfile() also remembers passphrases with which it's
204 * successfully decrypted keys (because if you try to add multiple
205 * keys in one go, you might very well have used the same passphrase
206 * for keys that have the same trust properties). Call
207 * pageant_forget_passphrases() to get rid of them all.
209 enum {
210 PAGEANT_ACTION_OK, /* success; no further action needed */
211 PAGEANT_ACTION_FAILURE, /* failure; *retstr is error message */
212 PAGEANT_ACTION_NEED_PP, /* need passphrase: *retstr is key comment */
213 PAGEANT_ACTION_WARNING, /* success but with a warning message;
214 * *retstr is warning message */
216 int pageant_add_keyfile(Filename *filename, const char *passphrase,
217 char **retstr, bool add_encrypted);
218 void pageant_forget_passphrases(void);
220 struct pageant_pubkey {
221 /* Everything needed to identify a public key found by
222 * pageant_enum_keys and pass it back to the agent or other code
223 * later */
224 strbuf *blob;
225 char *comment;
226 int ssh_version;
228 struct pageant_pubkey *pageant_pubkey_copy(struct pageant_pubkey *key);
229 void pageant_pubkey_free(struct pageant_pubkey *key);
231 typedef void (*pageant_key_enum_fn_t)(void *ctx, char **fingerprints,
232 const char *comment, uint32_t ext_flags,
233 struct pageant_pubkey *key);
234 int pageant_enum_keys(pageant_key_enum_fn_t callback, void *callback_ctx,
235 char **retstr);
236 int pageant_delete_key(struct pageant_pubkey *key, char **retstr);
237 int pageant_delete_all_keys(char **retstr);
238 int pageant_reencrypt_key(struct pageant_pubkey *key, char **retstr);
239 int pageant_reencrypt_all_keys(char **retstr);
240 int pageant_sign(struct pageant_pubkey *key, ptrlen message, strbuf *out,
241 uint32_t flags, char **retstr);
244 * Definitions for agent protocol extensions.
246 #define PUTTYEXT(base) base "@putty.projects.tartarus.org"
248 #define KNOWN_EXTENSIONS(X) \
249 X(EXT_QUERY, "query") \
250 X(EXT_ADD_PPK, PUTTYEXT("add-ppk")) \
251 X(EXT_REENCRYPT, PUTTYEXT("reencrypt")) \
252 X(EXT_REENCRYPT_ALL, PUTTYEXT("reencrypt-all")) \
253 X(EXT_LIST_EXTENDED, PUTTYEXT("list-extended")) \
254 /* end of list */
256 #define LIST_EXTENDED_FLAG_HAS_ENCRYPTED_KEY_FILE 1
257 #define LIST_EXTENDED_FLAG_HAS_NO_CLEARTEXT_KEY 2