Map Network Drive in .Net with TLS security - c#

In the past, there has been lots of productive discussion on how to mount drives programmatically.
This link is one productive example:
How do I map a network drive that requires a username and password in .NET?
However, what I seem to be missing is a way to perform this mount when TLS is required.
We see things like this:
net.exe use x: "\server.com#ssl:443\folder" /User:UserName Password
Where this can be used in code with:
System.Diagnostics.ProcessStartInfo process = new System.Diagnostics.ProcessStartInfo();
process.FileName = "net.exe";
process.Arguments = "use Z: \\\\JoeDoodle.TheDomain5.com#SSL\\MyFolder\\ PassW0rd /user:JoeUser";
process.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
System.Diagnostics.Process p = System.Diagnostics.Process.Start(process);
// Other stuff...
This sort of thing works great with SSL but not TLS. This is a .Net 4.0 application with our test base starting on Windows 7. Since we are running this as process as shown I am not sure not much that matters.
I cannot use WNetAddConnection2 and related imports because this is a remote drive. The other end is Linux exposing Webdav and it works fine for SSL but not TLS specifically. They are phasing out SSL so I must use TLS.
Any way to mount it programmatically will probably be fine with TLS but I just haven't found the successful combination.
Any help is appreciated.

The problem was ultimately not a Windows problem but an Apache problem.
Apache required not just turning SSLv3 off but a slight code change and recompile.
This only applied to Windows 7 connecting so I do not know about Windows 8.

Related

SerialPort.GetPortNames() returns incorrect port names

While c# is not my primary programming language, I'm maintaining such a program for a couple of years now. This program connects to a device on a serial port and works from Windows XP up to 8.1. One specific "feature" is that it uses .NET Framework 2.0.
With some users upgrading to Windows 10 we've got complains that the program cannot detect/open the COM port of the device. We have confirmed this on our own test systems with clean Win10 installation.
It turns out that the function SerialPort.GetPortNames() returns incorrect port names and adds 'strange' characters after the port name.
For example:
COM3吀
COM3䡢
COM3゠
Etc. When I refresh the list, every time another character (or two) shows up after the number.
The test code is super straightforward:
string[] portNames = System.IO.Ports.SerialPort.GetPortNames();
log("Available ports:");
foreach (string PortAvailable in portNames)
{
log(PortAvailable);
}
Where the log function mearly adds a line to a standard TextBox on the form:
txtLog.Text += Msg + Environment.NewLine;
This works in every other Windows version.
I've checked the registry and all looks fine there also.
Does anybody has an idea about this?
I'm suspecting that .NET Framework 2.0 is not 100% compatible anymore, although you can enable it in the Windows features and it seems that the program itself runs fine (besides my serial port problem). I'm a bit scared to upgrade to a newer .NET, let alone that we've VisualStudio 2008 for c# (max=.NET 3.5). Note that the program still needs to run on Windows XP also (POS version is still maintained by Microsoft).
ADDED:
I've "upgraded" a test program to .NET 3.5, and still having exactly the same issue.
Next step is to install a new VisualStudio (it appears that it is free nowadays?? Should I check for privacy settings in Studio also? ;-).
ADDED 2:
Installed VisualStudio 2015 and made multiple builds with different .NET framework versions. v2.0 and 3.5 still adding the strange character. But in v4.0 and up this issue seems te be solved! Now to get the original program compiled and working for the newer Framework.
But I find this issue really strange and would expect that this would hit more .NET functions and more programs.
I've seen the strange characters too. My solution is using Regular Expressions to filter out the number portion of the comm port name.
Dim ports As New Devices.Ports
For Each s As String In ports.SerialPortNames
s = Regex.Replace(s, "\D*(\d+)\D*", "$1")
Debug.WriteLine(s)
Next
I've had this exact same problem with USB CDC serial devices, handled by the new rewritten Windows 10 usbser.sys driver.
The garbage characters are often digits, so removing non-digits isn't a reliable way to work around it. For my solution, look at my last post on this thread here:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/a78b4668-ebb6-46aa-9985-ec41667abdde/ioportsserialportgetportnames-registrykeygetvalue-corruption-with-usbsersys-driver-on-windows?forum=netfxbcl
..there is code there that'll go through the registry, find usbser ports, and return their unmangled names. Beware that it doesn't return all serial ports, just ones provided by that driver. The code works on Windows XP through to 10.
The underlying problem is that the usbser.sys driver creates a registry entry, and on .NET (at least up to 3.5) the GetPortNames() function tries to read those registry keys and gets corrupted data. I've reported this to Microsoft, both via that forum (assuming they read it) and using the built-in Windows 10 beta error reporting tool. Maybe one day there will be a fix.
As you say the program works after enabling the windows feature:
.NET 2.0,3.0,3.5 isn't enabled by default on Windows 8/8.1/10. The files aren't stored on the install media/wim.
It can be enabled with the DISM command from windows update or a local source.
DISM /Online /Enable-Feature /FeatureName:NetFx3 /All
check this out: http://forums.radioreference.com/uniden-tech-support/317887-windows-10-uniden-usb-driver-5.html
For a work around to fix the Win 10 serial port not working caused by strange characters after the port name.
Go in to the Registry with regedit.exe.
Navigate to "HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALC OMM"
Make note of the comm port name.
Append a "0" or any character to the comm port name.
Change the comm port name back to what it was in step 3.
It worked for me.
Baldur
string[] ports = SerialPort.GetPortNames();
for (int i = 0; i<ports.Length;i++)
{
string mystr = ports[i];
if (((mystr[mystr.Length-1]) >= 0x30) & ((mystr[mystr.Length-1]) <= 0x39))
{
}
else
{
mystr = mystr.Remove(mystr.Length-1);
}
ports[i] = mystr;
}

