Пример #1
0
        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);
            }
        }
Пример #2
0
        /// <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);
        }
Пример #4
0
        /// <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();
 }