www.delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2008/04/23/01:26:24

X-Recipient: archive-cygwin AT delorie DOT com
X-Spam-Check-By: sourceware.org
Message-ID: <480EC85C.1020901@cwilson.fastmail.fm>
Date: Wed, 23 Apr 2008 01:25:48 -0400
From: Charles Wilson <cygwin AT cwilson DOT fastmail DOT fm>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.12) Gecko/20080213 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: ssh-agent, keychain, and Vista [Was: Re: Vista + cygwin basics]
References: <BAY105-W40C30B0D9C302BDEF32827B5E30 AT phx DOT gbl>
In-Reply-To: <BAY105-W40C30B0D9C302BDEF32827B5E30@phx.gbl>
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com

--------------070408020103070306030509
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Karl M wrote:
>> Karl M wrote:
>>> Just a comment...keychain is pretty heavy for what you get in
>>> Cygwin.
>>> My solution was to launch ssh-agent as a service (one for each
>>> user that wants it). That service spawns the agent and updates
>>> the user environment in the registry so that other processes can
>>> find the ssh-agent process/socket. The advantages are that it is
>>> fast and the agent survives a logout (only rekey for a reboot is
>>> desired).
>> 
> It is three bash script files and one C program (just compile it with
> gcc). The shell scripts (1) install the service, (2) are the service
> under cygrunsrv and (3) is the commands to add to your bash_profile.
> If you use a different shell, they will need syntax tweaking. The C
> program provides access to sending a Windows API call to broadcast a
> message for WM_SETTINGCHANGE. This is needed because the user can log
> in before the service is started in XP. I think that this all worked
> on WIN2k when last I tried it, but it has been a long time since I
> touched a WIN2k box. I have no experience with Vista :.).

I'll give that a try.  Here's my attempt, using session ids. There's a 
simple C program to obtain the session id, a patch to apply to 
/usr/bin/keychain to use it, and the snippet that goes into ~/.bash_profile.

It seems to do what I want, but as you say, keychain does slow down the 
login process quite a bit. Other drawbacks to my approach:
   (1) the console user's ssh-agent does not survive logoff (but remote 
logons' ssh-agents do, since they all live in session 0).
   (2) non-standard, win32-specific patch to /usr/bin/keychain

--
Chuck


--------------070408020103070306030509
Content-Type: text/plain;
 name="wts_session.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="wts_session.c"

#include <stdio.h>
#include <windows.h>

typedef enum _WTS_INFO_CLASS {
  WTSInitialProgram = 0,
  WTSApplicationName = 1,
  WTSWorkingDirectory = 2,
  WTSOEMId = 3,
  WTSSessionId = 4,
  WTSUserName = 5,
  WTSWinStationName = 6,
  WTSDomainName = 7,
  WTSConnectState = 8,
  WTSClientBuildNumber = 9,
  WTSClientName = 10,
  WTSClientDirectory = 11,
  WTSClientProductId = 12,
  WTSClientHardwareId = 13,
  WTSClientAddress = 14,
  WTSClientDisplay = 15,
  WTSClientProtocolType = 16,
  WTSIdleTime = 17,
  WTSLogonTime = 18,
  WTSIncomingBytes = 19,
  WTSOutgoingBytes = 20,
  WTSIncomingFrames = 21,
  WTSOutgoingFrames = 22,
  WTSClientInfo = 23,
  WTSSessionInfo = 24
} WTS_INFO_CLASS;

BOOL WINAPI WTSQuerySessionInformation(
  HANDLE hServer,
  DWORD SessionId,
  WTS_INFO_CLASS WTSInfoClass,
  LPTSTR* ppBuffer,
  DWORD* pBytesReturned
);

void WINAPI WTSFreeMemory(PVOID pMemory);

BOOL WINAPI ProcessIdToSessionId(DWORD dwProcessId, DWORD* pSessionId);


#define WTS_CURRENT_SERVER_HANDLE 0
#define WTS_CURRENT_SESSION -1

typedef BOOL(WINAPI *PFN_WTSQuerySessionInformation)(HANDLE, DWORD, WTS_INFO_CLASS, LPTSTR*, DWORD*);
static PFN_WTSQuerySessionInformation pfnWTSQuerySessionInformation = NULL;

