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
#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;
}
--- 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"
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
--
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/