Automating the Choose a digital certificate dialog - c#

I am using WatiN (2.0.10.928) with C# and Visual Studio 2008 to test a SSL secured website that requires a certificate. When you navigate to the homepage a "Choose a digital certificate" dialog is displayed and requires that you select a valid certificate and click the 'OK' button.
I'm looking for a way to automate the certificate selection so that every time a new test or fixture is executed (and my browser restarts) I don't have to manually interfere with the automated test and select the certificate. I've tried using various WatiN Dialog Handler classes and even looked into using the Win32 API to automate this but haven't had much luck.
I finally found a solution but its adds another dependency to the solution (a third party library called AutoIT). Since this solution isn't ideal but does work and is the best I could find, I will post the solution and mark it as the answer but I am still looking for an 'out of the box' WatiN solution that is more consistent with the rest of my code and test fixtures.
Thanks for your responses!

In my situation I have exactly one certificate attached, so I have to pick up the one and only existing on the list, so I have really simple DialogHandler for this - it only clicks on the button if it cans handle the dialog:
public class CertificateChoosingHandler : BaseDialogHandler
{
public override bool HandleDialog(Window window)
{
new WinButton(1, window.Hwnd).Click();
return true;
}
public override bool CanHandleDialog(Window window)
{
return window.StyleInHex == "94C808CC";
}
}
AFAIR this solution won't work in Windows 7.
EDIT: I forgot about something useful. When I found that this solution is not working in Windows 7, I discovered very interesting option in IE Internet Options somewhere in "Custom Level": Don’t prompt for client certificate selection when no certificates or only one certificate exists. So I have added my site to trusted sites and edited settings, and there is no need now for me to use this DialogHandler, but it still can be used even if no dialog appears. If it is not clear, what I wrote, here is how to Enable Prompt for Certificate in Internet Explorer to show certificate dialog.

The best solution I could find so far was posted here:
http://andrey-zhukov.blogspot.com/2009/10/recently-i-wanted-to-choose-digital.html
As stated in the post, it requires a reference to the AutoIT library: http://www.autoitscript.com/autoit3/index.shtml

I've taken #prostynick's hint and automated it. Basically, if you ENABLE the setting "Don’t prompt for client certificate selection when no certificates or only one certificate exists" in the IE security settings, then the whole dialog doesn't appear (if you only have one or no certificate, that is).
So, we just have to make sure that the user has that setting enabled before we initialize your WebBrowser object. And since these settings are conveniently stored in the registry, we can do it ourselves, without bothering the user. Here's some code that does just that:
// What this does is changes this setting in Internet Explorer:
// Tools -> Internet Options -> Security -> Custom Level ->
// Don't prompt for client certificate selection when no certificates
// or only one certificate exists -> ENABLE
//
// If you're not convinced that we need this, please reset all the security
// levels in IE to the default settings, comment out this code, and try to fetch
// <your url>.
//
// If it finishes, great! Then leave it commented out. Otherwise, curse and accept
// that we need this ugly hack OR that we need to instruct people to find & change
// some unholy IE setting...
RegistryKey stupidBrokenDefaultSetting = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3", true);
stupidBrokenDefaultSetting.SetValue("1A04", "0", RegistryValueKind.DWord);
I'm not sure if this works for everyone, or that you need Administrator rights or something, but it works for me.

Related

How to automatically accept Chrome's "Always open these types of links in the associated app" dialogs in Selenium

