 |
|
 |
Sorry but the following line will not compile since NetFwAuthorizedApplications is an uknown type. Am I doing somthing wrong? Regards David 
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
He had a typo it should be INetFwAuthorizedApplications
cheers, Donsw My Recent Article : CDC - Change Data Capture
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
This is good for xp, but the file is different for vista and xp so the same code will not work on both. You might want to update your article.
cheers, Donsw My Recent Article : CDC - Change Data Capture
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
 |
Don or anybody I implemented your code in a very simple test program with an Add button that adds the application to the firewall list, and a Remove button that removes it. This works absolutely fine. Then I called the same code from an Installer class as part of the install custom action, so that when I install the program it adds itself to the firewall list. In this case the call to INetFwAuthorizedApplications.Add(INetFwAuthorizedApplication) throws a System.InvalidCastException. I am completely mystified as to why this should happen. If anyone else has experienced this problem I would be delighted to hear from them - if they've solved it that would be even better!
Dave
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Issues with an "Installer class" vs. a normal application introduces many considerations that are very different from the core code in the example. When your Installer class executes, it's within the context of Microsoft's installer - msiexec which is a database and functionality combined to perform MS sanctified installations. They consider the authority to perform these operations, the ability to rollback operations; acceptability based on the concept of advertised functionality, etc.
To be honest, I did get the example to work as an installer class when I first developed it using msiexec installing for Administrators as an Administrator; however for needing to install my application for unpriviledged users there were many msiexec context issues that I didn't have time to work through and ended up not using msiexec.
For downloading some Google software, I noticed that they used the NSIS installer http://nsis.sourceforge.net/Main_Page. It's Windows specific, easy to learn and use, allows rebranding, looks very professional; and your executables behave like normal applications; ie you probably won't get the class cast exception running under NSIS.
It could be too that Microsoft views this functionality as a security hole as mentioned in a previous thread and so the cast exception is intentional; or the underlying functionality may have changed and the example now has a bug. For me, I wasn't interested in becoming an install expert and soon reached diminishing returns with msiexec issues. I just needed my app installed as a priviledged app with those needed ports open.
-- modified at 5:36 Thursday 29th November, 2007
Don
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I notice that you explicitly set a lot of the COM objects to null after they have been used. I would have thought this would be handled by the garbage collector, or is this an aspect of calling COM from managed code that I don't know about?
Dave
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
The tought behind that is that managed code will garbage collect when client references are null. And it is true that interface references are relinquished when the code runs out-of-scope; but lighter is better and I've had to debug memory loss issues in C++ code for forgetting to be explicit about it. Old habits I guess.
Don
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
This is really useful and just what I need, many thanks. I do have one question - I am not very experienced in using COM from C#. I see from the MSDN pages that, for example, a call such as INetFwPolicy fwPolicy = fwMgr.LocalPolicy; is actually a call to get_LocalPolicy(INetFwPolicy** localPolicy) which returns an HRESULT (http://msdn2.microsoft.com/en-us/library/aa365291.aspx[^]), and can potentially fail. I wondered if you knew how to detect an error (presumably null is returned) and how to acquire the HRESULT error code. With a Platform Invoke call it is just a matter of calling GetLastWin32Error(). Is it the same with COM?
Dave
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi Dave,
Your welcome, glad this example helped out.
HRESULTs, if included in the method signature of a COM interface, must be returned. Returning null when the return type is an HRESULT violates the COM contract and just isn't cool. HRESULTS have high order bits that tell whether the returned HRESULT is an error or not and the subsystem for which the code applies. Please check the appropriate include file for the details on the bit designations and error code values.
In practice, I recall using "if( hr != S_OK )" or some derivitive of it to detect errors and maintain memory and interface pointer integrity (C++). You might also look at COM smart pointers that can help in handling errors and protecting integrity. I don't recall the convention for C#; but guessing from the first signature you listed, you're probably right that fwPolicy would receive a null if fwMgr.LocalPolicy had a problem returning the INetFwPolicy interface.
Hope this helps, Don
Don
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Having done some testing, it turns out that the calls do not return null if a COM error occurs (many of the calls don't have a return value anyway, so that wouldn't work). In fact they they throw an exception.
Dave
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi Dave,
Not surprising, exceptions are a preferred mechanism to return error conditions because they can't be ignored by client code.
Don
Don
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Hi AleRanza,
When I coded/tested this originally, I used the admin user. Our needs were that the admin user would install our application and a limited user would just use it. Someone more familiar with the details of specific privileges will have to address your question; I've tried, but just don't know the intracacies of the XP security system.
Don
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I have converted your code to a class, so that someone can actually use it in an application from any point in the code the programmer considers suitable. I have separated the open and close ports and made the class take as parameters the application location to open as well as what ports need to be opened. As I believe some users might find it useful, I'm posting the code below. Great article by the way.
using System; using System.Collections.Generic; using System.Text; using System.Reflection; using NetFwTypeLib; using Microsoft.Win32;
namespace FWSetupAction { public class Firewall { protected INetFwProfile fwProfile;
#region openFirewall /// /// Opens the given ports on windows firewall. Also opens entirely the given application on the firewall. /// Please remember that you need administrative rights to use this function. /// /// The path of the application. Please include the ending \ /// The name of the executable to open /// The ports that you wish to open individually public void openFirewall(string filePath, string applicationName, int[] portsToOpen) { ///////////// Firewall Authorize Application //////////// String imageFilename = filePath + applicationName; setProfile(); INetFwAuthorizedApplications apps = fwProfile.AuthorizedApplications; INetFwAuthorizedApplication app = (INetFwAuthorizedApplication)getInstance("INetAuthApp"); app.Name = applicationName; app.ProcessImageFileName = imageFilename; apps.Add(app); apps = null;
//////////////// Open Needed Ports ///////////////// INetFwOpenPorts openports = fwProfile.GloballyOpenPorts; foreach (int port in portsToOpen) { INetFwOpenPort openport = (INetFwOpenPort)getInstance("INetOpenPort"); openport.Port = port; openport.Protocol = NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP; openport.Name = applicationName + " Operation Port (" + port.ToString() + ")"; openports.Add(openport); } openports = null; } #endregion // openFirewall
#region closeFirewall /// /// Deletes the firewall ports specified from the windows firewall exclusions list. Also deletes /// the given application from the excluded apps. /// /// The path of the application. Please include the ending \ /// The name of the executable to close /// The ports that you wish to close individually public void closeFirewall(string filePath, string applicationName, int[] portsToClose) { String imageFilename = filePath + applicationName; setProfile(); INetFwAuthorizedApplications apps = fwProfile.AuthorizedApplications; apps.Remove(imageFilename); apps = null; INetFwOpenPorts ports = fwProfile.GloballyOpenPorts; foreach (int port in portsToClose) { ports.Remove(port, NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP); } ports = null; } #endregion
#region setProfile protected void setProfile() { // Access INetFwMgr INetFwMgr fwMgr = (INetFwMgr)getInstance("INetFwMgr"); INetFwPolicy fwPolicy = fwMgr.LocalPolicy; fwProfile = fwPolicy.CurrentProfile; fwMgr = null; fwPolicy = null; } #endregion
#region getInstance protected Object getInstance(String typeName) { if (typeName == "INetFwMgr") { Type type = Type.GetTypeFromCLSID( new Guid("{304CE942-6E39-40D8-943A-B913C40C9CD4}")); return Activator.CreateInstance(type); } else if (typeName == "INetAuthApp") { Type type = Type.GetTypeFromCLSID( new Guid("{EC9846B3-2762-4A6B-A214-6ACB603462D2}")); return Activator.CreateInstance(type); } else if (typeName == "INetOpenPort") { Type type = Type.GetTypeFromCLSID( new Guid("{0CA545C6-37AD-4A6C-BF92-9F7610067EF5}")); return Activator.CreateInstance(type); } else return null; } #endregion
#region OpenFirewallPorts /// /// Opens the given ports on windows firewall. Also opens entirely the given application on the firewall. /// Please remember that you need administrative rights to use this function. /// /// The path of the application. Please include the ending \ /// The name of the executable to open /// The ports that you wish to open individually public static void OpenFirewallPorts(string executableFilePath, string applicationName, int[] portsToOpen) { Firewall fw = new Firewall(); fw.openFirewall(executableFilePath, applicationName, portsToOpen); } #endregion
#region CloseFirewallPorts /// /// Deletes the firewall ports specified from the windows firewall exclusions list. Also deletes /// the given application from the excluded apps. /// /// The path of the application. Please include the ending \ /// The name of the executable to close /// The ports that you wish to close individually public static void CloseFirewallPorts(string executableFilePath, string applicationName, int[] portsToClose) { Firewall fw = new Firewall(); fw.closeFirewall(executableFilePath, applicationName, portsToClose); } #endregion } }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
One thing I didn't see in your article (which I just assume) is that you need to be logged in as an Administrator to do this... which makes the previous poster's comments moot.
Otherwise, a very good article!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Good point, I'd forgotten about that aspect of it. Absolutely true -in order to install apps, write to the registry, change the firewall; you need to have Administrator privs.
Thanks very much, Don
Don
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
But on the Home editions (that almost everyone outside the IT business uses because it is cheaper) everyone is an administrator. So, I am still convinced this is an security hole. All security changes should at least be validated by a human to prevent "terror" apps from misusing it.
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
 |
As said in the previous topic, Microsoft provides the INetFwMgr api which is available to any installation software that uses it. If you view it as a security leak, you'll have to discuss it with Microsoft.
To your point about validating security changes; anytime you install an application, essentially you are endorsing all the changes that that install will make to your machine.
-- modified at 9:36 Thursday 27th July, 2006
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
 |
If you install AOL Instant Messenger or iTunes, they automatically add themselves. The API is provided so that people can make use of them.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
An application that add's itself to the windows firewall? Nice for spyware and virusses.
Please report this code to microsoft, so they can plug this hole .....
|
| Sign In·View Thread·PermaLink | 1.00/5 (2 votes) |
|
|
|
 |
|
 |
This code uses the Microsoft's firewall api so it's functionality they provide, not a hole in their security. It's true that you need to know the authenticity of the apps that you install; but not all apps are spyware and your machine would be pretty boring if your firewall prevented all network communications. By the way, if you run an app that needs to open and listen on a socket; Microsoft's firewall will prompt to see if you want to allow the application.
It's interesting too that allowed applications are actually more secure than opening ports. Open ports remain open whether the app that needs them is running or not. For allowed applications, the ports they listen on are open only when they execute; otherwise those ports are closed.
Not all applications are spyware and legitimate applications do this routinely - file and print sharing, iTunes, games, instant messangers, etc.
Don
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
 |
I concur that network connections are needed, and that the most programs available are thrust worthy. But, spyware firms are very good in misleading humans, so these apps will be installed. One of the pro's of XP is the Firewall, protecting these users. But, by providing such api's, the normal users (with xp-home) lose their protection.
|
| Sign In·View Thread·PermaLink | 1.00/5 (2 votes) |
|
|
|
 |