/////////////////////////////////////////////////////////////////////////////////////////////// private static ReturnCode WaitForSingleHandle( WaitHandle waitHandle, int milliseconds, bool userInterface, ref uint returnValue ) { ReturnCode code; Result error = null; code = WaitForSingleHandle( waitHandle, milliseconds, userInterface, ref returnValue, ref error); if (code != ReturnCode.Ok) { DebugOps.Complain(code, error); } if (traceWait) { TraceOps.DebugTrace(String.Format( "WaitForSingleHandle: exited, waitHandle = {0}, " + "milliseconds = {1}, userInterface = {2}, " + "returnValue = {3}, code = {4}, error = {5}", FormatOps.DisplayWaitHandle(waitHandle), milliseconds, userInterface, returnValue, code, FormatOps.WrapOrNull( true, true, error)), typeof(WindowOps).Name, TracePriority.NativeDebug); } return(code); }
/////////////////////////////////////////////////////////////////////// public static EventWaitHandle OpenEvent( string name ) { EventWaitHandle @event = null; try { @event = EventWaitHandle.OpenExisting(name); } catch (Exception e) { TraceOps.DebugTrace( e, typeof(ThreadOps).Name, TracePriority.HandleError); } #if DEBUG && VERBOSE TraceOps.DebugTrace(String.Format( "OpenEvent: {0}, name = {1}", (@event != null) ? "success" : "failure", FormatOps.WrapOrNull(name)), typeof(ThreadOps).Name, TracePriority.EventDebug); #endif return(@event); }
/////////////////////////////////////////////////////////////////////// public static ReturnCode GetCertificate( byte[] assemblyBytes, ref X509Certificate certificate, ref Result error ) { if (assemblyBytes != null) { try { certificate = new X509Certificate(assemblyBytes); return(ReturnCode.Ok); } catch (Exception e) { error = e; } } else { error = "invalid assembly bytes"; } TraceOps.DebugTrace(String.Format( "GetCertificate: query failure, error = {0}", FormatOps.WrapOrNull( true, true, error)), typeof(AssemblyOps).Name, TracePriority.SecurityError); return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// public void Report() { TraceOps.DebugTrace(String.Format( "Report: completed operation {0} in {1}", FormatOps.WrapOrNull(operation), this), typeof(PerformanceClientData).Name, TracePriority.TestDebug); }
/////////////////////////////////////////////////////////////////////// #region Private Methods private static bool IsUsable( string version ) { if (version == null) { TraceOps.DebugTrace( "IsUsable: invalid version string", typeof(NativeUtility).Name, TracePriority.NativeError); return(false); } if (version.IndexOf( optionUse32BitSizeT, StringOps.SystemStringComparisonType) == Index.Invalid) { TraceOps.DebugTrace(String.Format( "IsUsable: missing option {0}", FormatOps.WrapOrNull(optionUse32BitSizeT)), typeof(NativeUtility).Name, TracePriority.NativeError); return(false); } #if NATIVE_UTILITY_BSTR if (version.IndexOf( optionUseSysStringLen, StringOps.SystemStringComparisonType) == Index.Invalid) { TraceOps.DebugTrace(String.Format( "IsUsable: missing option {0}", FormatOps.WrapOrNull(optionUseSysStringLen)), typeof(NativeUtility).Name, TracePriority.NativeError); return(false); } #else if (version.IndexOf( optionUseSysStringLen, StringOps.SystemStringComparisonType) != Index.Invalid) { TraceOps.DebugTrace(String.Format( "IsUsable: mismatched option {0}", FormatOps.WrapOrNull(optionUseSysStringLen)), typeof(NativeUtility).Name, TracePriority.NativeError); return(false); } #endif return(true); }
/////////////////////////////////////////////////////////////////////// #region Background Error Reporter private static void ReportBackgroundError( Interpreter interpreter, string handlerName, string description0, string description1, ReturnCode code1, Result result1, int errorLine1, string description2, ReturnCode code2, Result result2, int errorLine2 ) { bool[] haveDescription = { !String.IsNullOrEmpty(description0), !String.IsNullOrEmpty(description1), !String.IsNullOrEmpty(description2) }; Result bgReport = String.Concat( haveDescription[0] ? String.Format(description0, FormatOps.WrapOrNull(handlerName)) : String.Empty, haveDescription[0] ? Environment.NewLine : String.Empty, haveDescription[1] ? String.Format("{0}{1}: {2}", haveDescription[0] ? BackgroundErrorDetailIndent : String.Empty, description1, ResultOps.Format(code1, result1, errorLine1, false, true)) : String.Empty, haveDescription[1] ? Environment.NewLine : String.Empty, haveDescription[2] ? String.Format("{0}{1}: {2}", haveDescription[0] ? BackgroundErrorDetailIndent : String.Empty, description2, ResultOps.Format(code2, result2, errorLine2, false, true)) : String.Empty, haveDescription[2] ? Environment.NewLine : String.Empty); // // TODO: Something else here as well? // if ((bgReport != null) && !String.IsNullOrEmpty(bgReport)) { DebugOps.Complain(interpreter, code2, bgReport); } }
/////////////////////////////////////////////////////////////////////// public static ReturnCode GetCertificate2( Assembly assembly, bool strict, ref X509Certificate2 certificate2, ref Result error ) { X509Certificate certificate = null; if (GetCertificate(assembly, ref certificate, ref error) == ReturnCode.Ok) { if (certificate != null) { try { certificate2 = new X509Certificate2(certificate); return(ReturnCode.Ok); } catch (Exception e) { error = e; } } else if (!strict) { certificate2 = null; return(ReturnCode.Ok); } else { error = "invalid certificate"; } } #if DEBUG if (!GlobalState.IsAssembly(assembly)) #endif { TraceOps.DebugTrace(String.Format( "GetCertificate2: assembly {0} query failure, error = {1}", FormatOps.WrapOrNull(assembly), FormatOps.WrapOrNull(true, true, error)), typeof(AssemblyOps).Name, TracePriority.SecurityError); } return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// public static ReturnCode GetHash( Assembly assembly, ref Hash hash, ref Result error ) { if (assembly != null) { Evidence evidence = assembly.Evidence; if (evidence != null) { try { foreach (object item in evidence) { if (item is Hash) { hash = (Hash)item; return(ReturnCode.Ok); } } error = "no hash found"; return(ReturnCode.Error); } catch (Exception e) { error = e; } } else { error = "invalid evidence"; } } else { error = "invalid assembly"; } TraceOps.DebugTrace(String.Format( "GetHash: assembly {0} query failure, error = {1}", FormatOps.WrapOrNull(assembly), FormatOps.WrapOrNull(true, true, error)), typeof(AssemblyOps).Name, TracePriority.SecurityError); return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// #region Private Methods private static ReturnCode IsStrongNameVerified( string fileName, bool force, ref bool returnValue, ref bool verified, ref Result error ) { if (String.IsNullOrEmpty(fileName)) { error = "invalid file name"; return(ReturnCode.Error); } #if WINDOWS && !MONO if (!PlatformOps.IsWindowsOperatingSystem()) { error = "not supported on this operating system"; return(ReturnCode.Error); } try { returnValue = UnsafeNativeMethods.StrongNameSignatureVerificationEx( fileName, force, ref verified); return(ReturnCode.Ok); } catch (Exception e) { error = e; } #else error = "not implemented"; #endif TraceOps.DebugTrace(String.Format( "IsStrongNameVerified: file {0} verification " + "failure, force = {1}, returnValue = {2}, " + "verified = {3}, error = {4}", FormatOps.WrapOrNull(fileName), force, returnValue, verified, FormatOps.WrapOrNull(error)), typeof(SecurityOps).Name, TracePriority.SecurityError); return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// #region Private Windows-Specific Methods #if WINDOWS private static ReturnCode WindowsIsAdministrator( ref bool administrator, ref Result error ) { try { // // NOTE: Are we running on Windows 2000 SP4 or higher? // if (PlatformOps.CheckVersion(PlatformID.Win32NT, 5, 0, 4, 0)) { // // HACK: Use a "documented" function for Windows // 2000 SP4+, Windows XP, and Vista (this // function used to be undocumented). // administrator = UnsafeNativeMethods.IsUserAnAdmin(); } else { // // HACK: Use a different undocumented function for // Windows NT and Windows 2000 RTM to SP3. // uint reserved2 = 0; administrator = UnsafeNativeMethods.IsNTAdmin( 0, ref reserved2); } return(ReturnCode.Ok); } catch (Exception e) { error = e; } TraceOps.DebugTrace(String.Format( "WindowsIsAdministrator: administrator = {0}, error = {1}", administrator, FormatOps.WrapOrNull(error)), typeof(SecurityOps).Name, TracePriority.SecurityError); return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// public static ReturnCode GetCertificate( Assembly assembly, ref X509Certificate certificate, ref Result error ) { if (assembly != null) { Module module = assembly.ManifestModule; if (module != null) { try { certificate = module.GetSignerCertificate(); return(ReturnCode.Ok); } catch (Exception e) { error = e; } } else { error = "invalid module"; } } else { error = "invalid assembly"; } #if DEBUG if (!GlobalState.IsAssembly(assembly)) #endif { TraceOps.DebugTrace(String.Format( "GetCertificate: assembly {0} query failure, error = {1}", FormatOps.WrapOrNull(assembly), FormatOps.WrapOrNull(true, true, error)), typeof(AssemblyOps).Name, TracePriority.SecurityError); } return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// public static ReturnCode GetCertificate2( string fileName, ref X509Certificate2 certificate2, ref Result error ) { X509Certificate certificate = null; if (GetCertificate(fileName, ref certificate, ref error) == ReturnCode.Ok) { if (certificate != null) { try { certificate2 = new X509Certificate2(certificate); return(ReturnCode.Ok); } catch (Exception e) { error = e; } } else { error = "invalid certificate"; } } #if DEBUG if (!PathOps.IsSameFile( Interpreter.GetActive(), fileName, GlobalState.GetAssemblyLocation())) #endif { TraceOps.DebugTrace(String.Format( "GetCertificate2: file {0} query failure, error = {1}", FormatOps.WrapOrNull(fileName), FormatOps.WrapOrNull(true, true, error)), typeof(CertificateOps).Name, TracePriority.SecurityError); } return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// #region Public Certificate Methods public static ReturnCode GetCertificate( string fileName, ref X509Certificate certificate, ref Result error ) { if (!String.IsNullOrEmpty(fileName)) { try { certificate = X509Certificate.CreateFromSignedFile( fileName); return(ReturnCode.Ok); } catch (Exception e) { error = e; } } else { error = "invalid file name"; } #if DEBUG if (!PathOps.IsSameFile( Interpreter.GetActive(), fileName, GlobalState.GetAssemblyLocation())) #endif { TraceOps.DebugTrace(String.Format( "GetCertificate: file {0} query failure, error = {1}", FormatOps.WrapOrNull(fileName), FormatOps.WrapOrNull(true, true, error)), typeof(CertificateOps).Name, TracePriority.SecurityError); } return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// #region Private Unix-Specific Methods #if UNIX private static ReturnCode UnixIsAdministrator( ref bool administrator, ref Result error ) { try { administrator = (UnsafeNativeMethods.getuid() == 0); return(ReturnCode.Ok); } catch (Exception e) { error = e; } TraceOps.DebugTrace(String.Format( "UnixIsAdministrator: administrator = {0}, error = {1}", administrator, FormatOps.WrapOrNull(error)), typeof(SecurityOps).Name, TracePriority.SecurityError); return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// public static bool TryGetAppSetting( string name, /* in */ out string value, /* out */ ref Result error /* out */ ) { Initialize(); lock (syncRoot) /* TRANSACTIONAL */ { NameValueCollection appSettings = GetAppSettings(); if (appSettings == null) { value = null; error = "invalid application settings"; return(false); } string stringValue = appSettings.Get(name); if (stringValue == null) { value = null; error = String.Format( "setting {0} not found", FormatOps.WrapOrNull(name)); return(false); } value = stringValue; return(true); } }
/////////////////////////////////////////////////////////////////////// public static ReturnCode SetExclusive( bool exclusive, ref Result error ) { lock (syncRoot) /* TRANSACTIONAL */ { bool wasExclusive = IsExclusive(); if (exclusive != wasExclusive) { UpdateOps.exclusive = exclusive; TraceOps.DebugTrace(String.Format( "SetExclusive: exclusive mode {0}", exclusive ? "enabled" : "disabled"), typeof(UpdateOps).Name, TracePriority.SecurityDebug); return(ReturnCode.Ok); } else { error = String.Format( "already {0}", exclusive ? "exclusive" : "non-exclusive"); } } TraceOps.DebugTrace(String.Format( "SetExclusive: exclusive = {0}, error = {1}", exclusive, FormatOps.WrapOrNull(error)), typeof(UpdateOps).Name, TracePriority.SecurityError); return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// private static void DumpSetup( Interpreter interpreter, string friendlyName, string baseDirectory, string packagePath, bool useBasePath, AppDomainSetup appDomainSetup ) { StringPairList list = new StringPairList(); AddInfo(appDomainSetup, list, DetailFlags.DebugTrace); TraceOps.DebugTrace(String.Format( "DumpSetup: interpreter = {0}, friendlyName = {1}, " + "baseDirectory = {2}, packagePath = {3}, " + "useBasePath = {4}, appDomainSetup = {5}", FormatOps.InterpreterNoThrow(interpreter), FormatOps.WrapOrNull(friendlyName), FormatOps.WrapOrNull(baseDirectory), FormatOps.WrapOrNull(packagePath), useBasePath, list), typeof(AppDomainOps).Name, TracePriority.SecurityDebug); }
/////////////////////////////////////////////////////////////////////// public static ReturnCode VerifyChain( Assembly assembly, X509Certificate2 certificate2, X509VerificationFlags verificationFlags, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, ref Result error ) { if (certificate2 != null) { try { X509Chain chain = X509Chain.Create(); if (chain != null) { X509ChainPolicy chainPolicy = chain.ChainPolicy; if (chainPolicy != null) { // // NOTE: Setup the chain policy settings as specified // by the caller. // chainPolicy.VerificationFlags = verificationFlags; chainPolicy.RevocationMode = revocationMode; chainPolicy.RevocationFlag = revocationFlag; if (chain.Build(certificate2)) { return(ReturnCode.Ok); } else { StringList list = new StringList(); if (chain.ChainStatus != null) { foreach (X509ChainStatus status in chain.ChainStatus) { list.Add( status.Status.ToString(), status.StatusInformation); } if (assembly != null) { error = String.Format( "assembly {0}: {1}", FormatOps.WrapOrNull(assembly), list.ToString()); } else { error = list; } } else { if (assembly != null) { error = String.Format( "assembly {0}: invalid chain status", FormatOps.WrapOrNull(assembly)); } else { error = "invalid chain status"; } } } } else { if (assembly != null) { error = String.Format( "assembly {0}: invalid chain policy", FormatOps.WrapOrNull(assembly)); } else { error = "invalid chain policy"; } } } else { if (assembly != null) { error = String.Format( "assembly {0}: invalid chain", FormatOps.WrapOrNull(assembly)); } else { error = "invalid chain"; } } } catch (Exception e) { if (assembly != null) { error = String.Format( "assembly {0}: {1}", FormatOps.WrapOrNull(assembly), e); } else { error = e; } } } else { if (assembly != null) { error = String.Format( "assembly {0}: invalid certificate", FormatOps.WrapOrNull(assembly)); } else { error = "invalid certificate"; } } return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// public static ReturnCode Wait( Interpreter interpreter, long microseconds, bool timeout, bool strict, ref Result error ) /* THREAD-SAFE */ { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { int waitCount; if ((waitCount = interpreter.EnterWait()) > 0) { if (microseconds == 0) { #if WINFORMS // // NOTE: If necessary, process all Windows messages // from the queue. // if (!strict) { code = WindowOps.ProcessEvents( interpreter, ref error); } if (code == ReturnCode.Ok) #endif { // // NOTE: Yield to other running threads. This // also gives them an opportunity to cancel // the script in progress on this thread. // HostOps.Yield(); } } else { // // NOTE: Keep track of how many iterations through // the loop we take. // int iterations = 0; // // HACK: Account for our processing overhead; use half // of the requested delay. // int milliseconds = ConversionOps.ToInt( PerformanceOps.GetMilliseconds(microseconds) / WaitDivisor); if (milliseconds < 0) { milliseconds = 0; } if (milliseconds > WaitMaximumSleepTime) { milliseconds = WaitMaximumSleepTime; } // // NOTE: For more precise timing, use the high-resolution // CPU performance counter. // long startCount = PerformanceOps.GetCount(); // // BUGFIX: Make sure the slop time does not exceed the // actual wait. // long slopMicroseconds = Math.Min( microseconds / WaitSlopDivisor, WaitSlopMinimumTime); // // NOTE: Delay for approximately the specified number of // microseconds, optionally timing out if we cannot // obtain the interpreter lock before the time period // elapses. // while (((code = Interpreter.EventReady(interpreter, timeout ? milliseconds : _Timeout.Infinite, ref error)) == ReturnCode.Ok) && !PerformanceOps.HasElapsed(startCount, microseconds, slopMicroseconds)) { #if WINFORMS if (!strict) { code = WindowOps.ProcessEvents(interpreter, ref error); if (code != ReturnCode.Ok) { break; } } #endif HostOps.SleepOrMaybeComplain(interpreter, milliseconds); iterations++; } long stopCount = PerformanceOps.GetCount(); double elapsedMicroseconds = PerformanceOps.GetMicroseconds( startCount, stopCount, 1); TraceOps.DebugTrace(String.Format( "Wait: code = {0}, iterations = {1}, microseconds = {2}, " + "elapsedMicroseconds = {3}, sleepMilliseconds = {4}, " + "slopMicroseconds = {5}, differenceMicroseconds = {6}, " + "waitCount = {7}, error = {8}", code, iterations, microseconds, elapsedMicroseconds, milliseconds, slopMicroseconds, elapsedMicroseconds - (double)microseconds, waitCount, FormatOps.WrapOrNull(true, true, error)), typeof(EventOps).Name, TracePriority.EventDebug); } /* IGNORED */ interpreter.ExitWait(); } else { error = "wait subsystem locked"; code = ReturnCode.Error; } } else { error = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////////////////////////////// #region Public Methods public static IDictionary <long, string> Parse( /* 0.0 */ string text, bool complex, bool space, bool sort, ref Result error ) { if (text == null) { error = "invalid flags"; return(null); } StringBuilder name = StringOps.NewStringBuilder(); StringBuilder value = StringOps.NewStringBuilder(); IDictionary <long, IDictionary <char, long> > perKeyFlags = new Dictionary <long, IDictionary <char, long> >(); bool haveName = false; bool open = false; long nonComplexKey = DefaultKey; long key = nonComplexKey; for (int index = 0; index < text.Length; index++) { char character = text[index]; switch (character) { case Characters.OpenBrace: { if (!complex) { error = String.Format( "unexpected open brace at index {0}, simple-only mode", index); return(null); } if (open) { error = String.Format( "unexpected open brace at index {0}, already open", index); return(null); } // // NOTE: This code cannot be reached. // // if (name.Length > 0) // { // error = String.Format( // "unexpected name at index {0}", // index); // // return null; // } // if (value.Length > 0) { if (!Union(perKeyFlags, value, nonComplexKey, false)) { // // NOTE: This code cannot be reached. // error = String.Format( "union of flags failed at index {0} for key {1}", index, nonComplexKey); return(null); } value.Length = 0; } open = true; break; } case Characters.CloseBrace: { if (!complex) { error = String.Format( "unexpected close brace at index {0}, simple-only mode", index); return(null); } if (!open) { error = String.Format( "unexpected close brace at index {0}, already closed", index); return(null); } if (!haveName) { error = String.Format( "unexpected close brace at index {0}, name incomplete", index); return(null); } if (name.Length == 0) { error = String.Format( "unexpected close brace at index {0}, name missing", index); return(null); } if (!HexadecimalNameToKey(name.ToString(), ref key)) { // // NOTE: This code cannot be reached. // error = String.Format( "invalid name {0}, must be a hexadecimal long integer", FormatOps.WrapOrNull(name)); return(null); } if (!Union(perKeyFlags, value, key, false)) { // // NOTE: This code cannot be reached. // error = String.Format( "union of flags failed at index {0} for key {1}", index, key); return(null); } name.Length = 0; value.Length = 0; haveName = false; open = false; break; } default: { if (haveName || !open) { if (space && Parser.IsWhiteSpace(character)) { continue; } if (!CharIsValidValue(character)) { error = String.Format( "invalid value character '{0}' at index {1}", character, index); return(null); } value.Append(character); } else { if (space && Parser.IsWhiteSpace(character)) { continue; } if (character == NameSepatator) { haveName = true; continue; } if (!CharIsValidName(character)) { error = String.Format( "invalid name character '{0}' at index {1}", character, index); return(null); } name.Append(character); if (name.Length == NameLength) { haveName = true; } } break; } } } if (complex && open) { error = "close brace expected"; return(null); } // // NOTE: This code cannot be reached. // // if (name.Length > 0) // { // error = String.Format( // "unexpected name at index {0}", // text.Length); // // return null; // } // if (value.Length > 0) { if (!Union(perKeyFlags, value, nonComplexKey, false)) { // // NOTE: This code cannot be reached. // error = String.Format( "union of flags failed at index {0} for key {1}", text.Length, nonComplexKey); return(null); } /* value.Length = 0; */ } // // NOTE: Return the merged flags dictionary to the caller, sorted // if necessary. // return(Merge(perKeyFlags, sort)); }
/////////////////////////////////////////////////////////////////////// #region Public Web Upload Methods #region Upload Data Methods public static ReturnCode UploadData( Interpreter interpreter, IClientData clientData, Uri uri, string method, byte[] rawData, bool trusted, ref byte[] bytes, ref Result error ) { bool wasTrusted = UpdateOps.IsTrusted(); TraceOps.DebugTrace(String.Format( "UploadData: interpreter = {0}, clientData = {1}, " + "uri = {2}, method = {3}, rawData = {4}, trusted = {5}, " + "wasTrusted = {6}", FormatOps.InterpreterNoThrow(interpreter), FormatOps.WrapOrNull(clientData), FormatOps.WrapOrNull(uri), FormatOps.WrapOrNull(method), FormatOps.WrapOrNull(rawData), trusted, wasTrusted), typeof(WebOps).Name, TracePriority.NetworkDebug); ReturnCode code = trusted ? wasTrusted ? ReturnCode.Ok : UpdateOps.SetTrusted(trusted, ref error) : ReturnCode.Ok; if (code == ReturnCode.Ok) { try { try { Result localError = null; using (WebClient webClient = CreateClient( interpreter, "UploadData", clientData, ref localError)) { if (webClient != null) { bytes = webClient.UploadData( uri, method, rawData); return(ReturnCode.Ok); } else if (localError != null) { error = localError; } else { error = "could not create web client"; } } } catch (Exception e) { error = e; } } finally { if (trusted && !wasTrusted) { ReturnCode untrustCode; Result untrustError = null; untrustCode = UpdateOps.SetTrusted( false, ref untrustError); if (untrustCode != ReturnCode.Ok) { DebugOps.Complain( interpreter, untrustCode, untrustError); } } } } return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// private static ReturnCode IsFileTrusted( string fileName, IntPtr fileHandle, bool userInterface, bool userPrompt, bool revocation, bool install, ref int returnValue, ref Result error ) { if (String.IsNullOrEmpty(fileName)) { error = "invalid file name"; return(ReturnCode.Error); } #if WINDOWS if (!PlatformOps.IsWindowsOperatingSystem()) { error = "not supported on this operating system"; return(ReturnCode.Error); } try { UnsafeNativeMethods.WINTRUST_FILE_INFO file = new UnsafeNativeMethods.WINTRUST_FILE_INFO(); file.cbStruct = (uint)Marshal.SizeOf( typeof(UnsafeNativeMethods.WINTRUST_FILE_INFO)); file.pcwszFilePath = fileName; file.hFile = fileHandle; file.pgKnownSubject = IntPtr.Zero; IntPtr pFile = IntPtr.Zero; try { pFile = Marshal.AllocCoTaskMem((int)file.cbStruct); if (pFile != IntPtr.Zero) { Marshal.StructureToPtr(file, pFile, false); UnsafeNativeMethods.WINTRUST_DATA winTrustData = new UnsafeNativeMethods.WINTRUST_DATA(); winTrustData.cbStruct = (uint)Marshal.SizeOf( typeof(UnsafeNativeMethods.WINTRUST_DATA)); winTrustData.pPolicyCallbackData = IntPtr.Zero; winTrustData.pSIPClientData = IntPtr.Zero; winTrustData.dwUIChoice = userInterface && userPrompt ? UnsafeNativeMethods.WTD_UI_ALL : UnsafeNativeMethods.WTD_UI_NONE; winTrustData.fdwRevocationChecks = revocation ? UnsafeNativeMethods.WTD_REVOKE_WHOLECHAIN : UnsafeNativeMethods.WTD_REVOKE_NONE; winTrustData.dwUnionChoice = UnsafeNativeMethods.WTD_CHOICE_FILE; winTrustData.pFile = pFile; winTrustData.dwStateAction = UnsafeNativeMethods.WTD_STATEACTION_IGNORE; winTrustData.hWVTStateData = IntPtr.Zero; winTrustData.pwszURLReference = null; winTrustData.dwProvFlags = UnsafeNativeMethods.WTD_SAFER_FLAG; winTrustData.dwUIContext = install ? UnsafeNativeMethods.WTD_UICONTEXT_INSTALL : UnsafeNativeMethods.WTD_UICONTEXT_EXECUTE; IntPtr hWnd = userInterface ? WindowOps.GetInteractiveHandle() : INVALID_HANDLE_VALUE; Guid actionId = GetActionId(); returnValue = UnsafeNativeMethods.WinVerifyTrust( hWnd, actionId, ref winTrustData); return(ReturnCode.Ok); } else { error = "out of memory"; } } finally { if (pFile != IntPtr.Zero) { Marshal.FreeCoTaskMem(pFile); pFile = IntPtr.Zero; } } } catch (Exception e) { error = e; } #else error = "not implemented"; #endif TraceOps.DebugTrace(String.Format( "IsFileTrusted: file {0} trust failure, " + "userInterface = {1}, revocation = {2}, " + "install = {3}, returnValue = {4}, error = {5}", FormatOps.WrapOrNull(fileName), userInterface, revocation, install, returnValue, FormatOps.WrapOrNull(error)), typeof(SecurityOps).Name, TracePriority.SecurityError); return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// public static ReturnCode UploadDataAsync( Interpreter interpreter, IClientData clientData, StringList arguments, CallbackFlags callbackFlags, Uri uri, string method, byte[] rawData, ref Result error ) { TraceOps.DebugTrace(String.Format( "UploadDataAsync: interpreter = {0}, clientData = {1}, " + "arguments = {2}, callbackFlags = {3}, uri = {4}, " + "method = {5}, rawData = {6}", FormatOps.InterpreterNoThrow(interpreter), FormatOps.WrapOrNull(clientData), FormatOps.WrapOrNull(true, true, arguments), FormatOps.WrapOrNull(callbackFlags), FormatOps.WrapOrNull(uri), FormatOps.WrapOrNull(method), FormatOps.WrapOrNull(rawData)), typeof(WebOps).Name, TracePriority.NetworkDebug); ReturnCode code = ReturnCode.Ok; WebClient webClient = null; try { ICallback callback = CommandCallback.Create( MarshalFlags.Default, callbackFlags, ObjectFlags.Callback, ByRefArgumentFlags.None, interpreter, null, null, arguments, ref error); if (callback != null) { try { Result localError = null; webClient = CreateClient( interpreter, "UploadDataAsync", clientData, ref localError); if (webClient != null) { callback.ClientData = new ClientData( new AnyTriplet <WebClient, Uri, IAnyPair <string, byte[]> >( webClient, uri, new AnyPair <string, byte[]>(method, rawData))); webClient.UploadDataCompleted += new UploadDataCompletedEventHandler( UploadDataAsyncCompleted); /* NO RESULT */ webClient.UploadDataAsync( uri, method, rawData, callback); } else if (localError != null) { error = localError; code = ReturnCode.Error; } else { error = "could not create web client"; code = ReturnCode.Error; } } catch (Exception e) { error = e; code = ReturnCode.Error; } } else { code = ReturnCode.Error; } } finally { if ((code != ReturnCode.Ok) && (webClient != null)) { ReturnCode disposeCode; Result disposeError = null; disposeCode = ObjectOps.TryDispose( webClient, ref disposeError); if (disposeCode != ReturnCode.Ok) { DebugOps.Complain( interpreter, disposeCode, disposeError); } } } return(code); }
/////////////////////////////////////////////////////////////////////// public ReturnCode Load( ref int loaded, ref Result error ) { CheckDisposed(); lock (syncRoot) /* TRANSACTIONAL */ { try { if (module != IntPtr.Zero) { return(ReturnCode.Ok); } if (String.IsNullOrEmpty(fileName)) { error = "invalid file name"; return(ReturnCode.Error); } int lastError; module = NativeOps.LoadLibrary( fileName, out lastError); /* throw */ if (NativeOps.IsValidHandle(module)) { Interlocked.Increment(ref loaded); return(ReturnCode.Ok); } else { error = String.Format( "LoadLibrary({1}) failed with error {0}: {2}", lastError, FormatOps.WrapOrNull(fileName), NativeOps.GetDynamicLoadingError(lastError)); } } catch (Exception e) { error = e; } finally { // // NOTE: If the module handle is valid then we know // the module was loaded successfully -OR- was // already loaded; therefore, increment the // reference count. // if (module != IntPtr.Zero) { Interlocked.Increment(ref referenceCount); } } } return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// #region Private Trusted Certificate Support Methods private static bool IsTrustedCertificate( X509Certificate certificate ) { bool result = false; string name = null; // // NOTE: Make sure the certificate public key matches what // we expect it to be for our own software updates. // if (certificate != null) { // // NOTE: Grab the public key of the certificate. // byte[] certificatePublicKey = certificate.GetPublicKey(); if ((certificatePublicKey != null) && (certificatePublicKey.Length > 0)) { lock (syncRoot) /* TRANSACTIONAL */ { // // NOTE: Compare the public key of the certificate to // one(s) that we trust for our software updates. // if (!result && (PublicKey1 != null) && (PublicKey1.Length > 0) && ArrayOps.Equals(certificatePublicKey, PublicKey1)) { name = "PublicKey1"; result = true; } if (!result && (PublicKey2 != null) && (PublicKey2.Length > 0) && ArrayOps.Equals(certificatePublicKey, PublicKey2)) { name = "PublicKey2"; result = true; } if (!result && (PublicKey3 != null) && (PublicKey3.Length > 0) && ArrayOps.Equals(certificatePublicKey, PublicKey3)) { name = "PublicKey3"; result = true; } if (!result && (PublicKey4 != null) && (PublicKey4.Length > 0) && ArrayOps.Equals(certificatePublicKey, PublicKey4)) { name = "PublicKey4"; result = true; } // // NOTE: Compare the public key of the certificate to // the auxiliary one that we trust for use by // third-party applications and plugins. // if (!result && (PublicKey5 != null) && (PublicKey5.Length > 0) && ArrayOps.Equals(certificatePublicKey, PublicKey5)) { name = "PublicKey5"; result = true; } } } } // // NOTE: Report this trust result to any trace listeners. // TraceOps.DebugTrace(String.Format( "IsTrustedCertificate: certificate = {0}, name = {1}, " + "result = {2}", FormatOps.Certificate(certificate, false, true), FormatOps.WrapOrNull(name), result), typeof(UpdateOps).Name, TracePriority.SecurityDebug); return(result); }
/////////////////////////////////////////////////////////////////////// public static ReturnCode SetTrusted( bool trusted, ref Result error ) { lock (syncRoot) /* TRANSACTIONAL */ { bool wasTrusted = IsTrusted(); if (trusted != wasTrusted) { try { #if !MONO if (!ShouldUseLegacyCertificatePolicy()) { // // NOTE: When using the .NET Framework, use the // newer certification validation callback // interface. // if (trusted) { AddServerCertificateValidationCallback(); } else { RemoveServerCertificateValidationCallback(); } TraceOps.DebugTrace(String.Format( "SetTrusted: {0} " + "RemoteCertificateValidationCallback", trusted ? "added" : "removed"), typeof(UpdateOps).Name, TracePriority.SecurityDebug); } else #endif { // // NOTE: When running on Mono, fallback to the // "obsolete" CertificatePolicy property. // if (trusted) { EnableLegacyCertificatePolicy(); } else { DisableLegacyCertificatePolicy(); } TraceOps.DebugTrace(String.Format( "SetTrusted: {0} CertificatePolicy", trusted ? "overridden" : "restored"), typeof(UpdateOps).Name, TracePriority.SecurityDebug); } return(ReturnCode.Ok); } catch (Exception e) { error = e; } } else { error = String.Format( "already {0}", trusted ? "trusted" : "untrusted"); } } TraceOps.DebugTrace(String.Format( "SetTrusted: trusted = {0}, error = {1}", trusted, FormatOps.WrapOrNull(error)), typeof(UpdateOps).Name, TracePriority.SecurityError); return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// public static string GetValue( string variable, ConfigurationFlags flags ) /* THREAD-SAFE */ { string prefixedVariable = null; // // NOTE: The default return value is null, which means that the // value is not available and/or not set. // string value = null; // // NOTE: If the variable name is null or empty, return the default // value (null) instead of potentially throwing an exception // later. // if (String.IsNullOrEmpty(variable)) { goto done; } // // NOTE: Try to get the variable name without the package name // prefix? // bool unprefixed = FlagOps.HasFlags( flags, ConfigurationFlags.Unprefixed, true); // // NOTE: Try to get the variable name prefixed by package name // first? // if (FlagOps.HasFlags(flags, ConfigurationFlags.Prefixed, true)) { prefixedVariable = String.Format( EnvVarFormat, EnvVarPrefix, variable); } // // NOTE: Does the caller want to check the environment variables? // if (FlagOps.HasFlags(flags, ConfigurationFlags.Environment, true)) { // // NOTE: Try the variable name prefixed by our package name // first? // if ((prefixedVariable != null) && (value == null)) { value = CommonOps.Environment.GetVariable(prefixedVariable); } // // NOTE: Failing that, just try for the variable name? // if (unprefixed && (value == null)) { value = CommonOps.Environment.GetVariable(variable); } } #if CONFIGURATION // // NOTE: Does the caller want to check the loaded AppSettings? // if (FlagOps.HasFlags(flags, ConfigurationFlags.AppSettings, true)) { // // NOTE: Try the variable name prefixed by our package name // first? // if ((prefixedVariable != null) && (value == null)) { value = ConfigurationOps.GetAppSetting(prefixedVariable); } // // NOTE: Failing that, just try for the variable name? // if (unprefixed && (value == null)) { value = ConfigurationOps.GetAppSetting(variable); } } #endif // // NOTE: If necessary, expand any contained environment variables. // if (!String.IsNullOrEmpty(value) && FlagOps.HasFlags(flags, ConfigurationFlags.Expand, true)) { value = CommonOps.Environment.ExpandVariables(value); } done: // // NOTE: Output diagnostic message about the configuration value // request. // if (DefaultVerbose || FlagOps.HasFlags(flags, ConfigurationFlags.Verbose, true)) { TraceOps.DebugTrace(String.Format( "GetValue: variable = {0}, prefixedVariable = {1}, " + "value = {2}, defaultVerbose = {3}, flags = {4}", FormatOps.WrapOrNull(variable), FormatOps.WrapOrNull(prefixedVariable), FormatOps.WrapOrNull(value), DefaultVerbose, FormatOps.WrapOrNull(flags)), typeof(GlobalConfiguration).Name, TracePriority.StartupDebug); } return(value); }
/////////////////////////////////////////////////////////////////////// private static bool LoadNativeLibrary( Interpreter interpreter ) { lock (syncRoot) /* TRANSACTIONAL */ { if (nativeModule != IntPtr.Zero) { return(true); } try { string fileName = GetNativeLibraryFileName(interpreter); if (!String.IsNullOrEmpty(fileName)) { TraceOps.DebugTrace(String.Format( "LoadNativeLibrary: using file name {0}", FormatOps.WrapOrNull(fileName)), typeof(NativeUtility).Name, TracePriority.NativeDebug); } else { TraceOps.DebugTrace(String.Format( "LoadNativeLibrary: file name {0} is invalid", FormatOps.WrapOrNull(fileName)), typeof(NativeUtility).Name, TracePriority.NativeError); return(false); } // // NOTE: Check if the native library file name actually // exists. If not, do nothing and return failure // after tracing the issue. // if (!File.Exists(fileName)) { TraceOps.DebugTrace(String.Format( "LoadNativeLibrary: file name {0} does not exist", FormatOps.WrapOrNull(fileName)), typeof(NativeUtility).Name, TracePriority.NativeError); return(false); } // // BUGFIX: Stop loading "untrusted" native libraries // when running with a "trusted" core library. // if (!RuntimeOps.ShouldLoadNativeLibrary(fileName)) { TraceOps.DebugTrace(String.Format( "LoadNativeLibrary: file name {0} is untrusted", FormatOps.WrapOrNull(fileName)), typeof(NativeUtility).Name, TracePriority.NativeError); return(false); } int lastError; nativeModule = NativeOps.LoadLibrary( fileName, out lastError); /* throw */ if (nativeModule != IntPtr.Zero) { InitializeNativeDelegates(true); Result error = null; if (SetNativeDelegates(ref error)) { nativeFileName = fileName; TraceOps.DebugTrace( "LoadNativeLibrary: successfully loaded", typeof(NativeUtility).Name, TracePriority.NativeDebug); return(true); } else { TraceOps.DebugTrace(String.Format( "LoadNativeLibrary: file name {0} delegate " + "setup error: {1}", FormatOps.WrapOrNull(fileName), error), typeof(NativeUtility).Name, TracePriority.NativeError); /* IGNORED */ UnloadNativeLibrary(interpreter); } } else { TraceOps.DebugTrace(String.Format( "LoadLibrary({1}) failed with error {0}: {2}", lastError, FormatOps.WrapOrNull(fileName), NativeOps.GetDynamicLoadingError(lastError).Trim()), typeof(NativeUtility).Name, TracePriority.NativeError); } } catch (Exception e) { TraceOps.DebugTrace( e, typeof(NativeUtility).Name, TracePriority.NativeError); } return(false); } }
/////////////////////////////////////////////////////////////////////// public static void UnsetValue( string variable, ConfigurationFlags flags ) /* THREAD-SAFE */ { string prefixedVariable = null; // // NOTE: If the variable name is null or empty, do nothing. // if (String.IsNullOrEmpty(variable)) { goto done; } // // NOTE: Try to set the variable name without the package name // prefix? // bool unprefixed = FlagOps.HasFlags( flags, ConfigurationFlags.Unprefixed, true); // // NOTE: Set the variable name prefixed by package name instead? // if (FlagOps.HasFlags(flags, ConfigurationFlags.Prefixed, true)) { prefixedVariable = String.Format( EnvVarFormat, EnvVarPrefix, variable); } #if CONFIGURATION // // NOTE: Does the caller want to remove the loaded AppSettings? // if (FlagOps.HasFlags(flags, ConfigurationFlags.AppSettings, true)) { // // NOTE: Try to unset the requested AppSettings value(s). // if (unprefixed) { ConfigurationOps.UnsetAppSetting(variable); } if (prefixedVariable != null) { ConfigurationOps.UnsetAppSetting(prefixedVariable); } } #endif // // NOTE: Does the caller want to remove the environment variables? // if (FlagOps.HasFlags(flags, ConfigurationFlags.Environment, true)) { // // NOTE: Try to unset the requested environment variable(s). // if (unprefixed) { CommonOps.Environment.UnsetVariable(variable); } if (prefixedVariable != null) { CommonOps.Environment.UnsetVariable(prefixedVariable); } } done: // // NOTE: Output diagnostic message about the configuration value // request. // if (DefaultVerbose || FlagOps.HasFlags(flags, ConfigurationFlags.Verbose, true)) { TraceOps.DebugTrace(String.Format( "UnsetValue: variable = {0}, prefixedVariable = {1}, " + "defaultVerbose = {2}, flags = {3}", FormatOps.WrapOrNull(variable), FormatOps.WrapOrNull(prefixedVariable), DefaultVerbose, FormatOps.WrapOrNull(flags)), typeof(GlobalConfiguration).Name, TracePriority.StartupDebug); } }