Mono HttpListener client certificate

I have created a server using HttpListener. It works perfect without SSL, but with SSL something strange happens.
I have installed the certificate using httpcfg and even with my own program, it installs correctly, the listener starts and serves HTTPS requests, but always asks for a client certificate.
It does not happens on Windows/.net, only with Linux/mono (I'm using ver 3.4.0) and is very annoying, I don't want the user to be asked each time he tries to log in for a client certificate.
Is this a mono bug or is there any way to disable the client certificate negotiation?
Thanks.
I'm having the same problem. What I've discovered is that this is hardcoded in Mono. In mcs/class/System/System.Net/HttpConnection.cs, when the constructor of SslServerStream is called, you will notice that the requestClientCertificate is hardcoded to true.
I came across this PR that attempts to change this hardcoded value to false, however it's currently semi-rejected due to "I rather not change one hardcoded value for another hardcoded value."
[Update] And I just now realized you (OP) are the author of the PR :)
[Update 9/21/2016] It looks like this question is still getting hits. If it is helpful to anyone, we went with nginx as a reverse proxy a long time ago when we could not resolve this issue. I'm glad we did, and should have done it sooner. It is much faster than Mono for handling the SSL/TLS, and allows us to more carefully control the crypto suites and keep up to date with security patches.
I'm keeping an eye on Mono 4.6, which has yet to release. With their overhaul of TLS and the ability to plug in alternate implementations at runtime this might give us a path forward without using nginx reverse proxy.
The only options one (still..) has are:
Use Gusman's pull request #1 or #2 (depending on your Mono version) as workaround which should be OK for productive environments, if a recent Mono version's source code is used.
Example for Mono v4.2.3.4:
echo -e -n "83c83\n< \t\t\t\tSslServerStream ssl_stream = new SslServerStream (new NetworkStream (sock, false), cert, false, true, false);\n---\n> \t\t\t\tSslServerStream ssl_stream = new SslServerStream (new NetworkStream (sock, false), cert, false, false, false);\n" > nocerts.diff
tar xvjf mono-4.2.3.4.tar.bz2
cd mono-4.2.3.4
patch ./mcs/class/System/System.Net/HttpConnection.cs ../nocerts.diff
./configure --prefix=/usr
make
make install
Or use the last Mono version that works without client certificates (which is v3.10.0).

Working with mongodb without a live port (embedded)