I'm automating tests using Selenium and C# and I need to open an external app from the browser. The problem is, I always get this notification and it blocks the test execution.
Does anyone know how to deal with this?
Chrome stores the settings for the acceptance of protocol handlers in the user profile. When running Chrome from Selenium, Chrome doesn't seem to use the standard Chrome user profile by default, and instead uses some default settings that are not persisted.
To get around this, you can launch Chrome from the command line manually and manually specify a new --user-data-dir=c:\foo\bar profile location. (Point it to a new/empty directory and Chrome will populate it for you.)
Using this manually-launched browser, navigate to the page you need to interact with, activate the link, click the "always open" checkbox, and run the program once.
Next, close Chrome and save a copy of the entire new user profile directory. When you run your Selenium tests, make sure to always pass Chrome the same command line options pointing it to that user profile. These settings are now persisted, so the link will open without user intervention in the future. (This question may be of help to feed the right command line args to Chrome.)
For repeatable tests, you will probably want to save a static copy of this profile and redeploy it whenever you launch Selenium.
If you are using Javascript+Selenium or WebdriverJS then use this :
chromeOptions = {
'args': ['--test-type',
'--start-maximized',
'use-fake-ui-for-media-stream',],
'prefs': {
protocol_handler: {
excluded_schemes: {
'yourprotocolname': false
}
}
},
};

Custom Actions Installer for Windows Service

I have a windows service which I silent install using msiexec.exe and I am passing the username and password for the "Set Service Login"
The Service is successfully installing but upon Starting the service I am receiving "error 1069: The service did not start due to logon problems"my logon account is administrator and I have tested that when I manually install using the same msi file and start the service it is starting successfully, I am stuck and need some ideas and guidance of what I am missing.
here is my overriden method from Installer Class.
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
var userName = Context.Parameters["USERNAME"];
var password = Context.Parameters["PASSWORD"];
if (!string.IsNullOrWhiteSpace(userName) && userName.ToLower() != "admin")
{
CustomInstallerParameters customParameters = new CustomInstallerParameters(Context);
SaveCustomParametersInStateSaverDictionary(stateSaver, customParameters);
}
else
{
Context.Parameters.Remove("USERNAME");
Context.Parameters.Remove("PASSWORD");
}
}
TIA.
It appears that you are using a Visual Studio setup project, and most likely also using one of the TextBoxes dialogs to collect the input.
You can't silently pass these parameters on the command line because Visual Studio generates custom actions to clear them (and I don't know why). In a silent install Windows runs just the InstallExecuteSequence, and if you look in there with (for example) Orca you'll see custom actions such as "CustomTextA_SetProperty_EDIT1" that clear the values. To state the obvious, the values you currently get will be blank, and you could verify this by logging the values somewhere.
So a starting point to getting this to work is to use Orca to delete those custom action calls in the InstallExecuteSequence table.
After that, there is a potential problem that the values won't make it to your custom action because they are not secured, so in the Property table you'd need to add those property names to the SecureCustomProperties list, semi-colon delimited (EDIT1;EDIT2 and so on).
Visual Studio setup projects aren't good at any of this, and something like WiX would be better because no code is required to install, start or stop services, or configure them with an account.
Most likely, different decade, same problem.... (SeServiceLogonRight)
http://iswix.com/2008/09/22/different-year-same-problem/
FWIW, I wasn't a big WiX user yet back then (I was merely dabbling at that point) but there are some real gems in the comments from my Matthew Rowan. He is correct... all of this gets WAY easier if you are using WiX.
For example you can follow this tutorial:
https://github.com/iswix-llc/iswix-tutorials
This creates a windows service running as SYSTEM. Add a reference to the WiXUtil extension and namespace and author a User element with the LogonAsService right set and your all set.
FWIW, my only concern with all this is that MSI needs property persistence if you don't want a repair to come by and corrupt the username and password. Property persistence is pretty easy to remember ( See: http://robmensching.com/blog/posts/2010/5/2/the-wix-toolsets-remember-property-pattern/ ) but the problem is providing enough encryption to not expose the account.
It's for the reason I typically suggest just running as NetworkService or SYSTEM and grant the computer object rights in a domain. An alternative is to have the installer create the service account and randomize the password on each repair so you don't have to persist it.

Disabling certificate revocation checking for an application on Windows

