private void TranslateEncryptionKey(ref WLANConfiguration config, string key, AuthenticationMode authMode, WEPStatus privacyMode) { if (privacyMode == WEPStatus.WEPEnabled) { if ((key.Length != 10) && (key.Length != 26)) { throw new ArgumentException("The encryption key for WEP must be either 10 or 26 characters"); } byte[] keyMaterial = HexStringToBytes(key); config.KeyMaterial = keyMaterial; config.CtlFlags |= WZCControl.WEPKPresent | WZCControl.WEPKXFormat; if (key.Length == 10) { config.CtlFlags |= WZCControl.WEPK40Bit; } config.KeyMaterial = EncryptKeyMaterial(keyMaterial); } else if ((privacyMode == WEPStatus.AESEnabled) || (privacyMode == WEPStatus.TKIPEnabled)) { config.KeyLength = key.Length; if ((config.KeyLength < 8) || (config.KeyLength > 63)) { throw new ArgumentException("The encryption key for WPA-PSK/TKIP must be either between 8 and 63"); } WZC.WZCPassword2Key(ref config, key); config.CtlFlags |= WZCControl.WEPKPresent | WZCControl.WEPKXFormat | WZCControl.ONEXEnabled; config.WPAMCastCipher = (int)WEPStatus.TKIPEnabled; config.KeyMaterial = EncryptKeyMaterial(config.KeyMaterial); } }
WZCPassword2Key( ref WLANConfiguration pwzcConfig, string cszPassword) { // Convert string from Unicode to Ascii. byte[] ascii = new byte[64]; byte[] src = Encoding.ASCII.GetBytes(cszPassword); Buffer.BlockCopy(src, 0, ascii, 0, src.Length); // Pass Ascii string and configuration structure // to the external call. WZCPassword2KeyCE(pwzcConfig.Data, ascii); }
internal AccessPoint(WLANConfiguration config) { if (config == null) { throw new ArgumentNullException("config"); } Name = config.SSID; macaddr = config.MACAddress; Privacy = config.Privacy; AuthenticationMode = config.AuthenticationMode; // jsm - Defect 352: Exposed keyIndex, keyMaterial, and EapolParams KeyIndex = config.KeyIndex; KeyMaterial = config.KeyMaterial; EapolParams = config.EapolParams; Channel = config.Configuration.Frequency; if (Channel > 14) { Channel = (config.Configuration.Frequency - 2407000) / 5000; } if (Channel < 0) { Channel = (int)((config.Configuration.Frequency - 2407) / 5); } // see if the rssi is in the HIWORD or LOWORD uint ssi = (uint)config.Rssi; if (((ssi & 0xFFFF0000) > 0) && ((ssi & 0xffff) == 0)) { // hiword SignalStrengthInDecibels = config.Rssi >> 16; } else if (ssi == 0) { SignalStrengthInDecibels = -99; } else { // loword SignalStrengthInDecibels = config.Rssi; } supportedrates = config.Rates; NetworkTypeInUse = config.NetworkTypeInUse; InfrastructureMode = config.InfrastructureMode; }
public WLANConfiguration Item(int index) { int offset = ConfigOffset; int currentSize = 0; // don't assume every element is equal size for (int i = 0; i <= index; i++) { currentSize = BitConverter.ToInt32(m_data.lpData, ConfigOffset); offset += currentSize; } WLANConfiguration config = new WLANConfiguration(currentSize); //jsm Bug 148 - BlockCopy was referencing data beyond data.lpData and causing ArgumentOutOfBounds Exception int bytesToCopyA = m_data.lpData.Length - (offset - currentSize); //this is the most we'll ever take int bytesToCopyB = bytesToCopyA <= currentSize ? bytesToCopyA : currentSize; Buffer.BlockCopy(m_data.lpData, offset - currentSize, config.Data, 0, bytesToCopyB); //Buffer.BlockCopy(data.lpData, offset - currentSize, config.Data, 0, currentSize); return(config); }
private WLANConfiguration MakeSSIDEntry(string SSID, bool bInfrastructure, string authKey, int keyIndex, AuthenticationMode authMode, WEPStatus privacyMode, EAPParameters eap) { WLANConfiguration config = new WLANConfiguration(); if (eap == null) { // setup default based on mode eap = new EAPParameters(); if (privacyMode == WEPStatus.WEPEnabled) { eap.EapFlags = EAPFlags.Disabled; } else if ((privacyMode == WEPStatus.AESEnabled) || (privacyMode == WEPStatus.TKIPEnabled)) { eap.EapType = EAPType.Default; eap.EapFlags = EAPFlags.Enabled; eap.Enable8021x = true; eap.AuthData = IntPtr.Zero; eap.AuthDataLen = 0; } } config.EapolParams = eap; config.MACAddress = this.GetPhysicalAddress().GetAddressBytes(); config.SSID = SSID; config.KeyIndex = keyIndex - 1; // WZC is 0-based, but wireless specs are 1-based config.InfrastructureMode = bInfrastructure ? InfrastructureMode.Infrastructure : InfrastructureMode.AdHoc; config.AuthenticationMode = authMode; config.Privacy = privacyMode; // translate key string into encrypted version if (authKey != null) { if (string.Compare(authKey, "auto", true) != 0) { TranslateEncryptionKey(ref config, authKey, authMode, privacyMode); } } return(config); }
public void SetItem(int index, WLANConfiguration wlc) { // Make sure data array is large enough to get element size. if ((ConfigOffset + sizeof(int)) <= m_data.lpData.Length) { // Figure out how big each element in the array // is. int elemSize = BitConverter.ToInt32(m_data.lpData, ConfigOffset); if (elemSize > wlc.Data.Length) { elemSize = wlc.Data.Length; } // Use the actual index to get the indicated element // in the Config list. Note that we use lpDataDirect, // so that we're copying to the internal array of our // data, not cloning it first, then copying to the clone // (which, of course, has no effect). Marshal.Copy(wlc.Data, 0, (IntPtr)((uint)(m_data.lpDataDirect) + ConfigOffset + index * (int)elemSize), elemSize); } }
/// <summary> /// Removes a network from the adapter's preferred list /// </summary> /// <param name="SSID">The SSID of the network to remove</param> public bool RemovePreferredNetwork(string SSID) { if ((SSID == null) || (SSID == string.Empty)) { throw new ArgumentException("Invalid SSID"); } // Get the current preferred list of SSID values. // First, we need to get an INTF_ENTRY for this adapter. INTF_ENTRY entry; int uret = WZC.QueryAdapter(this.Name, out entry); try { if (uret > 0) { // There is no list. Return false. return(false); } // Find the indicated item and remove it from // the list by creating a new list and setting // that as the preferred list. RAW_DATA rdold = entry.rdStSSIDList; WLANConfigurationList prefl = new WLANConfigurationList(rdold); // If there are no items in the list, return false. if (prefl.NumberOfItems == 0) { return(false); } // Build the new list. WLANConfigurationList prefnew = new WLANConfigurationList(prefl.NumberOfItems - 1); // Start at the top of the old list and copy items // from old to new, until we find the item to be // removed. int j = 0; int i; for (i = 0; i < prefl.NumberOfItems; i++) { WLANConfiguration item = prefl.Item(i); if (item.SSID == SSID) { // Skip to next item without incrementing // j. } else { prefnew.SetItem(j, item); j++; } } // Check for whether the item was found in the // list or not. If not, we don't reset the // wireless settings and instead return false. if (j == i) { return(false); } // Replace the old list with the new one // for the rest of the code. Entry #0 // is unset. prefl = prefnew; // Must now copy the new preferred list to the entry that // we will send with WZCSetInterface. entry.rdStSSIDList = prefl.rawData; // Finally, we are ready to select the new SSID as our // primary preferred connection. uret = WZC.SetAdapter(entry, INTF_FLAGS.INTF_ALL_FLAGS | INTF_FLAGS.INTF_PREFLIST); if (uret != 0) { throw new System.ComponentModel.Win32Exception(uret, "Unable to Set WZC Interface"); } } finally { entry.Dispose(); } return(uret <= 0); }
/// <summary> /// Sets wireless settings associated with a given interface and AP, adding to, rather than replacing the preferred list of APs. This version of the /// method is designed for the case where *all* of the options are going to be set, where no initial configuration exists at all and where existing /// items in the preferred list should be maintained. After this method executes, if it is successful, the specified SSID will be at the top, highest- /// priority, end of the preferred list. /// </summary> /// <param name="SSID"> /// Target SSID to connect /// </param> /// <param name="infrastructureMode"> /// Is infrastructure /// </param> /// <param name="authKey"> /// WEP key or WPA shared key string representing hex string (each two characters are converted to a single byte) /// </param> /// <param name="keyIndex"> /// Index of the WEP key. Valid values are 1-4 /// </param> /// <param name="authMode"> /// Authentication mode for the connection /// </param> /// <param name="privacyMode"> /// Privacy (encryption) mode for the connection /// </param> /// <param name="eapParams"> /// Parameters describing how the connection should use EAP to authenticate the user to the network /// </param> /// <returns>true if succeeded</returns> #endregion public bool AddPreferredNetwork(string SSID, bool infrastructureMode, string authKey, int keyIndex, AuthenticationMode authMode, WEPStatus privacyMode, EAPParameters eapParams) { if ((keyIndex <= 0) || (keyIndex > 4)) { throw new ArgumentException("Invalid keyIndex (must be between 1 and 4)"); } if ((SSID == null) || (SSID == string.Empty)) { throw new ArgumentException("Invalid SSID"); } // We may yet need to do some processing on the key, // if it is a WPA key. We need a WZC_WLAN_CONFIG // structure to pass to the WZC routine that does // this processing, however, so that is done below. // Get the current preferred list of SSID values. // First, we need to get an INTF_ENTRY for this adapter. INTF_ENTRY entry; int uret = WZC.QueryAdapter(this.Name, out entry); try { if (uret != 0) { throw new System.ComponentModel.Win32Exception(uret, "No preferred list found"); } // We need to push the indicated item to the top of the // preferred list. Once we do that and call WZCSetInterface // the connection will be established to that SSID. // The preferred list is in the rdStSSIDList field. RAW_DATA rdold = entry.rdStSSIDList; WLANConfigurationList prefl = new WLANConfigurationList(rdold); // Start at the bottom of the list. If the current item // is the one we want to copy, save it and start copying // items down in the list. WLANConfiguration targetItem = null; int i; for (i = (int)prefl.NumberOfItems - 1; i >= 0; i--) { targetItem = prefl.Item(i); if (targetItem.SSID == SSID) { break; } } // If we get no match for our SSID value, the item // is *not* in the preferred list, so we can // skip removing it. if (i >= 0) { // Now, copy the items before i on the // list down to cover i. This leaves // position 0 in the list as a copy of // position 1. We'll fill in position 0 // with the new most-preferred SSID. for (int j = i; j >= 1; j--) { // Copy old list item j-1 to new list item j. prefl.SetItem(j, prefl.Item(j - 1)); } } else { // The item was not in the list. We have // to expand the list and move all of // the original items down one spot. WLANConfigurationList prefl2 = new WLANConfigurationList(prefl.NumberOfItems + 1); for (int j = 0; j < (int)prefl.NumberOfItems; j++) { // Copy from old list to new list. prefl2.SetItem(j + 1, prefl.Item(j)); } // Replace the old list with the new one // for the rest of the code. Entry #0 // is unset. prefl = prefl2; } // Create a new item and put that in the list // at item #0, which presently exists but // doesn't mean anything (it's either a // totally blank item, if the SSID was not // in the list before the call, or it's the // old first item in the list). // Unlike the other SetWirelessSettings versions, // we *don't* get the current configuration here; // our parameters will set that. WLANConfiguration thisConfig = MakeSSIDEntry(SSID, infrastructureMode, authKey, keyIndex, authMode, privacyMode, eapParams); // OK, finally, set the item in the preferred // list according to the parameters to this // call. prefl.SetItem(0, thisConfig); // Must now copy the new preferred list to the entry that // we will sent with WZCSetInterface. entry.rdStSSIDList = prefl.rawData; // Finally, we are ready to select the new SSID as our // primary preferred connection. uret = WZC.SetAdapter(entry, INTF_FLAGS.INTF_PREFLIST); if (uret != 0) { throw new System.ComponentModel.Win32Exception(uret, "Unable to Set WZC Interface"); } } finally { entry.Dispose(); } return(true); }
/// <summary> /// Connects to an already-configured wireless network by SSID /// </summary> /// <param name="SSID"></param> /// <returns></returns> public bool ConnectToPreferredNetwork(string SSID) { INTF_ENTRY entry; int uret = WZC.QueryAdapter(this.Name, out entry); try { if (uret != 0) { throw new System.ComponentModel.Win32Exception(uret, "Unable to Query WZC Interface"); } // We need to push the indicated item to the top of the // preferred list. Once we do that and call WZCSetInterface // the connection will be established to that SSID. // The preferred list is in the rdStSSIDList field. RAW_DATA rdold = entry.rdStSSIDList; WLANConfigurationList prefl = new WLANConfigurationList(rdold); // Start at the bottom of the list. If the current item // is the one we want to copy, save it and start copying // items down in the list. WLANConfiguration targetItem = null; int i; for (i = (int)prefl.NumberOfItems - 1; i >= 0; i--) { targetItem = prefl.Item(i); if (targetItem.SSID == SSID) { break; } } // If we get no match for our SSID value, the item is *not* // in the preferred list. Return false. if (targetItem == null) { return(false); } // If the SSID is already first in the list, we're done. if (i > 0) { // Now, copy the rest of the items one place down in the // list. for (int j = i; j >= 1; j--) { // Copy old list item j-1 to new list item j. prefl.SetItem(j, prefl.Item(j - 1)); } // Put the saved target item in index 0 in the new list. prefl.SetItem(0, targetItem); } uret = WZC.SetAdapter(entry, INTF_FLAGS.INTF_ALL_FLAGS | INTF_FLAGS.INTF_PREFLIST); if (uret != 0) { throw new System.ComponentModel.Win32Exception(uret, "Unable to Set WZC Interface"); } } finally { entry.Dispose(); } return(true); }
/// <summary> /// The ProcessKey routine makes necessary modifications /// to the key material of a WPA key before it is passed /// to WZC routines. The processing done to it depends /// on how it was generated. /// </summary> /// <param name="kt"> /// The key type, indicating how the key material in /// the structure was originally generated /// </param> /// <param name="config"> /// The configuration being changed /// </param> /// <param name="passphrase"> /// For WPA-PSK passphrase type, the passphrase. /// </param> internal void ProcessKey(KeyType kt, ref WLANConfiguration config, string passphrase) { // Define fake key material for 'encrypting' the // keys. byte[] chFakeKeyMaterial = new byte[] { 0x56, 0x09, 0x08, 0x98, 0x4D, 0x08, 0x11, 0x66, 0x42, 0x03, 0x01, 0x67, 0x66 }; byte[] key; uint i; switch (kt) { case KeyType.WPAPassphrase: // We set this explicitly here. It was set // out of line in the NetUI code. config.Privacy = WEPStatus.TKIPEnabled; config.KeyLength = WLANConfiguration.WZCCTL_MAX_WEPK_MATERIAL; config.CtlFlags |= WZCControl.WEPKXFormat | WZCControl.ONEXEnabled | WZCControl.WEPKPresent; WZC.WZCPassword2Key(ref config, passphrase); // Note that, since the config structure doesn't // actually have a byte[] for key material, we // can't modify bytes of that 'array' in-place. key = config.KeyMaterial; for (i = 0; i < WLANConfiguration.WZCCTL_MAX_WEPK_MATERIAL; i++) { key[i] ^= chFakeKeyMaterial[(7 * i) % 13]; } config.KeyMaterial = key; config.EapolParams.EapFlags = EAPFlags.Enabled; config.EapolParams.EapType = EAPType.TLS; config.EapolParams.Enable8021x = true; // config.WPAMCastCipher = Ndis802_11Encryption2Enabled; break; case KeyType.WPABinary: // We set this explicitly here. It was set // out of line in the NetUI code. config.Privacy = WEPStatus.TKIPEnabled; config.KeyLength = WLANConfiguration.WZCCTL_MAX_WEPK_MATERIAL; config.CtlFlags |= WZCControl.WEPKPresent; // Note that, since the config structure doesn't // actually have a byte[] for key material, we // can't modify bytes of that 'array' in-place. key = config.KeyMaterial; for (i = 0; i < WLANConfiguration.WZCCTL_MAX_WEPK_MATERIAL; i++) { config.KeyMaterial[i] ^= chFakeKeyMaterial[(7 * i) % 13]; } config.KeyMaterial = key; config.EapolParams.EapFlags = EAPFlags.Enabled; config.EapolParams.EapType = EAPType.TLS; config.EapolParams.Enable8021x = true; // config.WPAMCastCipher = Ndis802_11Encryption2Enabled; break; } }
/// <summary> /// This routine is used, internally, to make entries /// for the preferred SSID list. It centralizes the /// mapping of key data into the structure, etc. /// </summary> /// <param name="SSID"> /// The SSID string for the new entry /// </param> /// <param name="bInfrastructure"> /// Set to true for infrastucture mode; false for /// ad hoc mode /// </param> /// <param name="Key"> /// WEP key material /// </param> /// <param name="keyIndex"> /// Key index. Valid values are 1-4 /// </param> /// <param name="authMode"> /// Authentication mode for the connection /// </param> /// <param name="privacyMode"> /// Privacy (encryption) mode for the connection /// </param> /// <returns> /// New WZC_WLAN_CONFIG object or null on failure /// </returns> private WLANConfiguration MakeSSIDEntry(string SSID, bool bInfrastructure, byte[] Key, int keyIndex, AuthenticationMode authMode, WEPStatus privacyMode) { WLANConfiguration thisConfig = new WLANConfiguration(); // Set the length. thisConfig.Length = thisConfig.Data.Length; // Set the MAC address. thisConfig.MACAddress = this.GetPhysicalAddress().GetAddressBytes(); // Set the SSID. thisConfig.SSID = SSID; // Save the privacy mode. thisConfig.Privacy = privacyMode; // Set the key index. Note that, since the 'first' // key is key #1 in all of the wireless specifications, // we have to decrement the value for WZC, which expects // it to be 0. thisConfig.KeyIndex = keyIndex - 1; // Proceed with configuration. byte[] arrKey = null; if (Key != null) { // Key size has already been checked (this // is an entry invariant). arrKey = Key.Clone() as byte[]; thisConfig.KeyLength = arrKey.Length; thisConfig.CtlFlags |= WZCControl.WEPKPresent | WZCControl.WEPKXFormat; if (arrKey.Length == 10) { thisConfig.CtlFlags |= WZCControl.WEPK40Bit; } byte[] chFakeKeyMaterial = new byte[] { 0x56, 0x09, 0x08, 0x98, 0x4D, 0x08, 0x11, 0x66, 0x42, 0x03, 0x01, 0x67, 0x66 }; for (int i = 0; i < arrKey.Length; i++) { arrKey[i] ^= chFakeKeyMaterial[(7 * i) % 13]; } thisConfig.KeyMaterial = arrKey; } else { // Clear the key material, as well as setting // the length to zero. byte[] key = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; thisConfig.KeyMaterial = key; thisConfig.KeyLength = 0; } thisConfig.AuthenticationMode = authMode; // ???? do the right thing, based on the mode. // If we have no key, we should probably set this to WEP Off. thisConfig.InfrastructureMode = bInfrastructure ? InfrastructureMode.Infrastructure : InfrastructureMode.AdHoc; return(thisConfig); }
internal unsafe void RefreshListPreferred(bool nearbyOnly) { // If the caller wants only the local preferred APs, // we check nearby list and, if the AP is not there, // we don't add it to our own preferred list. AccessPointCollection apc = null; if (nearbyOnly) { apc = m_adapter.NearbyAccessPoints; } // First step is to get the INTF_ENTRY for the adapter. // This includes the list of preferred SSID values. INTF_ENTRY ie = INTF_ENTRY.GetEntry(this.m_adapter.Name); // The field rdStSSIDList is the preferred list. It comes // in the form of a WZC_802_11_CONFIG_LIST. RAW_DATA rd = ie.rdStSSIDList; WLANConfigurationList cl = new WLANConfigurationList(rd); // Step through the list and add a new AP to the // collection for each entry. for (int i = 0; i < cl.NumberOfItems; i++) { WLANConfiguration c = cl.Item(i); //Debug.WriteLine(c.SSID); //for (int d = 1; d <= c.Data.Length; d++) //{ // Debug.Write(string.Format("{0:x2}{1}", c.Data[d - 1], (d%8 == 0) ? "\r\n" : " ")); //} //Debug.WriteLine(string.Empty); // If we're only showing those which we can hear, // see if the current SSID is in the nearby list. if (nearbyOnly) { // Find the currently active AP with the SSID // to match the one we're working on. AccessPoint activeAP = apc.FindBySSID(c.SSID); int ss; // If the given SSID is not in range, don't add // an entry to the list. if (activeAP != null) { // Update signal strength. ss = activeAP.SignalStrengthInDecibels; // Copy the signal strength value to the // NDIS_WLAN_BSSID structure for the // preferred list entry. c.Rssi = ss; // Create the AP instance and add it to the // preferred list. AccessPoint ap = new AccessPoint(c); m_aps.Add(ap); } } else { // Create the AP instance and add it to the // preferred list. The signal strength will // not necessarily be valid. AccessPoint ap = new AccessPoint(c); m_aps.Add(ap); } } // Dispose of INTF_ENTRY ie.Dispose(); }