I am starting mongodb from C# code.
I am connecting to it without mentioning any port:
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = dir + #"\mongod.exe";
start.WindowStyle = ProcessWindowStyle.Hidden;
start.UseShellExecute = false;
start.Arguments = "--dbpath d:\test\mongodb\data";
Process mongod = Process.Start(start);
MongoClient client = new MongoClient();
MongoServer server = client.GetServer();
MongoDatabase database = server.GetDatabase("db_name");
at the mongodb console (output window) I see that mongodb is listening to a port.
Is it possible to start mongo without a port?
You can't. MongoDB is a standalone server. The only way to communicate with MongoDB is using TCP or unix sockets, so it's never a truly embedded database. Auto-Deploying the database doesn't make it an embedded database, it will have its own process and it will be available to other applications.
When you don't configure a port, MongoDB (and it's drivers) will use port 27017.
If you need an embedded database, use one. Candidates for C# include SQLite, db4o, perst and it's BSD-licensed fork volante, and a ton of smaller projects like siaqodb (some of these not free).
MongoDB will be trouble because it's rather aggressive about memory allocation and might need repair when things go wrong.
You can't start mongod without it listening to a port, however to restrict access you can:
use the bind_ip configuration option to limit connections to localhost only (127.0.0.1)
use the port configuration option to change to a non-standard port specific to your application
configure authentication and appropriate user roles
Given you are planning to spawn the mongod process on the user's machine, you unfortunately can't prevent determined users with Administrator access from bypassing any of the above restrictions.
As noted in the answer by #mnemosyn, there are certainly databases such as SQLite that are designed to be embeddable and compiled into your application code without spawning external processes.

Windows-7:Disable internet connection sharing on network adapter when it's in hidden state?

