UWP create VPN connection - c#

Currently I'm trying to figure out, how to add a VPN profile and connect to it from my universal app. I can connect to existing VPN connections with the Windows.Networking.Vpn namespace. I can also add a profile, but can not find a way to set all the required information (PSK for example). There is no documentation about this namespace in the MS docs. I also saw that there are two different profile namespaces available: VpnNativeProfile and VpnPlugInProfile. What is the difference between them? Currently I'm not at home, so I can't provide my current code, but it would be very helpful if someone can give me some hints. Is there a documentation available somewhere else?
Edit 1//
Here is my sample Code
Creating a profile
VpnManagementAgent mgr = new VpnManagementAgent();
VpnNativeProfile profile = new VpnNativeProfile()
{
AlwaysOn = false,
NativeProtocolType = VpnNativeProtocolType.L2tp,
ProfileName = "MyConnection",
RememberCredentials = true,
RequireVpnClientAppUI = true,
RoutingPolicyType = VpnRoutingPolicyType.SplitRouting,
TunnelAuthenticationMethod = VpnAuthenticationMethod.PresharedKey,
UserAuthenticationMethod = VpnAuthenticationMethod.Mschapv2,
};
profile.Servers.Add("vpn.example.com");
VpnManagementErrorStatus profileStatus = await mgr.AddProfileFromObjectAsync(profile);
Connecting to the VPN
PasswordCredential credentials = new PasswordCredential
{
UserName = "username",
Password = "password",
};
VpnManagementErrorStatus connectStatus = await mgr.ConnectProfileWithPasswordCredentialAsync(profile, credentials);
This works, but i don't know where or how to set the PSK.

VPN Native Profile : This refers to a Windows Inbox / Built-In VPN profile and can be used for L2TP, PPTP or IKEv2 based VPN
VPN Plugin Profile : Refers to a Windows 10 UWP based VPN Plugin. This is a VPN app written using the Windows.networking.VPN namespace.
I also took a peek at the code and can see that there seems to be a very obvious miss where there isnt really a way to set the PSK via the code. The only real workaround would be to set it in the Settings UI for now.
I will go ahead and report to the VPN team for Windows about this being missing.
Documentation Link : https://learn.microsoft.com/en-us/uwp/api/windows.networking.vpn

Related

WebView2 Not Respecting Windows Account (allowSingleSignOnUsingOSPrimaryAccount)

I have a .NET 5.0 WinForms app that uses WebView2 with the evergreen runtime. I create my own environment with allowSingleSIgnOnUsingOSPrimaryAccount set to true (see snippet below). This results in the user opening up the app viewing our AzureAD fronted web app and authenticating against our app reg without the need to type in a user/pass or go through MFA.
var _cacheFolderPath = Path.Combine(Application.UserAppDataPath, "Myappname.exe.WebView2");
CoreWebView2EnvironmentOptions webViewEnvironmentOptions = new CoreWebView2EnvironmentOptions(allowSingleSignOnUsingOSPrimaryAccount: _config.UseWindowsAuth);
var webView2Environment = CoreWebView2Environment.CreateAsync(browserExecutableFolder: null, userDataFolder: _cacheFolderPath, options: webViewEnvironmentOptions).Result;
webView.EnsureCoreWebView2Async(webView2Environment);
On most machines, this works as expected, but there are a few machines where users are prompted for password. So a user that seamlessly logs in to our web app when logged into Windows on their primary machine may go to one of these particular machines and get prompted for an email/pass and MFA. I'm not seeing errors, event logs, etc....it just seems as though setting this value to true in code is simply being ignored or overridden.
I've tried to look for documentation related to Group Policy settings possibly being the cause, but there is not a lot I found regarding this for WebView2. Is there anything that is/can be set explicitly through GP, or some other mechanism that may be having some effect WebView2's behavior regarding allowSingleSignOnUsingOSPrimaryAccount?
Maybe try to go with something like this:
var options = new CoreWebView2EnvironmentOptions
{
AllowSingleSignOnUsingOSPrimaryAccount = true,
AdditionalBrowserArguments = "--auth-server-whitelist=_"
};
var userdatafolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Incognito", new Random().Next().ToString());
var environment = await CoreWebView2Environment.CreateAsync(null, userdatafolder, options: options);
Debug.WriteLine("InitializeAsync");
await WebView21.EnsureCoreWebView2Async(environment);
Debug.WriteLine($"WebView2 Runtime version: {WebView21.CoreWebView2.Environment.BrowserVersionString}");

