Implemetation: Pageant - Apache553/ssh-agent-bridge GitHub Wiki

Putty/Pageant uses Windows Messages and Named Shared Memory to communicate.

Procedure

Server

  1. The server creates a window with its both title and class equal to Pageant.
  2. In message loop, once received a WM_COPYDATA message, converts lparam to a pointer to COPYDATASTRUCT. Check whether the dwData member of the struct equals to 0x804e50ba. If true, go to next step, else return 0 to indicate a failure.
  3. Convert the lpData member to char*, which is the name of a file mapping. The cbData member is the length of the string, including null-terminator.
  4. Open the file mapping with the name, call GetSecurityInfo with file mapping handle to get its owner. If the handle owner is not the server process's owner, go failure routine.
  5. Map a view of the file mapping, there is a standard ssh agent protocol packet. After handling the request, write the reply packet back, then return 1 to indicate a successful request.

Client

  1. Call FindWindow with title Pageant and class Pageant to find the window handle of the server.
  2. Format PageantRequest%08x with current thread id. Use the result string as the name of a new file mapping.
  3. Set file mapping security descriptor owner to the owner of process.
  4. Write packet data into the file mapping. Send a WM_COPYDATA message to server window with SendMessage. The dwData member of COPYDATASTRUCT should be the magic number 0x804e50ba. The lpData member should be a pointer that points to the file mapping's name. The cbData member should be the length of the name, including null-termintor.
  5. Check the return value of the call, zero indicates a failure. Read the reply packet from the file mapping in case of a non-zero return value.

Notes

  • According to the implementation of original Putty, a single request cannot be longer than 8192 bytes.
  • Because of the existance of UIPI, a non-elevated client can't access an elevated server, unless the server has done some work to allow such access. The original putty rejects such access.
  • In some implementations of Pageant protocol, the server window might be a message-only window, which become a pit while enumerating all server windows. Observed in GnuPG's implementation till now.