public void PageantAgentInstanceTest() { /* code based on agent_query function in winpgntc.c from PuTTY */ using (PageantAgent agent = new PageantAgent()) { /* try starting a second instance */ Assert.That(delegate() { PageantAgent agent2 = new PageantAgent(); agent2.Dispose(); }, Throws.InstanceOf<PageantRunningException>()); /* test WndProc callback */ IntPtr hwnd = FindWindow("Pageant", "Pageant"); Assert.That(hwnd, Is.Not.EqualTo(IntPtr.Zero)); int threadId = Thread.CurrentThread.ManagedThreadId; string mapName = String.Format("PageantRequest{0:x8}", threadId); using (MemoryMappedFile mappedFile = MemoryMappedFile.CreateNew(mapName, 4096)) { Assert.That(mappedFile.SafeMemoryMappedFileHandle.IsInvalid, Is.False); using (MemoryMappedViewStream stream = mappedFile.CreateViewStream()) { byte[] message = new byte[] {0, 0, 0, 1, (byte)Agent.Message.SSH2_AGENTC_REMOVE_ALL_IDENTITIES}; stream.Write(message, 0, message.Length); COPYDATASTRUCT copyData = new COPYDATASTRUCT(); if (IntPtr.Size == 4) { copyData.dwData = new IntPtr(unchecked((int)AGENT_COPYDATA_ID)); } else { copyData.dwData = new IntPtr(AGENT_COPYDATA_ID); } copyData.cbData = mapName.Length + 1; copyData.lpData = Marshal.StringToCoTaskMemAnsi(mapName); IntPtr copyDataPtr = Marshal.AllocHGlobal(Marshal.SizeOf(copyData)); Marshal.StructureToPtr(copyData, copyDataPtr, false); IntPtr resultPtr = SendMessage(hwnd, WM_COPYDATA, IntPtr.Zero, copyDataPtr); Marshal.FreeHGlobal(copyData.lpData); Marshal.FreeHGlobal(copyDataPtr); Assert.That(resultPtr, Is.Not.EqualTo(IntPtr.Zero)); byte[] reply = new byte[5]; stream.Position = 0; stream.Read(reply, 0, reply.Length); byte[] expected = {0, 0, 0, 1, (byte)Agent.Message.SSH_AGENT_SUCCESS}; Assert.That(reply, Is.EqualTo(expected)); } } } }
public void SendMessageTest() { // TODO: Need to modify this test so that it does not use PageantAgent const string messageValue = "junk"; var builder = new BlobBuilder (); builder.AddStringBlob(messageValue); var messageBytes = builder.GetBlob(); using (var agent = new PageantAgent()) { var client = new PageantClient(); var reply = client.SendMessage(messageBytes); var replyParser = new BlobParser(reply); var replyHeader = replyParser.ReadHeader(); Assert.That(replyHeader.Message, Is.EqualTo(Agent.Message.SSH_AGENT_FAILURE)); } }
public override bool Initialize(IPluginHost host) { pluginHost = host; uiHelper = new UIHelper(pluginHost); removeKeyList = new List<ISshKey>(); debug = (pluginHost .CommandLineArgs[AppDefs.CommandLineOptions.Debug] != null); LoadOptions(); if (debug) Log("Loading KeeAgent..."); var isWindows = Environment.OSVersion.Platform == PlatformID.Win32NT; var domainSocketPath = Environment.GetEnvironmentVariable (UnixClient.SshAuthSockName); try { if (Options.AgentMode != AgentMode.Client) { if (isWindows) { // In windows, try to start an agent. If Pageant is running, we will // get an exception. try { var pagent = new PageantAgent(); pagent.Locked += PageantAgent_Locked; pagent.KeyUsed += PageantAgent_KeyUsed; pagent.KeyAdded += PageantAgent_KeyAdded; pagent.KeyRemoved += PageantAgent_KeyRemoved; pagent.MessageReceived += PageantAgent_MessageReceived; // IMPORTANT: if you change either of these callbacks, you need // to make sure that they do not block the main event loop. pagent.FilterKeyListCallback = FilterKeyList; pagent.ConfirmUserPermissionCallback = Default.ConfirmCallback; agent = pagent; if (Options.UseCygwinSocket) { StartCygwinSocket(); } if (Options.UseMsysSocket) { StartMsysSocket(); } } catch (PageantRunningException) { if (Options.AgentMode != AgentMode.Auto) { throw; } } } else { // In Unix, we only try to start an agent if Agent mode was explicitly // selected or there is no agent running (indicated by environment variable). if (Options.AgentMode == AgentMode.Server || string.IsNullOrWhiteSpace (domainSocketPath)) { var unixAgent = new UnixAgent(); unixAgent.Locked += PageantAgent_Locked; unixAgent.KeyUsed += PageantAgent_KeyUsed; unixAgent.KeyAdded += PageantAgent_KeyAdded; unixAgent.KeyRemoved += PageantAgent_KeyRemoved; unixAgent.MessageReceived += PageantAgent_MessageReceived; // IMPORTANT: if you change either of these callbacks, you need // to make sure that they do not block the main event loop. unixAgent.FilterKeyListCallback = FilterKeyList; unixAgent.ConfirmUserPermissionCallback = Default.ConfirmCallback; agent = unixAgent; try { var socketPath = Options.UnixSocketPath.ExpandEnvironmentVariables(); unixAgent.StartUnixSocket (socketPath); } catch (ArgumentNullException) { var autoModeMessage = Options.AgentMode == AgentMode.Auto ? " to use KeeAgent in Agent mode or enable an external SSH agent in your " + "desktop session manager to use KeeAgent in Client mode." : "."; MessageService.ShowWarning("KeeAgent: No path specified for Agent socket file.", "Please enter a file in the KeeAgent options (Tools > Options... > KeeAgent tab)" + autoModeMessage); } catch (Exception ex) { MessageService.ShowWarning(ex.Message); } } } } if (agent == null) { if (isWindows) { agent = new PageantClient(); } else { agent = new UnixClient(); } } pluginHost.MainWindow.FileOpened += MainForm_FileOpened; pluginHost.MainWindow.FileClosingPost += MainForm_FileClosing; pluginHost.MainWindow.FileClosed += MainForm_FileClosed; // load all database that are already opened foreach (var database in pluginHost.MainWindow.DocumentManager.Documents) { MainForm_FileOpened(this, new FileOpenedEventArgs(database.Database)); } AddMenuItems(); GlobalWindowManager.WindowAdded += WindowAddedHandler; MessageService.MessageShowing += MessageService_MessageShowing; columnProvider = new KeeAgentColumnProvider(this); host.ColumnProviderPool.Add(columnProvider); SprEngine.FilterCompile += SprEngine_FilterCompile; SprEngine.FilterPlaceholderHints.Add(keyFilePathSprPlaceholder); SprEngine.FilterPlaceholderHints.Add(identFileOptSprPlaceholder); return true; } catch (PageantRunningException) { ShowPageantRunningErrorMessage(); } catch (Exception ex) { MessageService.ShowWarning("KeeAgent failed to load:", ex.Message); } Terminate(); return false; }