typedef void(WINAPI *PFN_WTSFreeMemory)(PVOID);
static PFN_WTSFreeMemory pfnWTSFreeMemory = NULL;

typedef BOOL(WINAPI *PFN_ProcessIdToSessionId)(DWORD, DWORD*);
static PFN_ProcessIdToSessionId pfnProcessIdToSessionId = NULL;

/**************************************************************************
 * getProcAddress
 **************************************************************************/
FARPROC getProcAddress(LPCTSTR lpModuleName, LPCSTR lpProcName)
{
  HMODULE hModule = NULL;
  FARPROC fpProcAddress = NULL;

  hModule = GetModuleHandle(lpModuleName);
  if (!hModule)
  {
    hModule = LoadLibrary(lpModuleName);
    if (!hModule) return NULL;
  }
  fpProcAddress = GetProcAddress(hModule, lpProcName);
  return fpProcAddress;
}

int main(int argc, char* argv)
{
  DWORD dwLength;
  ULONG sessionId;
  LPTSTR ppBuffer = NULL;

  if((pfnWTSQuerySessionInformation = (PFN_WTSQuerySessionInformation) 
      getProcAddress("wtsapi32","WTSQuerySessionInformationA")) == NULL)
  {
    /* must be on an older OS; there is no session */
    return 1;
  }
  if((pfnWTSFreeMemory = (PFN_WTSFreeMemory) 
      getProcAddress("wtsapi32","WTSFreeMemory")) == NULL)
  {
    /* must be on an older OS; there is no session */
    return 1;
  }
  if((pfnProcessIdToSessionId = (PFN_ProcessIdToSessionId) 
      getProcAddress("kernel32","ProcessIdToSessionId")) == NULL)
  {
    /* must be on an older OS; there is no session */
    return 1;
  }

  if (! (*pfnWTSQuerySessionInformation)(WTS_CURRENT_SERVER_HANDLE,
                                         WTS_CURRENT_SESSION,
                                         WTSSessionId,
                                         &ppBuffer,
                                         &dwLength))
  {
    /* terminal services might not be running. Try... */
    DWORD dwSessionId;
    if (! (*pfnProcessIdToSessionId)(GetCurrentProcessId(), &dwSessionId))
    {
      /* that failed to */
      return 2;
    }
    sessionId = (ULONG)dwSessionId;
  }
  else
  {
    sessionId = (ULONG)(*ppBuffer);
    (*pfnWTSFreeMemory)((PVOID)ppBuffer);
  }
  printf("%u\n", sessionId);
  return 0;
}

--------------070408020103070306030509
Content-Type: text/plain;
 name="keychain.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="keychain.diff"

--- keychain.orig	2008-04-23 01:01:23.858400000 -0400
+++ keychain	2008-04-23 01:04:31.760600000 -0400
@@ -1376,6 +1376,14 @@
 # simultaneously
 [ -z "$hostopt" ] && hostopt="${HOSTNAME}"
 [ -z "$hostopt" ] && hostopt=`uname -n 2>/dev/null || echo unknown`
+
+# This is Win32 specific
+if [ -f /usr/bin/wts_session.exe ]
+then
+  sessionid=`/usr/bin/wts_session.exe`
+  [ -n "${sessionid}" ] && hostopt="${hostopt}_${sessionid}"
+fi
+
 pidf="${keydir}/${hostopt}-sh"
 cshpidf="${keydir}/${hostopt}-csh"
 fishpidf="${keydir}/${hostopt}-fish"

--------------070408020103070306030509
Content-Type: text/plain;
 name="bash_profile.snip"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="bash_profile.snip"


keychain --noask --quiet
sessionid=
hostname_and_session=$HOSTNAME
[[ -f /usr/bin/wts_session.exe ]] && \
  sessionid=$(/usr/bin/wts_session.exe)
[ -n "$sessionid" ] && hostname_and_session="${hostname_and_session}_${sessionid}"

[[ -f $HOME/.keychain/${hostname_and_session}-sh ]] && \
  source $HOME/.keychain/${hostname_and_session}-sh
#[[ -f $HOME/.keychain/${hostname_and_session}-sh-gpg ]] && \
# source  $HOME/.keychain/${hostname_and_session}-sh-gpg



--------------070408020103070306030509
Content-Type: text/plain; charset=us-ascii

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/
--------------070408020103070306030509--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019