LDAP search fails on server, not in Visual Studio

I'm creating a service to search for users in LDAP. This should be fairly straightforward and probably done a thousand times, but I cannot seem to break through properly. I thought I had it, but then I deployed this to IIS and it all fell apart.
The following is setup as environment variables:
ldapController
ldapPort
adminUsername 🡒 Definitely a different user than the error reports
adminPassword
baseDn
And read in through my Startup.Configure method.
EDIT I know they are available to IIS, because I returned them in a REST endpoint.
This is my code:
// Connect to LDAP
LdapConnection conn = new LdapConnection();
conn.Connect(ldapController, ldapPort);
conn.Bind(adminUsername, adminPassword);
// Run search
LdapSearchResults lsc = conn.Search(
baseDn,
LdapConnection.SCOPE_SUB,
lFilter,
new string[] { /* lots of attributes to fetch */ },
false
);
// List out entries
var entries = new List<UserDto>();
while (lsc.hasMore() && entries.Count < 10) {
LdapEntry ent = lsc.next(); // <--- THIS FAILS!
// ...
}
return entries;
As I said, when debugging this in visual studio, it all works fine. When deployed to IIS, the error is;
Login failed for user 'DOMAIN\IIS_SERVER$'
Why? The user specified in adminUsername should be the user used to login (through conn.Bind(adminUsername, adminPassword);), right? So why does it explode stating that the IIS user is the one doing the login?
EDIT I'm using Novell.Directory.Ldap.NETStandard
EDIT The 'user' specified in the error above, is actually NOT a user at all. It is the AD registered name of the computer running IIS... If that makes any difference at all.
UPDATE After consulting with colleagues, I set up a new application pool on IIS, and tried to run the application as a specified user instead of the default passthrough. Exactly the same error message regardless of which user I set.
Try going via Network credentials that allows you to specify domain:
var networkCredential = new NetworkCredential(userName, password, domain);
conn.Bind(networkCredential);
If that does not work, specify auth type basic (not sure that the default is) before the call to bind.
conn.AuthType = AuthType.Basic;

Exchange Web Services Autodiscover non default link

I am writing a piece of software that runs on a utility device on a customers network, but not on the domain. The autodiscover service is not available off domain the same as it is either on the domain or even on the internet. None of the ways the service works by default will find it according to the docs, but the customer's IT staff tells me, supposedly :/ , it will all work if I can access Autodiscover at the link they gave me. Is there any way to override the default approach and pass it this url to autodiscover from? Hardcoding the link to /exchange.asmx is not an option nor is adding this device to the domain.
I am reusing, and now tweaking, a tried and true piece of software that has been deployed many times, but this situation is a first.
Using the EWS Managed API you may be able to do it using the AutodiscoverService class. It has a constructor that takes the URI of the Autodiscover service as a parameter.
Your code should look something like this. Note that I disable SCP lookup as you are not on a domain. I have not actually tried this code but give it a try:
AutodiscoverService ads = new AutodiscoverService(new Uri("..."));
ads.EnableScpLookup = false;
ads.Credentials = new NetworkCredential(...);
ads.RedirectionUrlValidationCallback = delegate { return true; };
GetUserSettingsResponse grResp = ads.GetUserSettings("someemail#domain.com", UserSettingName.ExternalEwsUrl);
Uri casURI = new Uri(grResp.Settings[UserSettingName.ExternalEwsUrl].ToString());
var service = new ExchangeService()
{
Url = casURI,
Credentials = ads.Credentials,
};