I have a .NET 3.5 desktop application that had been showing periodic slow downs in functionality whenever the test machine it was on was out of the office.
I managed to replicate the error on a machine in the office without an internet connection, but it was only when i used ANTS performance profiler that i got a clearer picture of what was going on.
In ANTS I saw a "Waiting for synchronization" taking up to 16 seconds that corresponded to the delay I could see in the application when NHibernate tried to load the System.Data.SqlServerCE.dll assembly.
If I tried the action again immediately it would work with no delay but if I left it for 5 minutes then it would be slow to load again the next time I tried it.
From my research so far it appears to be because the SqlServerCE dll is signed and so the system is trying to connect to get the certificate revocation lists and timing out.
Disabling the "Automatically detect settings" setting in the Internet Options LAN settings makes the problem go away, as does disabling the "Check for publishers certificate revocation".
But the admins where this application will be deployed are not going to be happy with the idea of disabling certificate checking on a per machine or per user basis so I really need to get the application level disabling of the CRL check working.
There is the well documented bug in .net 2.0 which describes this behaviour, and offers a possible fix with a config file element.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<generatePublisherEvidence enabled="false"/>
</runtime>
</configuration>
This is NOT working for me however even though I am using .net 3.5.
The SQLServerCE dll is being loaded dynamically by NHibernate and I wonder if the fact that it's dynamic could somehow be why the setting isn't working, but I don't know how I could check that.
Can anyone offer suggestions as to why the config setting might not work?
Or is there another way I could disable the check at the application level, perhaps a CAS policy setting that I can use to set an exception for the application when it's installed?
Or is there something I can change in the application to up the trust level or something like that?
You can specify in code if you want to check the revocation list per application:
ServicePointManager.CheckCertificateRevocationList = false;
In this blog posting (which cites another source) you have two options: disable CRL checking system wide or per app:
Disable CRL Checking Machine-Wide Control Panel -> Internet Options ->
Advanced -> Under security, uncheck the Check for publisher's
certificate revocation option
Disable CRL Checking For a Specific .Net Application See this
Microsoft KB Article: http://support.microsoft.com/kb/936707
What solved the problem for me:
I (think I) had a problem with online revocation before, so I explicitly switched to offline. Due to to warning, I now had to change...
_ = builder.Services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(
options =>
{
options.AllowedCertificateTypes = CertificateTypes.All;
options.RevocationMode = X509RevocationMode.Offline;
}
);
... to ...
_ = builder.Services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(
options =>
{
options.AllowedCertificateTypes = CertificateTypes.All;
options.RevocationMode = X509RevocationMode.NoCheck;
}
);

How to automatically bypass logon message on RDP?