I'm trying to share internet over a network adapter on windows-7 using NetConLib.dll.
In order to do this, internet sharing should be disabled on all other network adapters.
In normal cases. I can iterate all the installed network adapters and disable sharing on them.
However, sometimes when the network device is unplugged, the adapter is hidden in windows.
But it's properties is still present inside windows registry.
I can't even find the adapter in Control Panel.
And off course, can't iterate it using the NetConlib library.
Possible scenarios.
The easiest way, would be using a windows command to disable internet
sharing on all the adapters. Regardless of their visibility.
Is that possible in anyway ?
The second solution is to recover the network adapter from hidden state, so that
NetConlib could iterate through it and disable it.
I tried to find the adapter's properties in windows registry and unhide it, But couldn't find anything.
Any solution?
#erm3nda.
Thank you for the informative answer. Although it didn't fix the problem I'm facing with NetConlib.
SC config correctly shuts down ICS service. But the shared network adapter continues on being flagged as Shared1. So ICS service being turned off doesn't seem to affect the adapters' settings.
Quite interestingly; when you try to share another adapter using windows GUI (Right click on adapter -> Properties -> Share), a message is prompted telling you
"there is another adapter being shared currently, your new adapter
will be shared instead". You click ok and it's done.
I've been digging the entire internet the whole afternoon to see if there are other solutions using CMD commands.
Maybe there could be a away to share an adapter with a command. This way windows would handle disabling other adapters. In a similar way as when the GUI is used.
1: Windows tells you which adapter is currently being shared in Control Panel\Network and Internet\Network Connections).
Possible solution 1: Disable ICS at all.
You can stop ICS service, so none of the connections will be at sharing status and will not conflict with NetConLib.dll. (Not sure about the hidden ones, you must try).
You can manage it from command line using:
net start SharedAccess or net stop SharedAccess
Also, if you need to disable it from reboot to, must disable service using:
sc config SharedAccess start= disabled
Notes and references:
Executing sc config will display "start= OPTIONS" and some other.
The space below = and option is mandatory. You can check result
running services.msc from Run or cmd.
Exec net to display OPTIONS. The name of service is on the
services.msc list under "Name of the service" label from ICS service.
netsh routing is not on Win7 anymore, so you only can
start/stop/enable/disable but not enable for a particular Interface.
You must set by handMouse... This not work under Win7 ICS into XP
system
Sc Config command was from this cool documentation i found
today.
Possible solution 2: Remove ghost interfaces?
I try also around Adapters and interfaces into registry and do not see anything about show/hid/ghost/enabled or similar. I also search here kb 314053 for registry conf.
I can suggeest try Possible solution 1 :) or directly delete hidden/ghost adapters.
You can do it by two ways. Devcon remove option will delete also drivers.
Device manager: Run set devmgr_show_nonpresent_devices=1 and run
devmgmt.msc. You must see over "See" a "Show hidden" option. The
show_nonpresent must reveal also hidden devices, not only inactive.
kb 269155 - You must click over #link named "Let me fix it
myself"
With devcon.exe utility: This is a device manager tool from Windows
with power moves. You will find a very big and helpfull guide
here.
Basic usage for find netcards devcon findall =net, also you can devcon findall =net *ndis* to list all ndis cards.
Basic usage for remove will be devcon remove =net *ndis* to remove all ndis card type.
I try also enable/disable commands but nothing has change into my network interfaces list.
I removed my own wifi card to test it :) Anyway, i didn't notice any option about "Unhide" feature for such devices from conections panel.
NEW EDIT (Too much verbose, right?)
I found a tool called ics-manager from this superuser post. - read answer #3
You can download directly from utapyngo's Git project page.
It's based on .Net Framework 4. Yo must download and run the build.bat to compile both exe's (You got also the C# source). The solution is to get only the compiled IcsManager.exe (command line version) with the only needed library IcsManagerLibrary.dll.
This app is using also NETCONLib.dll, so you can use it, or read the source to see wich is the correct function you need to do it and implement on your development.
If you got problems with the Ip range "192.168.137.1", you can set from Registry permanently, or run netsh interface ipv4 set address name="YOUR-INTERFACE" source=static addr=192.168.2.1 mask=255.255.255.0. You will got ugly errors from launch the netsh interface using tilde or accutes into interfaces name (Spanish default ethernet name is "Conexión de áreal local"... a joke).
Note: You can pack all at once, using first a Bat to call the IcsManager.exe' with the arguments needed, then launch the netsh configure command later from same batch to full configure.
Comment: About the prompt when try to overwrite an shared connection, it's surely because only one could be shared. I also see, they are configured as Public and Home to set the pair, but i can't find where's the registry key...Also make some exports from reg and using Diffs, no lucky. I got stuck at diffs and start to search "ICS C++ and C#" on Google, then found it.
Extra: I got the netsh it into a bat, and it's launched for Windows Task when a Ethernet cable is plugged (Here is the howto) in order to use with Android Reverse Tethering. As you can see, im too interesting into your question because it makes me research better and also learned a lot.
Sorry about my bad English. Im not.
Regards.
I found that by going into Device Manager, you can show the Hidden Devices and try to disable the internet sharing on the adapters.
Hopefully this is near what you are asking. Good luck!
Atm
Source: http://msdn.microsoft.com/en-us/library/windows/hardware/ff553955%28v=vs.85%29.aspx
I'm about 10 years late to the party, but the complete solution to this problem is nowhere else on the internet. In order to disable internet connection sharing for a device that is unplugged or uninstalled you will need to:
Clear the shared access registry
Clear the WMI sharing entry for the device
Disable sharing through the netcon library
Clearing the registry:
You need to set two registry keys to 0xFFFFFFFF:
HKLM:\Software\Microsoft\Windows\CurrentVersion\SharedAccess\PrivateIndex and
HKLM:\Software\Microsoft\Windows\CurrentVersion\SharedAccess\PublicIndex
For example in powershell:
Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\SharedAccess" -Name "PrivateIndex" -Value 0xFFFFFFFF
Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\SharedAccess" -Name "PublicIndex" -Value 0xFFFFFFFF
Clear the WMI sharing entry for the device:
For every HNet_ConnectionProperties you must ensure IsIcsPublic and IsIcsPrivate is set to false. You can view which interface has IsIcsPublic or IsIcsPrivate set in powershell:
Get-CimInstance -ClassName 'HNet_ConnectionProperties' -Namespace 'root\Microsoft\HomeNet' | Format-Table
Unfortunately, the Set-CimInstance cmdlet does not appear to work in this scenario, so we have to choose another language. Fortunately, code to set these values to false can be found online. For example, here is some C# that performs this task (attibuted to utapyngo)
public static void CleanupWMISharingEntries()
{
var scope = new ManagementScope("root\\Microsoft\\HomeNet");
scope.Connect();
var options = new PutOptions();
options.Type = PutType.UpdateOnly;
var query = new ObjectQuery("SELECT * FROM HNet_ConnectionProperties");
var srchr = new ManagementObjectSearcher(scope, query);
foreach (ManagementObject entry in srchr.Get())
{
if ((bool)entry["IsIcsPrivate"])
entry["IsIcsPrivate"] = false;
if ((bool)entry["IsIcsPublic"])
entry["IsIcsPublic"] = false;
entry.Put(options);
}
}
... and some vbscript (attributed to billchaison):
set WMI = GetObject("WinMgmts:\root\Microsoft\HomeNet")
set objs1 = WMI.ExecQuery("SELECT * FROM HNet_ConnectionProperties WHERE IsIcsPrivate = TRUE")
for each obj in objs1
obj.IsIcsPrivate = FALSE
obj.Put_
next
set objs2 = WMI.ExecQuery("SELECT * FROM HNet_ConnectionProperties WHERE IsIcsPublic = TRUE")
for each obj in objs2
obj.IsIcsPublic = FALSE
obj.Put_
next
Disable sharing through the netcon library:
This part you probably already know, but for completeness, here is some powershell that does it:
regsvr32.exe /s hnetcfg.dll
$NetShare = New-Object -ComObject HNetCfg.HNetShare
foreach ($RawConnection in $NetShare.EnumEveryConnection) {
$Sharing = $NetShare.INetSharingConfigurationForINetConnection.Invoke($RawConnection)
$Sharing.DisableSharing()
}
The documentation for the relevant COM APIs for netcon can be found on MSDN

Register ocx files remotely

I have some VB6 .ocx files that I would like to register. These .ocx files would be on a remote machine.
What is the best way to register these .ocx files programatically?
string arg_fileinfo = "/s" + " " + "\"" + "\\<remotemachine>\\<directory>\\<ocx>" + "\"";
Process reg = new Process();
//This file registers .dll files as command components in the registry.
reg.StartInfo.FileName = "regsvr32.exe";
reg.StartInfo.Arguments = arg_fileinfo;
reg.StartInfo.UseShellExecute = false;
reg.StartInfo.CreateNoWindow = true;
reg.StartInfo.RedirectStandardOutput = true;
reg.Start();
reg.WaitForExit();
reg.Close();
I'm not getting any errors but it isn't registering the .ocx either. Any ideas?
If you want to register a remote file for use on a local machine, there is nothing special required for registering a file on a UNC path, but you do need to make sure that the UNC path or mapped drive is still available to all users, especially the user that is running regsvr32. Presumably, this will be the local admin which (by default on Windows Vista+) will require elevation which can disconnect network connections.
Also note that your example is missing the extra \ from the beginning of the UNC path. Your code will result in arg_fileinfo containing /s "\<remotemachine>\<directory>\<ocx>".
You can add the extra \, or use the # decorator which makes it a lot clearer when entering Windows paths:
string arg_fileinfo = "/s \"" + #"\\<remotemachine>\<directory>\<ocx>" + "\"";
Or just use it for the entire string and the alternative quote escaping method:
string arg_fileinfo = #"/s ""\\<remotemachine>\<directory>\<ocx>""";
Take this as a warning you're free to ignore (because I know you will anyway):
Doing this isn't a good practice. Just to begin with "run from network" PE files (EXE, DLL, OCX) need to be specially linked for it or you risk high network activity and crashes due to intermittent network interruptions. And registering anything not on the boot drive or at least a local hard drive isn't sensible anyway. Doing any of this ranks high on the "poor practices" list even though it might seem to work most of the time.
Why not just do normal deployment following accepted practices?
My guess would be that you are doing a lot of Mort development, throwing together version after version of some program hoping one of them will eventually "stick." So you want to dump some or all of it onto a network share, thinking "Installation? Installation? We don't need no steenking installation. I can just plop new files out there and have everything magically work with no effort."
I'll assume you don't have the luxury of a managed network you can use to push out updates via Group Policy, and that you aren't creating the necessary MSI installer packages handling the Product and Upgrade Codes in them.
One alternative would be to use reg-free COM, which will solve a lot of small issues for you.
Now, you could do this and still ignore the hazards of PE files run from a network share, or you could bypass that using a small launcher program. That launcher could check a network share for a new version, and if found copy the newer files to the local PC before starting the actual application and terminating. This is basically an auto-updated XCopy Deployment technique.
You can get as fancy as need be. For example if your application accepts command line parameters it might do the new version check itself and if found then start the small updater (passing it the command line parameters), then terminate. The updater app could restart and pass those parameters to the new version.
But yes, life as Mort (or even an official on-the-payroll developer) can be a pain. It can be extremely difficult to get the attention of your friendly neighborhood box jockeys to do things properly even if you are working in a managed corporate LAN environment. That goes double if your application isn't part of some highly engineered sanctioned Major Project.
I had to do this several years ago. As best I can remember, UNC names wouldn't work, a mapped drive letter was required. Whether it was strictly a regsvr32 issue, or was caused by something else (e.g. Windows 95) is lost in the fog of time.
If you want to register the file for use on the remote machine, you you need to run the code on that remote machine.
You can either do this by physically sitting in front of the computer, using remote control software, or a remote admin tool like psexec.exe.

Categories

Resources