/// <summary> /// Default contructor. /// </summary> /// <param name="entryForm">The password entry form.</param> /// <param name="passwordEntryManager">The manager used for interacting with the open password entry.</param> public RunAsOptions(PwEntryForm entryForm, PasswordEntryManager passwordEntryManager) { InitializeComponent(); this.passwordEntryManager = passwordEntryManager; this.LoadSettings(); entryForm.EntrySaving += this.Container_EntrySaving; }
/// <summary> /// Event handler for when a password entry window is shown. Adds the "Run As" tab. /// </summary> /// <param name="sender">The object which triggered the event.</param> /// <param name="e">The event arguments.</param> private void PasswordEntryFormShown(object sender, System.EventArgs e) { PwEntryForm form = (PwEntryForm)sender; PasswordEntryManager passwordEntryManager = new PasswordEntryManager(this.host.Database, form); RunAsTab runAsTab = new RunAsTab((PwEntryForm)sender, passwordEntryManager); runAsTab.EntryIconUpdated += this.RunAsTab_EntryIconUpdated; }
/// <summary> /// Default constructor. /// </summary> /// <param name="container">The password entry form.</param> /// <param name="passwordEntryManager">The manager used for interacting with the open password entry.</param> internal RunAsTab(PwEntryForm container, PasswordEntryManager passwordEntryManager) : base(TAB_TITLE) { this.passwordEntryManager = passwordEntryManager; // Find the tab container and add this tab page to it. TabControl tabContainer = this.GetTabContainer(container); tabContainer.Controls.Add(this); // Add the run as options to this tab page. RunAsOptions optionsControl = new RunAsOptions(container, this.passwordEntryManager); optionsControl.EntryIconUpdated += this.OptionsControl_EntryIconUpdated; optionsControl.Dock = DockStyle.Fill; this.Controls.Add(optionsControl); }
/// <summary> /// Event handler triggered when the context menu containing this menu item is opened. /// </summary> /// <param name="sender">The object which triggered the event.</param> /// <param name="e">The event arguments.</param> private void EntryContextMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e) { PwEntry[] selectedEntries = this.mainWindow.GetSelectedEntries(); if (selectedEntries == null || selectedEntries.Length == 0) { this.Enabled = false; } else if (selectedEntries.Length == 1) { PasswordEntryManager entryManager = new PasswordEntryManager(this.mainWindow.ActiveDatabase, selectedEntries[0]); this.Enabled = entryManager.GetRunAsSettings().IsEnabled; } else { this.Enabled = true; } }
/// <summary> /// Event handler triggered when the menu item is clicked. /// </summary> /// <param name="sender">The object which triggered the event.</param> /// <param name="e">The event arguments.</param> private void RunAsMenuItem_Click(object sender, System.EventArgs e) { // Obtain a list of all selected entries to execute and loop through them. PwEntry[] selectedEntries = this.mainWindow.GetSelectedEntries(); // If there are no entries (the array is null), just return as we // probably entered this through the keyboard shotcut event. if (selectedEntries == null) { return; } // TODO: Add confirmation when executing more than one application. foreach (PwEntry entry in selectedEntries) { PasswordEntryManager entryManager = new PasswordEntryManager(this.mainWindow.ActiveDatabase, entry); try { // Create and run an executor for the password entry. ApplicationExecutor executor = new ApplicationExecutor(entryManager); executor.Run(); } catch (ApplicationExecutionException ex) { // If there was an error, display a suitable error message. string errorMessage = string.Concat( "Unable to execute application for password entry '", entryManager.GetTitle(), "':", Environment.NewLine, Environment.NewLine, ex.Message); MessageBox.Show( this.mainWindow, errorMessage, "Run As Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
public void ExecuteApplication(PasswordEntryManager entryManager) { ExecutionSettings settings = entryManager.GetExecutionSettings(); // Determine the values to use on native calls based on the impersonation settings. string domain = settings.Domain; string username = settings.Username; Win32.LogonFlags logonFlags = settings.NetOnly ? Win32.LogonFlags.LOGON_NETCREDENTIALS_ONLY : Win32.LogonFlags.LOGON_WITH_PROFILE; string application = settings.Application; string arguments = settings.Arguments; string workingDir = string.IsNullOrWhiteSpace(settings.WorkingDir) ? null : settings.WorkingDir; // Create variables required for impersonation handling. IntPtr token = IntPtr.Zero; Win32.StartupInfo startupInfo = new Win32.StartupInfo(); Win32.ProcessInformation processInfo = new Win32.ProcessInformation(); try { // Create process startupInfo.cb = Marshal.SizeOf(startupInfo); bool result = Win32.CreateProcessWithLogonW( username, domain, entryManager.ProcessReplacementTags(settings.Password), (uint)logonFlags, application, arguments, 0, IntPtr.Zero, workingDir, ref startupInfo, out processInfo); if (!result) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } catch (Win32Exception ex) { string errorMessage = ex.Message; if ("A logon request contained an invalid logon type value".Equals(errorMessage)) { errorMessage = string.Concat(errorMessage, ". This is usually caused by attempting to use credentials for the network only but not specifying a domain."); } throw new ApplicationExecutionException(errorMessage, ex); } finally { if (processInfo.process != IntPtr.Zero) { Win32.CloseHandle(processInfo.process); } if (processInfo.thread != IntPtr.Zero) { Win32.CloseHandle(processInfo.thread); } } }
internal ApplicationExecutor(PasswordEntryManager entryManager) { this.entryManager = entryManager; this.settings = this.entryManager.GetRunAsSettings(); }