static WindowsFingerprint() { using (var sec = new SHA1CryptoServiceProvider()) { var sb = new StringBuilder(); ManagementObjectCollection collection = null; ManagementObjectSearcher searcher = null; searcher = new ManagementObjectSearcher("Select * From Win32_BIOS"); collection = searcher.Get(); foreach (ManagementObject mo in collection) { try { sb.Append(mo["SerialNumber"].ToString()); } catch { } try { sb.Append(mo["Manufacturer"].ToString()); } catch { } try { sb.Append(mo["Name"].ToString()); } catch { } } collection.Dispose(); searcher.Dispose(); searcher = new ManagementObjectSearcher("Select * From Win32_BaseBoard"); collection = searcher.Get(); foreach (ManagementObject mo in collection) { try { sb.Append(mo["SerialNumber"].ToString()); } catch { } try { sb.Append(mo["Manufacturer"].ToString()); } catch { } try { sb.Append(mo["Name"].ToString()); } catch { } } collection.Dispose(); searcher.Dispose(); byte[] bt = sec.ComputeHash(Encoding.UTF8.GetBytes(sb.ToString())); s_fingerPrint = BitConverter.ToString(bt).Replace("-", ""); LoggerUtil.GetAppWideLogger()?.Info("My fingerprint is {0}", s_fingerPrint); } }
/// <summary> /// Disables all outbound traffic from this device persistently until this action is /// explicitly reversed. /// </summary> public static void DisableInternet() { try { IntPtr engineHandle = IntPtr.Zero; var nullPtr = IntPtr.Zero; var result = NativeMethods.FwpmEngineOpen0(null, NativeConstants.RPC_C_AUTHN_WINNT, IntPtr.Zero, IntPtr.Zero, ref engineHandle); if (result != 0) { if (s_logger != null) { s_logger.Info("Failed to open filter engine handle: " + result); } return; } if (s_logger != null) { s_logger.Info("Filter engine handle opened successfully."); } FWPM_FILTER0_ fwpFilter = new FWPM_FILTER0_(); // Predefined windows GUID for outbound packet matching. var FWPM_LAYER_OUTBOUND_IPPACKET_V4_MANAGED = new Guid("1e5c9fae-8a84-4135-a331-950b54229ecd"); var FWPM_LAYER_OUTBOUND_IPPACKET_V4 = new GUID(); using (var ms = new MemoryStream(FWPM_LAYER_OUTBOUND_IPPACKET_V4_MANAGED.ToByteArray())) using (var br = new BinaryReader(ms)) { FWPM_LAYER_OUTBOUND_IPPACKET_V4.Data1 = br.ReadUInt32(); FWPM_LAYER_OUTBOUND_IPPACKET_V4.Data2 = br.ReadUInt16(); FWPM_LAYER_OUTBOUND_IPPACKET_V4.Data3 = br.ReadUInt16(); FWPM_LAYER_OUTBOUND_IPPACKET_V4.Data4 = br.ReadBytes(8); } fwpFilter.layerKey = FWPM_LAYER_OUTBOUND_IPPACKET_V4; using (var ms = new MemoryStream(INSTALLED_FILTER_ID.ToByteArray())) using (var br = new BinaryReader(ms)) { fwpFilter.filterKey.Data1 = br.ReadUInt32(); fwpFilter.filterKey.Data2 = br.ReadUInt16(); fwpFilter.filterKey.Data3 = br.ReadUInt16(); fwpFilter.filterKey.Data4 = br.ReadBytes(8); } // PERSIST OR BOOT? fwpFilter.flags = NativeConstants.FWPM_FILTER_FLAG_PERSISTENT; //fwpFilter.flags = NativeConstants.FWPM_FILTER_FLAG_BOOTTIME; fwpFilter.action.type = FWP_ACTION_TYPE.FWP_ACTION_BLOCK; fwpFilter.weight.type = FWP_DATA_TYPE_.FWP_EMPTY; // auto-weight. fwpFilter.numFilterConditions = 0; // this applies to all application traffic fwpFilter.displayData.name = "Citadel INet Block"; fwpFilter.displayData.description = "Enforce filter use for internet access."; ulong runtimeId = 0; result = NativeMethods.FwpmFilterAdd0(engineHandle, ref fwpFilter, IntPtr.Zero, ref runtimeId); if (result != 0) { if (s_logger != null) { s_logger.Info("Failed to add filter: " + result); } NativeMethods.FwpmEngineClose0(engineHandle); return; } if (s_logger != null) { s_logger.Info("Filter added successfully."); } result = NativeMethods.FwpmEngineClose0(engineHandle); if (result != 0) { if (s_logger != null) { s_logger.Info("Failed to close install handle: " + result); } return; } } catch (Exception e) { LoggerUtil.RecursivelyLogException(s_logger, e); } }
public AuthenticationResultObject Authenticate(string username, byte[] unencryptedPassword) { m_logger.Error(nameof(Authenticate)); AuthenticationResultObject ret = new AuthenticationResultObject(); // Enforce parameters are valid. Debug.Assert(StringExtensions.Valid(username)); if (!StringExtensions.Valid(username)) { throw new ArgumentException("Supplied username cannot be null, empty or whitespace.", nameof(username)); } Debug.Assert(unencryptedPassword != null && unencryptedPassword.Length > 0); if (unencryptedPassword == null || unencryptedPassword.Length <= 0) { throw new ArgumentException("Supplied password byte array cannot be null and must have a length greater than zero.", nameof(unencryptedPassword)); } // // Don't bother if we don't have internet. var hasInternet = NetworkStatus.Default.HasIpv4InetConnection || NetworkStatus.Default.HasIpv6InetConnection; if (hasInternet == false) { m_logger.Info("Aborting authentication attempt because no internet connection could be detected."); ret.AuthenticationResult = AuthenticationResult.ConnectionFailed; ret.AuthenticationMessage = "Aborting authentication attempt because no internet connection could be detected."; return(ret); } // Will be set if we get any sort of web exception. bool connectionFailure = false; // Try to send the device name as well. Helps distinguish between clients under the same account. string deviceName = string.Empty; byte[] formData = null; try { deviceName = Environment.MachineName; } catch { deviceName = "Unknown"; } try { var authRequest = GetApiBaseRequest(m_namedResourceMap[ServiceResource.GetToken]); // Build out username and password as post form data. We need to ensure that we mop // up any decrypted forms of our password when we're done, and ASAP. formData = System.Text.Encoding.UTF8.GetBytes(string.Format("email={0}&identifier={1}&device_id={2}", username, FingerPrint.Value, deviceName)); // Don't forget to the set the content length to the total length of our form POST data! authRequest.ContentLength = formData.Length; authRequest.ContentType = "application/x-www-form-urlencoded"; // XXX TODO - This is naughty, because we're putting our password into a string, so // it will linger in memory. However, it appears that the provided API doesn't give // us any choice. // KF NOTE: Why System.String is insecure. https://stackoverflow.com/questions/1166952/net-secure-memory-structures var encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + Encoding.UTF8.GetString(unencryptedPassword))); authRequest.Headers.Add("Authorization", "Basic " + encoded); // Grab the request stream so we can POST our login form data to it. using (var requestStream = authRequest.GetRequestStream()) { // Write and close. requestStream.Write(formData, 0, formData.Length); requestStream.Close(); } // Now that our login form data has been POST'ed, get a response. using (var response = (HttpWebResponse)authRequest.GetResponse()) { // Get the response code as an int so we can range check it. var code = (int)response.StatusCode; // Check if the response status code is outside the "success" range of codes // defined in HTTP. If so, we failed. We include redirect codes (3XX) as success, // since our server side will just redirect us if we're already authed. if (code > 199 && code < 299) { using (var tr = new StreamReader(response.GetResponseStream())) { AuthToken = tr.ReadToEnd(); UserEmail = username; } response.Close(); authRequest.Abort(); ret.AuthenticationResult = AuthenticationResult.Success; return(ret); } else { if (code == 401 || code == 403) { m_logger.Info("Authentication failed with code: {0}.", code); AuthToken = string.Empty; ret.AuthenticationResult = AuthenticationResult.Failure; return(ret); } else if (code > 399 && code < 499) { m_logger.Info("Authentication failed with code: {0}.", code); ret.AuthenticationResult = AuthenticationResult.Failure; return(ret); } } } } catch (WebException e) { // XXX TODO - Is this sufficient? if (e.Status == WebExceptionStatus.Timeout) { m_logger.Info("Authentication failed due to timeout."); connectionFailure = true; } try { using (WebResponse response = e.Response) { HttpWebResponse httpResponse = (HttpWebResponse)response; m_logger.Error("Error code: {0}", httpResponse.StatusCode); string errorText = string.Empty; using (Stream data = response.GetResponseStream()) using (var reader = new StreamReader(data)) { errorText = reader.ReadToEnd(); // GS Just cleans up the punctuation at the end of string string excpList = "$@*!."; var chRemoved = errorText .Select(ch => excpList.Contains(ch) ? (char?)null : ch); errorText = string.Concat(chRemoved.ToArray()) + "!"; m_logger.Error("Stream errorText: " + errorText); } int code = (int)httpResponse.StatusCode; if (code == 401 || code == 403) { AuthToken = string.Empty; } if (code > 399 && code < 499) { m_logger.Info("Authentication failed with code: {0}.", code); m_logger.Info("Athentication failure text: {0}", errorText); ret.AuthenticationMessage = errorText; ret.AuthenticationResult = AuthenticationResult.Failure; return(ret); } } } catch (Exception iex) { LoggerUtil.RecursivelyLogException(m_logger, iex); } // Log the exception. m_logger.Error(e.Message); m_logger.Error(e.StackTrace); } catch (Exception e) { while (e != null) { m_logger.Error(e.Message); m_logger.Error(e.StackTrace); e = e.InnerException; } m_logger.Info("Authentication failed due to a failure to process the request and response."); AuthToken = string.Empty; ret.AuthenticationResult = AuthenticationResult.Failure; return(ret); } finally { // This finally block is guaranteed TM to be run, so this is where we're going to // clean up any decrypted versions of the user's password held in memory. if (unencryptedPassword != null && unencryptedPassword.Length > 0) { Array.Clear(unencryptedPassword, 0, unencryptedPassword.Length); } if (formData != null && formData.Length > 0) { Array.Clear(formData, 0, formData.Length); } } m_logger.Info("Authentication failed due to a complete failure to process the request and response."); // If we had success, we should/would have returned by now. if (!connectionFailure) { AuthToken = string.Empty; } ret.AuthenticationResult = connectionFailure ? AuthenticationResult.ConnectionFailed : AuthenticationResult.Failure; return(ret); }
/// <summary> /// Enables outbound traffic on this device if previously blocked. /// </summary> public static void EnableInternet() { try { IntPtr engineHandle = IntPtr.Zero; var nullPtr = IntPtr.Zero; var result = NativeMethods.FwpmEngineOpen0(null, NativeConstants.RPC_C_AUTHN_WINNT, IntPtr.Zero, IntPtr.Zero, ref engineHandle); if (result != 0) { if (s_logger != null) { s_logger.Info("Failed to open filter engine handle: " + result); } return; } if (s_logger != null) { s_logger.Info("Filter engine handle opened successfully."); } var nativeGuid = new GUID(); using (var ms = new MemoryStream(INSTALLED_FILTER_ID.ToByteArray())) using (var br = new BinaryReader(ms)) { nativeGuid.Data1 = br.ReadUInt32(); nativeGuid.Data2 = br.ReadUInt16(); nativeGuid.Data3 = br.ReadUInt16(); nativeGuid.Data4 = br.ReadBytes(8); } result = NativeMethods.FwpmFilterDeleteByKey0(engineHandle, ref nativeGuid); if (result != 0) { if (s_logger != null) { s_logger.Info("Failed to delete old installed filter: " + result); } NativeMethods.FwpmEngineClose0(engineHandle); return; } if (s_logger != null) { s_logger.Info("Old handle uninstalled successfully successfully."); } result = NativeMethods.FwpmEngineClose0(engineHandle); if (result != 0) { if (s_logger != null) { s_logger.Info("Failed to close uninstall handle: " + result); } return; } } catch (Exception e) { LoggerUtil.RecursivelyLogException(s_logger, e); } }
private WebServiceUtil() { m_logger = LoggerUtil.GetAppWideLogger(); }