/// <summary> /// Generates user data xml. /// </summary> /// <param name="authMethod">authMethod</param> /// <returns>Complete user data xml as string.</returns> public static string CreateUserDataXml(EapConfig.AuthenticationMethod authMethod) { _ = authMethod ?? throw new ArgumentNullException(nameof(authMethod)); using var userCert = authMethod.ClientCertificateAsX509Certificate2(); XElement newUserData = new XElement(nsEHUC + "EapHostUserCredentials", new XAttribute(XNamespace.Xmlns + "eapCommon", nsEC), new XAttribute(XNamespace.Xmlns + "baseEap", nsBEMUC), new XElement(nsEHUC + "EapMethod", new XElement(nsEC + "Type", (int)authMethod.EapType), new XElement(nsEC + "AuthorId", authMethod.EapType == EapType.TTLS ? 311 : 0) //new XElement(nsEC + "AuthorId", "67532") // geant link ), new XElement(nsEHUC + "Credentials", new XAttribute(XNamespace.Xmlns + "eapuser", nsEUP), new XAttribute(XNamespace.Xmlns + "xsi", nsXSI), new XAttribute(XNamespace.Xmlns + "baseEap", nsBEUP), new XAttribute(XNamespace.Xmlns + "MsPeap", nsMPUP), new XAttribute(XNamespace.Xmlns + "MsChapV2", nsMCUP), new XAttribute(XNamespace.Xmlns + "eapTtls", nsTTLS), EapUserData( authMethod.ClientUserName, authMethod.ClientPassword, outerIdentity: string.IsNullOrEmpty(authMethod.ClientOuterIdentity) ? authMethod.ClientUserName : authMethod.ClientOuterIdentity , authMethod.EapType, authMethod.InnerAuthType, userCert?.Thumbprint ) ) ); // returns xml as string if not null return(newUserData != null?newUserData.ToString() : ""); }
/// <summary> /// Generates wireless profile xml. Content depends on the EAP type. /// </summary> /// <param name="authMethod">authMethod</param> /// <param name="withSSID">TODO</param> /// <param name="withHS20">If to install as hotspot 2.0 profile or not (separate profile from normal eap)</param> /// <param name="strictMode">If the server cannot be verified, allow asking the user to allow it anyway</param> /// <returns>A tuple containing the profile name and the WLANProfile XML data</returns> private static ValueTuple <string, string> CreateProfileXml( EapConfig.AuthenticationMethod authMethod, string withSSID = null, bool withHS20 = false, bool strictMode = true, bool hiddenNetwork = false) { if (withHS20 && withSSID != null) { throw new ArgumentException("Cannot configure with both SSID and HS20"); // we can, but the result is confusing } if (withSSID != null && !authMethod.IsSSIDSupported) { throw new ArgumentException("Cannot configure " + nameof(authMethod) + " with SSID because it doesn't support SSID configuration"); } if (withHS20 && !authMethod.IsHS20Supported) { throw new ArgumentException("Cannot configure " + nameof(authMethod) + " with Hotspot 2.0 because it doesn't support Hotspot 2.0 configuration"); } if (withSSID != null && !authMethod.SSIDs.Any((ssid) => withSSID == ssid)) { throw new ArgumentException("The ssid is not used by the authentication method"); } // Decide the profile name, which is the unique identifier for this profile string profileName = null; if (withHS20 && string.IsNullOrWhiteSpace(profileName)) { profileName = authMethod.EapConfig.InstitutionInfo.DisplayName; } if (withSSID != null && string.IsNullOrWhiteSpace(profileName)) { profileName = withSSID; } if (string.IsNullOrWhiteSpace(profileName)) { foreach (string preferredSSID in PREFERRED_SSIDS) { if (authMethod.SSIDs.Contains(preferredSSID)) { profileName = preferredSSID; break; } } } if (string.IsNullOrWhiteSpace(profileName) && authMethod.SSIDs.Any()) { profileName = authMethod.SSIDs.First(); } if (string.IsNullOrWhiteSpace(profileName) && authMethod.ConsortiumOIDs.Any()) { profileName = authMethod.ConsortiumOIDs.First(); } if (withHS20 && authMethod.SSIDs.Contains(profileName)) { // since profileName is the unique identifier of the profile. avoid collisions with the profiles per ssid profileName += " via Passpoint"; // GEANT convention as fallback } // Construct XML document XElement ssidConfigElement; XElement hs2Element, roamingConsortiumElement; XElement newProfile = new XElement(nsWLAN + "WLANProfile", new XElement(nsWLAN + "name", profileName), ssidConfigElement = new XElement(nsWLAN + "SSIDConfig"), hs2Element = new XElement(nsWLAN + "Hotspot2", new XElement(nsWLAN + "DomainName", authMethod.EapConfig.InstitutionInfo.InstId), //new XElement(nsWLAN + "NAIRealm", ), // A list of Network Access Identifier (NAI) Realm identifiers. Entries in this list are usually of the form user@domain. // new XElement(nsWLAN + "Network3GPP", ), // A list of Public Land Mobile Network (PLMN) IDs. roamingConsortiumElement = new XElement(nsWLAN + "RoamingConsortium") // A list of Organizationally Unique Identifiers (OUI) assigned by IEEE. ), new XElement(nsWLAN + "connectionType", "ESS"), new XElement(nsWLAN + "connectionMode", "auto"), new XElement(nsWLAN + "autoSwitch", "false"), new XElement(nsWLAN + "MSM", new XElement(nsWLAN + "security", new XElement(nsWLAN + "authEncryption", new XElement(nsWLAN + "authentication", "WPA2"), new XElement(nsWLAN + "encryption", "AES"), // CredentialApplicability.MinRsnProto is forced to not be TKIP new XElement(nsWLAN + "useOneX", "true") ), new XElement(nsWLAN + "PMKCacheMode", "enabled"), new XElement(nsWLAN + "PMKCacheTTL", "720"), new XElement(nsWLAN + "PMKCacheSize", "128"), new XElement(nsWLAN + "preAuthMode", "disabled"), new XElement(nsOneX + "OneX", new XElement(nsOneX + "authMode", "user"), new XElement(nsOneX + "EAPConfig", CreateEapConfiguration( authMethod.EapType, authMethod.InnerAuthType, authMethod.ClientOuterIdentity, authMethod.ServerNames, authMethod.CertificateAuthoritiesAsX509Certificate2() .Where(cert => cert.Subject == cert.Issuer) .Select(cert => cert.Thumbprint).ToList(), strictMode) ) ) ) ) ); // Add all the supported SSIDs, if we have none, assume we're doing HS20 if we got this far and nobody stopped us var ssids = authMethod.SSIDs.Any() ? authMethod.SSIDs : new List <string> { "#Passpoint" }; ssids.ForEach(ssid => // This element supports up to 25 SSIDs in the v1 namespace and up to additional 10000 SSIDs in the v2 namespace. ssidConfigElement.Add( new XElement(nsWLAN + "SSID", //new XElement(nsWLAN + "hex", ssidHex), new XElement(nsWLAN + "name", ssid) ) )); ssidConfigElement.Add( new XElement(nsWLAN + "nonBroadcast", hiddenNetwork ? "true" : "false") ); // Populate the Hs2 field authMethod.ConsortiumOIDs.ForEach(oui => roamingConsortiumElement.Add( new XElement(nsWLAN + "OUI", oui) )); // ... or remove it if it shouldn't be there if (!withHS20) { hs2Element.Remove(); } // return xml as string return(profileName, newProfile.ToString()); }
public static ValueTuple <string, string> CreateHS20ProfileXml(EapConfig.AuthenticationMethod authMethod) => CreateProfileXml(authMethod, withHS20: true, strictMode: true);
public static ValueTuple <string, string> CreateSSIDProfileXml(EapConfig.AuthenticationMethod authMethod, string ssid) => CreateProfileXml(authMethod, withSSID: ssid, strictMode: true);
/// <summary> /// Constructs a EapAuthMethodInstaller /// </summary> /// <param name="authMethod">The authentification method to attempt to install</param> public EapAuthMethodInstaller(EapConfig.AuthenticationMethod authMethod) { AuthMethod = authMethod ?? throw new ArgumentNullException(paramName: nameof(authMethod)); }