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 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: In-Reply-To: Content-Type: multipart/mixed; boundary="------------070408020103070306030509" Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , 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 #include 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--