1
- // Licensed to the .NET Foundation under one or more agreements.
1
+ // Licensed to the .NET Foundation under one or more agreements.
2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
// See the LICENSE file in the project root for more information.
4
4
13
13
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
14
14
//
15
15
16
+ using MS . Win32 ;
16
17
using System . Windows ;
17
- using System . Windows . Interop ;
18
18
using MS . Internal . Utility ;
19
- using MS . Win32 ;
20
19
using System . Runtime . InteropServices ;
21
- using MS . Internal . Documents . Application ;
22
20
23
21
namespace MS . Internal . AppModel
24
22
{
@@ -31,9 +29,6 @@ enum LaunchResult
31
29
32
30
internal static class AppSecurityManager
33
31
{
34
- #region Internal Methods
35
-
36
-
37
32
///<summary>
38
33
/// Safely launch the browser if you can.
39
34
/// If you can't demand unmanaged code permisison.
@@ -88,10 +83,7 @@ internal static LaunchResult SafeLaunchBrowserOnlyIfPossible(Uri originatingUri,
88
83
// For all other cases ( evil protocols etc).
89
84
// We will demand.
90
85
//
91
- // The check of IsInitialViewerNavigation is necessary because viewer applications will probably
92
- // need to call Navigate on the URI they receive, but we want them to be able to do it in partial trust.
93
- if ( ! BrowserInteropHelper . IsInitialViewerNavigation &&
94
- ( ( fIsTopLevel && isKnownScheme ) || fIsMailTo ) )
86
+ if ( ( fIsTopLevel && isKnownScheme ) || fIsMailTo )
95
87
{
96
88
if ( ! isKnownScheme && fIsMailTo ) // unnecessary if - but being paranoid.
97
89
{
@@ -145,285 +137,5 @@ the key used is (supposedly) HKCR\htmlfile\shell\opennew\ddeexec, and its value
145
137
throw new InvalidOperationException ( SR . FailToLaunchDefaultBrowser ,
146
138
new System . ComponentModel . Win32Exception ( /*uses the last Win32 error*/ ) ) ;
147
139
}
148
-
149
- #endregion Internal Methods
150
-
151
- #region Private Methods
152
-
153
- /// <summary>
154
- /// Returns the HTTP "Referer" header.
155
- /// </summary>
156
- /// <returns>returns a string containing one or more HTTP headers separated by \r\n; the string must also be terminated with a \r\n</returns>
157
- private static string GetHeaders ( Uri destinationUri )
158
- {
159
- string referer = BindUriHelper . GetReferer ( destinationUri ) ;
160
-
161
- if ( ! String . IsNullOrEmpty ( referer ) )
162
- {
163
- // The headers we pass in to IWebBrowser2.Navigate must
164
- // be terminated with a \r\n because the browser then
165
- // concatenates its own headers on to the end of that string.
166
- referer = $ "{ RefererHeader } { referer } \r \n ";
167
- }
168
-
169
- return referer ;
170
- }
171
-
172
- //
173
- // Functionally equivalent copy of Trident's CanNavigateToUrlWithZoneCheck function
174
- // Checks to see whether a navigation is considered a zone elevation.
175
- // Once a zone elevation is identified - calls into urlmon to check settings.
176
- //
177
- private static LaunchResult CanNavigateToUrlWithZoneCheck ( Uri originatingUri , Uri destinationUri )
178
- {
179
- LaunchResult launchResult = LaunchResult . NotLaunched ; // fail securely - assume this is the default.
180
- int targetZone = NativeMethods . URLZONE_LOCAL_MACHINE ; // fail securely this is the most priveleged zone
181
- int sourceZone = NativeMethods . URLZONE_INTERNET ; // fail securely this is the least priveleged zone.
182
- bool fEnabled = true ;
183
-
184
- EnsureSecurityManager ( ) ;
185
-
186
- // is this feature enabled ?
187
- fEnabled = UnsafeNativeMethods . CoInternetIsFeatureEnabled (
188
- NativeMethods . FEATURE_ZONE_ELEVATION ,
189
- NativeMethods . GET_FEATURE_FROM_PROCESS ) != NativeMethods . S_FALSE ;
190
-
191
- targetZone = MapUrlToZone ( destinationUri ) ;
192
-
193
- // Get source zone.
194
-
195
- // Initialize sourceUri to null so that source zone defaults to the least privileged zone.
196
- Uri sourceUri = null ;
197
-
198
- // If the MimeType is not a container, attempt to find sourceUri.
199
- // sourceUri should be null for Container cases, since it always assumes
200
- // the least privileged zone (InternetZone).
201
- if ( Application . Current . MimeType != MimeType . Document )
202
- {
203
- sourceUri = BrowserInteropHelper . Source ;
204
- }
205
- else if ( destinationUri . IsFile &&
206
- System . IO . Path . GetExtension ( destinationUri . LocalPath )
207
- . Equals ( DocumentStream . XpsFileExtension , StringComparison . OrdinalIgnoreCase ) )
208
- {
209
- // In this case we know the following:
210
- // 1) We are currently a Container
211
- // 2) The destination is a File and another Container
212
-
213
- // In this case we want to treat the destination as internet too so Container
214
- // can navigate to other Containers by passing zone checks
215
- targetZone = NativeMethods . URLZONE_INTERNET ;
216
- }
217
-
218
- if ( sourceUri != null )
219
- {
220
- sourceZone = MapUrlToZone ( sourceUri ) ;
221
- }
222
- else
223
- {
224
- // 2 potential ways to get here.
225
- // a) We aren't a fusion hosted app. Assume full-trust.
226
- // b) Some bug in hosting caused source Uri to be null.
227
- //
228
- // For a - we will say there is no cross-domain check.
229
- // b - we'll assume InternetZone, and use Source.
230
- return LaunchResult . Launched ;
231
- }
232
-
233
- // <Notes from Trident>
234
- // ------------------------------
235
- // Check if there is a zone elevation.
236
- // Custom zones would have a higher value that URLZONE_UNTRUSTED, so this solution isn't quite complete.
237
- // However, we don't know of any product actively using custom zones, so rolling this out.
238
- // INTRANET and TRUSTED are treated as equals.
239
- // ------------------------------
240
- // </Notes from Trident>
241
-
242
- //
243
- // Note the negative logic - it first sees to see something is *not* a zone elevation.
244
- //
245
- if (
246
- // Even if feature is disabled.
247
- // We still block navigation to local machine.
248
- // IF source zone is internet or restricted.
249
-
250
- ( ! fEnabled &&
251
- ( ( sourceZone != NativeMethods . URLZONE_INTERNET &&
252
- sourceZone != NativeMethods . URLZONE_UNTRUSTED ) ||
253
- targetZone != NativeMethods . URLZONE_LOCAL_MACHINE ) ) ||
254
-
255
- // If feature is enabled
256
- // It's not a zone elevation if
257
- // the zones are equal OR
258
- // the zones are both less than restricted and
259
- // the sourceZone is more trusted than Target OR
260
- // sourceZone and TargetZone are both Intranet or Trusted
261
- //
262
- // per aganjam - Intranet and Trusted are treated as equivalent
263
- // as it was a common scenario for IE. ( website on intranet points to trusted site).
264
- //
265
-
266
- ( fEnabled &&
267
- (
268
- sourceZone == targetZone ||
269
- (
270
- sourceZone <= NativeMethods . URLZONE_UNTRUSTED &&
271
- targetZone <= NativeMethods . URLZONE_UNTRUSTED &&
272
- (
273
- sourceZone < targetZone ||
274
- (
275
- ( sourceZone == NativeMethods . URLZONE_TRUSTED || sourceZone == NativeMethods . URLZONE_INTRANET ) &&
276
- ( targetZone == NativeMethods . URLZONE_TRUSTED || targetZone == NativeMethods . URLZONE_INTRANET )
277
- )
278
- )
279
- )
280
- ) ) )
281
- {
282
- // There is no zone elevation. You can launch away !
283
- return LaunchResult . Launched ;
284
- }
285
-
286
- launchResult = CheckBlockNavigation ( sourceUri ,
287
- destinationUri ,
288
- fEnabled ) ;
289
-
290
- return launchResult ;
291
- }
292
-
293
- ///<summary>
294
- /// Called when we suspect there is a zone elevation.
295
- /// Calls the Urlmon IsFeatureZoneElevationEnabled which may pop UI based on settings.
296
- /// functionally equivalent to the BlockNavigation: label in Trident's CanNavigateToUrlWithZoneCheck
297
- ///</summary>
298
- private static LaunchResult CheckBlockNavigation ( Uri originatingUri , Uri destinationUri , bool fEnabled )
299
- {
300
- if ( fEnabled )
301
- {
302
- if ( UnsafeNativeMethods . CoInternetIsFeatureZoneElevationEnabled (
303
- BindUriHelper . UriToString ( originatingUri ) ,
304
- BindUriHelper . UriToString ( destinationUri ) ,
305
- _secMgr ,
306
- NativeMethods . GET_FEATURE_FROM_PROCESS ) == NativeMethods . S_FALSE )
307
- {
308
- return LaunchResult . Launched ;
309
- }
310
- else
311
- {
312
- if ( IsZoneElevationSettingPrompt ( destinationUri ) )
313
- {
314
- // url action is query, and we got a "no" answer back.
315
- // we can assume user responded No.
316
- return LaunchResult . NotLaunchedDueToPrompt ;
317
- }
318
- else
319
- return LaunchResult . NotLaunched ;
320
- }
321
- }
322
- else
323
- {
324
- return LaunchResult . Launched ;
325
- }
326
- }
327
-
328
- // Is ZoneElevation setting set to prompt ?
329
- private static bool IsZoneElevationSettingPrompt ( Uri target )
330
- {
331
- Invariant . Assert ( _secMgr != null ) ;
332
-
333
- // Was this due to a prompt ?
334
-
335
- int policy = NativeMethods . URLPOLICY_DISALLOW ;
336
-
337
- unsafe
338
- {
339
- String targetString = BindUriHelper . UriToString ( target ) ;
340
-
341
- _secMgr . ProcessUrlAction ( targetString ,
342
- NativeMethods . URLACTION_FEATURE_ZONE_ELEVATION ,
343
- ( byte * ) & policy ,
344
- sizeof ( int ) ,
345
- null ,
346
- 0 ,
347
- NativeMethods . PUAF_NOUI ,
348
- 0 ) ;
349
- }
350
-
351
- return ( policy == NativeMethods . URLPOLICY_QUERY ) ;
352
- }
353
-
354
- private static void EnsureSecurityManager ( )
355
- {
356
- // IMPORTANT: See comments in header r.e. IInternetSecurityManager
357
-
358
- if ( _secMgr == null )
359
- {
360
- lock ( _lockObj )
361
- {
362
- if ( _secMgr == null ) // null check again - now that we're in the lock.
363
- {
364
- _secMgr = ( UnsafeNativeMethods . IInternetSecurityManager ) new InternetSecurityManager ( ) ;
365
-
366
- //
367
- // Set the Security Manager Site.
368
- // This enables any dialogs popped to be modal to our window.
369
- //
370
- _secMgrSite = new SecurityMgrSite ( ) ;
371
-
372
- _secMgr . SetSecuritySite ( ( NativeMethods . IInternetSecurityMgrSite ) _secMgrSite ) ;
373
- }
374
- }
375
- }
376
- }
377
-
378
-
379
-
380
- internal static void ClearSecurityManager ( )
381
- {
382
- if ( _secMgr != null )
383
- {
384
- lock ( _lockObj )
385
- {
386
- if ( _secMgr != null )
387
- {
388
- _secMgr . SetSecuritySite ( null ) ;
389
- _secMgrSite = null ;
390
- _secMgr = null ;
391
- }
392
- }
393
- }
394
- }
395
-
396
- internal static int MapUrlToZone ( Uri url )
397
- {
398
- EnsureSecurityManager ( ) ;
399
- int zone ;
400
- _secMgr . MapUrlToZone ( BindUriHelper . UriToString ( url ) , out zone , 0 ) ;
401
- return zone ;
402
- }
403
-
404
- [ ComImport , ComVisible ( false ) , Guid ( "7b8a2d94-0ac9-11d1-896c-00c04Fb6bfc4" ) ]
405
- internal class InternetSecurityManager
406
- {
407
- }
408
-
409
-
410
-
411
- #endregion Private Methods
412
-
413
- #region Private Fields
414
-
415
- private const string RefererHeader = "Referer: " ;
416
-
417
- private const string BrowserOpenCommandLookupKey = "htmlfile\\ shell\\ open\\ command" ;
418
-
419
- // Object to be used for locking. Using typeof(Util) causes an FxCop
420
- // violation DoNotLockOnObjectsWithWeakIdentity
421
- private static readonly object _lockObj = new object ( ) ;
422
-
423
- private static UnsafeNativeMethods . IInternetSecurityManager _secMgr ;
424
-
425
- private static SecurityMgrSite _secMgrSite ;
426
-
427
- #endregion Private Fields
428
140
}
429
141
}
0 commit comments