Sync Framework - file sync across domains

I'm trying to do a one-way directory synchronization across domains (with no trust). Ideally I'd like to use an existing sync framework like Microsoft Sync Framework 2.1, but can't figure out how to set up the authentication correctly. I think I'll need to use NTLM pass-through authentication (described here), but initial tests are not showing success.
The code I'm working off of looks similar to this (based off the MSDN sample):
SafeTokenHandle safeTokenHandle;
bool returnValue = LogonUser("xfrtest", ".", "password", 8, 2, out safeTokenHandle);
using (WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle()))
{
using (WindowsImpersonationContext ctx = newId.Impersonate())
{
sourceProvider = new FileSyncProvider(
sourceReplicaRootPath, filter, options);
destinationProvider = new FileSyncProvider(
destinationReplicaRootPath, filter, options);
SyncOrchestrator agent = new SyncOrchestrator();
agent.LocalProvider = sourceProvider;
agent.RemoteProvider = destinationProvider;
agent.Direction = SyncDirectionOrder.Upload;
sourceProvider.DetectChanges();
destinationProvider.DetectChanges();
var results = agent.Synchronize();
}
}
I have the "xfrtest" account set up locally on both machines with the same password. The logon works for the source system (which I'm also running the code on) but fails on the target.
So the questions are...first, is it possible to do this using Sync Framework? If so, am I approaching it wrong with pass-through? If not, any suggestions for good alternatives?
As it turns out, this code actually DOES work. My issue was that my non-production domains I was testing in had trust, which causes Windows to not fall back to NTLM pass-through authentication. When I set up domains with no trust or non-domain machines, this works.

Help With Proxy Username & Pass with GeckoFX?

I am trying to set the proxy username and password. I saw this posting (http://geckofx.org/viewtopic.php?id=832) and I thought it might be a similar setting for the username/password, such as :
Skybound.Gecko.GeckoPreferences.User["network.proxy.user"] = (user);
Skybound.Gecko.GeckoPreferences.User["network.proxy.password"] = (password);
But, nothing has worked so far. Can anyone help? I would really appreciate it!!!
I am using VB.net if that helps. Thanks!!
You probably need to set proxy type to 1.
To detect proxy settings automatically, try this:
Uri website = new Uri("http://stackoverflow.com");
System.Net.IWebProxy defaultproxy = System.Net.WebRequest.GetSystemWebProxy();
Uri proxy = defaultproxy.GetProxy(website); //no actual connect is done
if (proxy.AbsoluteUri != website.AbsoluteUri) {
Skybound.Gecko.GeckoPreferences.User["network.proxy.http"] = proxy.Host;
Skybound.Gecko.GeckoPreferences.User["network.proxy.http_port"] = proxy.Port;
Skybound.Gecko.GeckoPreferences.User["network.proxy.ssl"] = proxy.Host;
Skybound.Gecko.GeckoPreferences.User["network.proxy.ssl_port"] = proxy.Port;
Skybound.Gecko.GeckoPreferences.User["network.proxy.type"] = 1;
//0 – Direct connection, no proxy. (Default)
//1 – Manual proxy configuration.
//2 – Proxy auto-configuration (PAC).
//4 – Auto-detect proxy settings.
//5 – Use system proxy settings (Default in Linux).
}
You're trying to set them among the settings. You can access all available settings by typing about:config in the firefox addressbar, and there is no user or password setting there. I assume this is because the usernames and passwords needs to be stored securely.
I think that if you leave them unset when you try to connect to the proxy it'll ask you for them and then store them somewhere secure, and it will then use that username and password automatically.
If you do need to store them manually, I'd suggest that it might be worth to look at the Password Manager, maybe GeckoFX supports some way of accessing that?

Categories