I'm developing an installer for an application which includes a Windows Service. The service will need a username/password from the user in order to get information from our server, so I'd like to set that during install. We also need to store that info in the Services config file so it has to be encrypted.
So I'd like the installer to call the same .dll the service uses when it encrypts the credentials. I set up custom actions created through the custom action wizard. I set it to "Call a public method in a managed assembly" and picked "Installed with the product" as the Location. I'm able to pick the dll and the target function and set everything up through the wizard. The path it resolves to in the installer log looks correct...
But I'm getting the error:
Unable to load managed custom action assembly
So not sure what to do in order to get this working?
The second part of the question is, what happens if the end user doesn't have .NET 4 installed? I'm going to set the installer to install it... but will there be problems or will we need to force a reboot partway through the install process? If so I might just temporarily store things unencrypted and have the service encrypt them when it first runs... which at this point is probably the easy way, but it doesn't feel like the "correct" way. ;)
Related
I've developing an asp.net core application to tun on a web far, and I'm using "AddDataProtection" to protect for key encryption at rest like, the documentation recommends, but when I deploy my application and run directly from IIS with AppPool identity, the key is never created and I get errors on the DpapiNG windows logs.
My code is the following:
services.AddDataProtection(opt => opt.ApplicationDiscriminator = ApplicationConfig.dataProtectionApplicationDiscriminator)
.PersistKeysToFileSystem(new DirectoryInfo(encKeyPath))
.ProtectKeysWithDpapiNG(string.Format("CERTIFICATE=HashId:{0}", ApplicationConfig.dataProtectionCertThumbprint),
flags: DpapiNGProtectionDescriptorFlags.None);
Debugging from visual studio, everything runs fine, but I'm running VS under administrator rights, so permission is not an issue here.
I've tried adding permissions to the AppPool App user to the private key it self directly from MMC, but it did not worked, and even gave permission on the full path to the location were the keys should be created like stated here https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview (check first comment) but also it did not worked.
I was only able to make it work by setting the AppPool to run with the identity of an Administrator, but clearly this is a no go, I just wanted to make sure this was a permission issue somewhere.
Is anybody facing the same issue that is able to help?
Regards,
André
Most likely your issue is you are trying to store your keys somewhere in a folder path that you are cobbling together (or even by using the default path that AddDataProtection provides) that uses an environment path such as %LOCALAPPDATA%. Example: "%LOCALAPPDATA%\ASP.NET\DataProtection-Keys".
Usually, by default IIS DOES NOT set up your app pool accounts with environment path variables such as %LOCALAPPDATA%. The value ends up being blank and your app then tries to write keys to the wrong folder (such as \ASP.NET\DataProtection-Keys instead of %LOCALAPPDATA%\ASP.NET\DataProtection-Keys).
Fix: Within %WINDIR%\System32\inetsrv\config\applicationHost.config set setProfileEnvironment=true. I think you have to restart IIS as well.
I have a web application project in VS2012 which I'm publishing using a "Web Deploy Package". I want this package to include app-pool settings, specifically creating an IIS app-pool and assigning the newly created application to it.
I'm familiar with the option "Include application pool settings used by this Web project" available when the project is configured to use an IIS instance (not IIS Express), but IIS configuration is not part of the project file, and thus not source controlled. What happens when somebody builds a deployment package on a machine that hasn't had IIS meticulously configured? Not ideal.
How else then, can I go about getting AppPool settings into my web deploy package? I understand that the appPoolConfig provider is IIS7+ only, I'm fine with that limitation. I've banged my head against this issue in the past and never found a solution. 18 months later, we've got a new VisualStudio version, and a new web-publishing-pipeline, are there new options to address this? Or maybe something I missed when I first tackled this problem?
Edit
OK, I'm seeing the following as options:
Configure my project to sync settings from an IIS instance. As mentioned, I'm not a fan of this given that it puts settings outside of the project, meaning the environment has to be meticulously configured to build + publish. Plus it drags along other IIS settings I don't want included.
Inject something into the web-publishing-pipeline (WPP) to modify the archive.xml. I've toyed with this in the past and had limited success. One problem is the pipeline isn't exactly co-operative with working directly on the archive.xml file, another problem is some of the more cryptic attributes involved, like MSDeploy.MSDeployProviderOptions which appears to have some Base64 encoded binary? No idea what to put in there.
Find an existing "provider" that can do what I want. I might be out of luck here, the appPoolConfig provider only seems to want to read / write IIS, not, say, an XML file of settings. Does anybody know otherwise?
Write my own "provider" to produce manifest output entries. I'm not sure, is it possible to write a custom provider that writes to a manifest using the name of an existing provider? As in, MyCustomPoolProvider writes appPoolConfig sections into a manifest? This sounds like a potentially painful exercise that may or may not work. Would I still need to figure out the encoding of whatever is going into MSDeploy.MSDeployProviderOptions?
I get the feeling that the fundamental obstacle with Web Deploy for what I'm trying to accomplish, is how strictly it leans on "providers". The pre-existing providers are largely designed for IIS synchronisation, not primary development and publication. It so happens that some of these providers can be relatively easily hooked into via MSBuild, but the majority insist on pulling data from IIS, and that's that.
You are correct in your understanding of the appPoolConfig provider, in that it can only sync between App Pools and can't be provided with the configuration directly. What you could potentially do is keep a copy of the appPool in question in package form (ie. msdeploy -verb:sync -source:appPoolConfig=PoolName -dest:package=apppool.zip) and attempt to hijack the pipeline so that the MSDeploy call adds the application content into the package, leaving the existing content there.
Alternatively, you could always keep the packages separate and deploy them with different calls to MSDeploy.
FYI, MSDeploy.MSDeployProviderOptions is simply an encoded version of the parameters supplied to the provider when it was packaged. For example, -source:dirPath=c:\,ignoreErrors=0x10293847 -dest:package=package.zip would package the ignoreErrors value.
I have a 3rd party web page screen capture DLL from http://websitesscreenshot.com/ that lets me target a URL and save the page to a image file. I've moved this code into my Azure-based project and when I run it on my local sandboxed dev box and save to the Azure blob, everything is fine. But when I push the bits to my live server on Azure, it's failing.
I think this is because either MSHTML.dll and/or SHDOCVW.dll are missing from my Azure configuration.
How can I get these libraries (plus any dependent binaries) up to Azure?
I found the following advice on an MSFT forum but haven't tried it yet. http://social.msdn.microsoft.com/Forums/en-US/windowsazuredevelopment/thread/0344dcff-6fdd-4479-a3b4-3e89750a92f4/
Hello, I haven't tried mshtml in the cloud. But generally speaking, to
use a native dll in a Web Role, you add the dll to the Web Role
project just like adding a picture (choose add existing items). Then
make sure the Build Action is set to Content. This tells Visual Studio
to copy the dll file to the output package.
Also check dependencies carefully. A lot of problems related to native
code are caused by missing dependencies, such as a particular VC++
runtime dll.
Thought I'd ask here first before I burn a day or two on an unproven solution.
EDIT #1:
it turns out that our problem was not related to MSHTML.dll or SHDOCVW.dll missing from the Azure server. They're there.
The issue is that by default new server instance have the IE security hardening feature enabled, and this was preventing our 3rd party dll from executing script. So we needed to turn off the enhanced IE security configuration settings. This is also a non-trivial exercise.
In the meantime, we just created a server-side version of the feature on our site we need to make screen captures from (e.g. we eliminated JSON-based rendering of UI on the client), and we were able to proceed.
I think the solution mentioned in the MSDN forum thread is correct. You should put them as part of your project files, so that the SDK will package and deploy them to the VM on the cloud.
But if they are COM and need to be registed you'd better call the register command via the Startup feature. Please check http://msdn.microsoft.com/en-us/hh351539
HTH
Apparently the management piece of IIS - the IIS WMI provider - is installable separately from the IIS runtime.
I'd like to produce an installer for an add-on to IIS, and I know how to check for the existence of the IIS runtime in the WIX project. But, the installer needs to do various management things, WMI things, and for that it needs not only IIS, but the WMI Provider for IIS. Which as I said, may or may not be present.
In a WIX project, How do I check for the existence of the IIS WMI Provider, and how do I present a reasonable dialog to the user if the IIS WMI Provider is not present?
The installer already has a few MSI Custom Actions implemented in Javascript, and I can use
var iis = GetObject("winmgmts:root\WebAdministration");
...to check for the existence of the WMI Provider. It will fail (throw) if no WMI Provider is there. I suppose I could use this to set a Property, and then check that Property in a Condition early on in the Product.wxs file.
is this going to work? any other suggestions?
I suppose the better way for this is still to browse the registry for appropriate setting. Another question is it's not always easy to find the right one. :)
For instance, my installer needs IIS6 compatibility to be enabled (for IIS 7 machines), in particular, IIS 6 WMI compatibility. This setting is located under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp\Components, in a value called WMICompatibility. So, everything I should do is to author a RegistrySearch element to search for this value and check if it's 1.
In order to find the correct setting, I would search for the key all IIS parameters reside under (it might differ for each version of IIS, I'm not certain here), enable IIS WMI provider you need and see what was changed in registry. I suspect registry monitor software can help here a lot.
Yes, testing instantiation of the object via the moniker is going to work. It's a reasonable strategy, better than spelunking around in the registry. It delivers the right result, all the time. Just catch the exception that occurs if the WMI provider is not available.
I've got a classlibrary which defines a couple of helper classes/methods which are used from a classic asp web application. So far, everything works fine. Now I've added a new helper method which signs a PDF file using a third party tool. Using a console application to call this wrapper method, everything works fine. Once I use an asp page to call the exact same method, the call to
X509Certificate2 cert = new X509Certificate2(sigFilePath, sigPassword);
fails with the error "The system cannot find the specified file" (translated from german).
Since the same code works fine called from the console application, i guess the problem must be located somewhere different. Could it be a security issue?
When I wonder if I'm facing a security issue like you do, I just do a quick test : I put the user account the webserver is using in the administrators group, do a quick iisreset, and try again. If it's working know you now it's a security issue. If it's still failing, look somewhere else.
Never forget to then remove the user accoung from the administrators group, and only do that on you own dev machine, not on production servers !!
If it's a security issue, I would then recommend launching Process Monitor (look for procmon in google). It's a Microsoft download. Look for access denied in the result column. You'll then know what's blocking you ...