pageant.h 9.8 KB

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