I'm trying to log in to a server through remote desktop using c#. I'm able to initiate the connection using the AxMSTSCLib and the code below. However, I'm stuck on our domain's security notice.
When logging in manually it requires you to click ok on the notice before the log in completes. I have been unable to find anyway to interact with this OK button through my application. I've tried variations of SendKeys, sending key events using interop services, finding the cursor position and sending a mouse click event...
I'm running out of ideas here.
rdp.Server = server;
rdp.Domain = domain;
rdp.UserName = userName;
IMsTscNonScriptable secured = (IMsTscNonScriptable)rdp.GetOcx();
secured.ClearTextPassword = password;
rdp.StartConnected = 1;
rdp.Connect();
Thanks
Well, there is a way to do what you ask.
You will need to download a copy of Windows 7 Embedded Standard (WES7 wSP1).
WES7 contains something that other editions of Windows 7 do not - a Dialog Filter.
It runs as a service, and allows you to specify certain window events to be performed automatically, without user interaction.
The Dialog Filter Editor is installed with the Windows Embedded Standard 7 tools in the EmbeddedSDK\bin folder.
All you have to do is:
Add the service to your Windows, by copying the necessary Dialog Filter files to C:\Windows\System32. There are x86 and x64 versions, so choose the correct architecture.
Register the files, and enable the service to run automatically.
Add the ConfigurationList.xml file created with the editor to C:\ProgramData\Microsoft\DialogFilter.
This location is hidden by defeault, so make sure to show hidden files and unhide protected system files in Windows Explorer.
I've actually created the ConfigurationList.xml file already, so you can simply copy the following code and save it as "ConfigurationList.xml":
<?xml version="1.0" encoding="utf-8"?>
<CL:dialogs xmlns:CL="urn:Dialogs">
<dialog>
<ProcessImageName>rundll32.exe</ProcessImageName>
<Title>Remote Desktop Connection</Title>
<Class>#32770</Class>
<Buttons>
<Button>OK</Button>
<Button>Cancel</Button>
<Button>Close</Button>
</Buttons>
<Actions>
<Action>OK</Action>
</Actions>
</dialog>
</CL:dialogs>
As you can see, the action is set to press the OK button automatically in the RDP dialog that pops up when making an RDP connection.
More info regarding the Dialog Filter directly from MS:
https://msdn.microsoft.com/en-US/library/ff794135(v=winembedded.60).aspx
Just found a much easier way to do this:
There's a free small app called ClickOff, which works in a very similar manner to Windows Embedded Standard 7 DialogFilter.
You can download ClickOff v1.90 here.
After you install ClickOff, you can define which window to capture, and which button inside it to click. Only thing is that you must add it to your startup apps.
I have already created a clickoff.lst file which clicks OK on the 30-sec RDP timeout popup window. The file should be placed in C:\Users\USERNAME\AppData\Roaming\ClickOff. Here's the contents of the file:
1.900
WINDOWTITLE="Remote Desktop Connection" BUTTONTEXT="OK" MSGTEXT="CompName\\UserName wants to connect to this machine.\r\n\r\nClick OK to disconnect your session immediately or click cancel to stay connected.\r\n\r\nOtherwise, you will be disconnected in 30 seconds." BUTTONID="1" MSGID="65535" DLGID="0" CLKEVENT="17" CLKMETHOD="3" TIMESCLICKED="0" WAIT="0" BPOSX="0" BPOSY="0" ;
Cheers.

.NET Publisher Certificates

I'm using a book for studying for .NET certification, and I'm stumped on the issue of publisher certificates.
Background:
Windows Vista Home Basic SP2
Visual Studio 2008
.NET 3.5 SP1
Goal:
Write a simple C# console application that has its permission to read from a specific text file determined by the application's certificate.
Symptoms:
I am able to read from the file despite assigning the Nothing permission set to the code group that is conditioned by the application's certificate.
Steps taken:
Wrote C# console application that uses StreamReader to read the file and output to the console. The application works as expected.
On the application's properties, I used the Signing tab, set ON the checkbox for "Sign the ClickOnce manifest", clicked the Create Test Certificate button, and entered passwords.
Next, I clicked the More Details button, navigated to the Details tab, selected the Public Key row, and clicked the Copy to File button.
In the Certificate Export Wizard, I chose not to export the private key, chose the DER encoded binary X.509 format, and provided the path of the .CER file.
Next I rebuilt the application.
I opened the .NET Framework 2.0 Configuration tool.
I navigated to My Computer > Runtime Security > Machine > Code Groups > All_Code
Right clicked All_Code, and selected New to begin the Create Code Group wizard.
Gave the new code group a name, then selected the Publisher condition type.
Clicked the Import from Certificate File button, then selected the newly created .CER file.
Next I selected the Nothing permission set.
When running the application, which should now be a member of the new code group, it still works the same. I would expect that if it's a member of the Nothing permission set that it couldn't read the file.
Thanks for any insight you can provide. I'm probably missing one little detail. I wonder if this has anything to do with using Vista Home Basic.
Can your application read the file in question w/o any certificate?
Adding Nothing to a set of existing permissions won't change much.

Categories

Resources