Skip to content
Snippets Groups Projects
  1. Apr 04, 2021
  2. Apr 02, 2021
    • Simon Tatham's avatar
      Make unused Pageant accessor functions private. · 30c87c28
      Simon Tatham authored
      We're no longer calling pageant_nth_ssh*_key or pageant_add_ssh*_key
      from outside pageant.c. Remove them from pageant.h and turn them
      static, so that we carry on not doing so.
      30c87c28
    • Simon Tatham's avatar
      winpgnt: fix GUI removal of encrypted keys. · fbab1667
      Simon Tatham authored
      The GUI loop that responded to the 'Remove Key' button in the key list
      worked by actually trying to retrieve a pointer to the ssh_key for a
      stored key, and then passing that back to the delete function. But
      when a key is encrypted, that pointer is NULL, so we segfaulted.
      
      Fixed by changing pageant_delete_ssh2_key() to take a numeric index in
      the list instead of a key pointer.
      fbab1667
    • Simon Tatham's avatar
      Polish up passphrase prompts for key decryption. · efc31ee3
      Simon Tatham authored
      Now Windows Pageant has two clearly distinct dialog boxes for
      requesting a key passphrase: one to use synchronously when the user
      has just used the 'Add Key' GUI action, and one to use asynchronously
      in response to an agent client's attempt to use a key that was loaded
      encrypted.
      
      Also fixed the wording in the asynchronous box: there were two copies
      of the 'enter passphrase' instruction, one from the dialog definition
      in pageant.rc file and one from the cross-platform pageant.c. Now
      pageant.c doesn't format a whole user-facing message any more: it
      leaves that to the platform front end to do it the way it wants.
      
      I've also added a call to SetForegroundWindow, to try to get the
      passphrase prompt into the foreground. In my experience this doesn't
      actually get it the keyboard focus, which I think is deliberate on
      Windows's part and there's nothing I can do about it. But at least the
      user should _see_ that the prompt is there, so they can focus it
      themself.
      efc31ee3
  3. Mar 13, 2021
    • Simon Tatham's avatar
      Unix Pageant: support multiple fingerprint types. · 7cadad4c
      Simon Tatham authored
      The callback-function API in pageant.h for key enumeration is modified
      so that we pass an array of all the available fingerprints for each
      key.
      
      In Unix Pageant, that's used by the -l option to print whichever
      fingerprint the user asked for. (Unfortunately, the option name -E is
      already taken, so for the moment I've called it --fptype. I may
      revisit that later.)
      
      Also, when matching a key by fingerprint, we're prepared to match
      against any fingerprint type we know, with disambiguating prefixes if
      necessary (e.g. you can match "md5:ab:12" or "sha256:Ab12". That has
      to be done a bit carefully, because we match MD5 hex fingerprints
      case-insensitively, but SHA256 fingerprints are case-sensitive.
      7cadad4c
  4. Dec 15, 2020
    • Simon Tatham's avatar
      pageant -l: indicate whether keys are encrypted. · 353db313
      Simon Tatham authored
      The callback function to pageant_enum_keys now takes a flags
      parameter, which receives the flags word from the extended key list
      request, if available. (If not, then the flags word is passed as
      zero.)
      
      The only callback that uses this parameter is the one for printing
      text output from 'pageant -l', which uses it to print a suffix on each
      line, indicating whether the key is stored encrypted only (so it will
      need a passphrase on next use), or whether it's stored both encrypted
      _and_ unencrypted (so that 'pageant -R' will be able to return it to
      the former state).
      353db313
    • Simon Tatham's avatar
      Pageant: new PuTTY-specific ext request, 'list-extended'. · 39ec2837
      Simon Tatham authored
      This is an extended version of SSH2_AGENTC_REQUEST_IDENTITIES, which
      augments each entry in the returned key list with an extra field
      containing additional data about the key.
      
      The initial contents of that extra field are a pair of flags
      indicating whether the key is currently stored in the agent encrypted,
      decrypted or both.
      
      The idea is that this will permit a Pageant-aware client to make
      decisions based on that. For a start, the output key list can mention
      it to the user; also, if you try to add a key unencrypted when it's
      already present, we can discriminate based on whether it's already
      present _unencrypted_
      39ec2837
    • Simon Tatham's avatar
      Pageant: move extension list out into header file. · 3687df73
      Simon Tatham authored
      That's a part of the protocol spec (ish), so it should be somewhere
      reasonably sensible rather than buried in the middle of a source file.
      3687df73
  5. Feb 15, 2020
    • Simon Tatham's avatar
      Pageant client: functions to send reencryption requests. · e563627d
      Simon Tatham authored
      The reencrypt-all request is unusual in its ability to be _partially_
      successful. To handle this I've introduced a new return status,
      PAGEANT_ACTION_WARNING. At the moment, users of this client code don't
      expect it to appear on any request, and I'll make them watch for it
      only in the case where I know a particular function can generate it.
      e563627d
    • Simon Tatham's avatar
      Rework the Pageant client code to use BinarySource. · 2e479fab
      Simon Tatham authored
      There was a lot of ugly, repetitive, error-prone code that decoded
      agent responses in raw data buffers. Now my internal client query
      function is returning something that works as a BinarySource, so we
      can decode agent responses using the marshal.h system like any other
      SSH-formatted message in this code base.
      
      While I'm at it, I've centralised more of the parsing of key lists
      (saving repetition in pageant_add_key and pageant_enum_keys),
      including merging most of the logic between SSH-1 and SSH-2. The old
      functions pageant_get_keylist1 and pageant_get_keylist2 aren't exposed
      in pageant.h any more, because they no longer exist in that form, and
      also because nothing was using them anyway. (Windows Pageant was using
      the separate pageant_nth_ssh2_key() functions that talk directly to
      the core, and Unix Pageant was using the more cooked client function
      pageant_enum_keys.)
      2e479fab
  6. Feb 09, 2020
    • Simon Tatham's avatar
      Unix Pageant: --test-sign client option. · 518c0f0e
      Simon Tatham authored
      This reads data from standard input, turns it into an SSH-2 sign
      request, and writes the resulting signature blob to standard output.
      
      I don't really anticipate many uses for this other than testing. But
      it _is_ convenient for testing changes to Pageant itself: it lets me
      ask for a signature without first having to construct a pointless SSH
      session that will accept the relevant key.
      518c0f0e
  7. Feb 08, 2020
    • Simon Tatham's avatar
      Unix Pageant: -E option to load key files encrypted. · 55005a08
      Simon Tatham authored
      This applies to both server modes ('pageant -E key.ppk [lifetime]')
      and client mode ('pageant -a -E key.ppk').
      
      I'm not completely confident that the CLI syntax is actually right
      yet, but for the moment, it's enough that it _exists_. Now I don't
      have to test the encrypted-key loading via manually mocked-up agent
      requests.
      55005a08
  8. Feb 02, 2020
    • Simon Tatham's avatar
      Pageant: introduce an API for passphrase prompts. · 08d5c233
      Simon Tatham authored
      This begins to head towards the goal of storing a key file encrypted
      in Pageant, and decrypting it on demand via a GUI prompt the first
      time a client requests a signature from it. That won't be a facility
      available in all situations, so we have to be able to return failure
      from the prompt.
      
      More precisely, there are two versions of this API, one in
      PageantClient and one in PageantListenerClient: the stream
      implementation of PageantClient implements the former API and hands it
      off to the latter. Windows Pageant has to directly implement both (but
      they will end up funnelling to the same function within winpgnt.c).
      
      NFC: for the moment, the new API functions are never called, and every
      implementation of them returns failure.
      08d5c233
  9. Jan 26, 2020
    • Simon Tatham's avatar
      Greatly improve printf format-string checking. · cbfba7a0
      Simon Tatham authored
      I've added the gcc-style attribute("printf") to a lot of printf-shaped
      functions in this code base that didn't have it. To make that easier,
      I moved the wrapping macro into defs.h, and also enabled it if we
      detect the __clang__ macro as well as __GNU__ (hence, it will be used
      when building for Windows using clang-cl).
      
      The result is that a great many format strings in the code are now
      checked by the compiler, where they were previously not. This causes
      build failures, which I'll fix in the next commit.
      cbfba7a0
  10. Jan 25, 2020
    • Simon Tatham's avatar
      Pageant: new asynchronous internal APIs. · de38a4d8
      Simon Tatham authored
      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.
      de38a4d8
  11. Jan 04, 2019
    • Simon Tatham's avatar
      Remove a lot of pointless 'struct' keywords. · 35690040
      Simon Tatham authored
      This is the commit that f3295e0f _should_ have been. Yesterday I just
      added some typedefs so that I didn't have to wear out my fingers
      typing 'struct' in new code, but what I ought to have done is to move
      all the typedefs into defs.h with the rest, and then go through
      cleaning up the legacy 'struct's all through the existing code.
      
      But I was mostly trying to concentrate on getting the test suite
      finished, so I just did the minimum. Now it's time to come back and do
      it better.
      35690040
  12. Nov 03, 2018
    • Simon Tatham's avatar
      Convert a lot of 'int' variables to 'bool'. · 3214563d
      Simon Tatham authored
      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'!
      3214563d
  13. Oct 04, 2018
    • Simon Tatham's avatar
      Get rid of lots of implicit pointer types. · 96ec2c25
      Simon Tatham authored
      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.
      96ec2c25
  14. Jul 09, 2018
    • Simon Tatham's avatar
      Raise AGENT_MAX_MSGLEN to 256Kb. · 98528db2
      Simon Tatham authored
      That's the same value as in the OpenSSH source code, so it should be
      large enough that anyone needing to sign a larger message will have
      other problems too.
      98528db2
  15. May 27, 2018
    • Simon Tatham's avatar
      Modernise the Socket/Plug vtable system. · 5129c40b
      Simon Tatham authored
      Now I've got FROMFIELD, I can rework it so that structures providing
      an implementation of the Socket or Plug trait no longer have to have
      the vtable pointer as the very first thing in the structure. In
      particular, this means that the ProxySocket structure can now directly
      implement _both_ the Socket and Plug traits, which is always
      _logically_ how it's worked, but previously it had to be implemented
      via two separate structs linked to each other.
      5129c40b
  16. May 25, 2018
    • Simon Tatham's avatar
      Build SSH agent reply messages in a BinarySink. · b6cbad89
      Simon Tatham authored
      This gets rid of yet another huge pile of beating around the bush with
      length-counting. Also, this time, the BinarySink in question is a
      little more interesting than just being a strbuf every time: on
      Windows, where the shared-memory Pageant IPC system imposes a hard
      limit on the size of message we can return, I've written a custom
      BinarySink implementation that collects up to that much data and then
      gives up and sets an overflow flag rather than continue to allocate
      memory.
      
      So the main Pageant code no longer has to worry about checking
      AGENT_MAX_MSGLEN all the time - and better still, the Unix version of
      Pageant is no longer _limited_ by AGENT_MAX_MSGLEN in its outgoing
      messages, i.e. it could store a really extra large number of keys if
      it needed to. That limitation is now a local feature of Windows
      Pageant rather than intrinsic to the whole code base.
      
      (AGENT_MAX_MSGLEN is still used to check incoming agent messages for
      sanity, however. Mostly that's because I feel I ought to check them
      against _some_ limit, and this one seems sensible enough. Incoming
      agent messages are more bounded anyway - they generally don't hold
      more than _one_ private key.)
      b6cbad89
    • Simon Tatham's avatar
      Change ssh.h crypto APIs to output to BinarySink. · 67de463c
      Simon Tatham authored
      This affects all the functions that generate public and private key
      and signature blobs of all kinds, plus ssh_ecdhkex_getpublic. Instead
      of returning a bare block of memory and taking an extra 'int *length'
      parameter, all these functions now write to a BinarySink, and it's the
      caller's job to have prepared an appropriate one where they want the
      output to go (usually a strbuf).
      
      The main value of this change is that those blob-generation functions
      were chock full of ad-hoc length-counting and data marshalling. You
      have only to look at rsa2_{public,private}_blob, for example, to see
      the kind of thing I was keen to get rid of!
      67de463c
  17. May 12, 2015
  18. May 11, 2015
    • Simon Tatham's avatar
      Unix Pageant: first draft of -l key list option. · 511d967d
      Simon Tatham authored
      It doesn't look very pretty at the moment, but it lists the keys and
      gets the fingerprints right.
      511d967d
    • Simon Tatham's avatar
      Pageant: factor out cross-platform parts of add_keyfile(). · 2069de8c
      Simon Tatham authored
      I've now centralised into pageant.c all the logic about trying to load
      keys of any type, with no passphrase or with the passphrases used in
      previous key-loading actions or with a new user-supplied passphrase,
      whether we're the main Pageant process ourself or are talking to
      another one as a client. The only part of that code remaining in
      winpgnt.c is the user interaction via dialog boxes, which of course is
      the part that will need to be done differently on other platforms.
      2069de8c
  19. May 07, 2015
    • Simon Tatham's avatar
      Clean up Unix Pageant's setup and teardown. · 47c9a6ef
      Simon Tatham authored
      I've moved the listening socket setup back to before the lifetime
      preparations, so in particular we find out that we couldn't bind to
      the socket _before_ we fork. The only part that really needed to come
      after lifetime setup was the logging setup, so that's now a separate
      function called later.
      
      Also, the random exit(0)s in silly places like x11_closing have turned
      into setting a time_to_die flag, so that all clean exits funnel back
      to the end of main() which at least tries to tidy up a bit afterwards.
      
      (Finally, fixed a small bug in testing the return value of waitpid(),
      which only showed up once we didn't exit(0) after the first wait.
      Ahem.)
      47c9a6ef
  20. May 06, 2015
    • Simon Tatham's avatar
      Put proper logging into Pageant. · bc4066e4
      Simon Tatham authored
      Now it actually logs all its requests and responses, the fingerprints
      of keys mentioned in all messages, and so on.
      
      I've also added the -v option, which causes Pageant in any mode to
      direct that logging information to standard error. In --debug mode,
      however, the logging output goes to standard output instead (because
      when debugging, that information changes from a side effect to the
      thing you actually wanted in the first place :-).
      
      An internal tweak: the logging functions now take a va_list rather
      than an actual variadic argument list, so that I can pass it through
      several functions.
      bc4066e4
  21. May 05, 2015
    • Simon Tatham's avatar
      Cross-platform support for speaking SSH agent protocol on a Socket. · 7b607853
      Simon Tatham authored
      The exact nature of the Socket is left up to the front end to decide,
      so that we can use a Unix-domain socket on Unix and a Windows named
      pipe on Windows. But the logic of how we receive data and what we send
      in response is all cross-platform.
      7b607853
    • Simon Tatham's avatar
      Move half of Pageant out into a cross-platform source file. · 5ba2d611
      Simon Tatham authored
      I'm aiming for windows/winpgnt.c to only contain the parts of Windows
      Pageant that are actually to do with handling the Windows API, and for
      all the actual agent logic to be cross-platform.
      
      This commit is a start: I've moved every function and internal
      variable that was easy to move. But it doesn't get all the way there -
      there's still a lot of logic in add_keyfile() and get_keylist*() that
      would be good to move out to cross-platform code, but it's harder
      because that code is currently quite intertwined with details of
      Windows OS interfacing such as printing message boxes and passphrase
      prompts and calling back out to agent_query if the Pageant doing that
      job isn't the primary one.
      5ba2d611
Loading