views:

2483

answers:

7

I've developed a .net 3.0 application, which is deployed using clickonce.

I'd like to move from full trust to partial trust to ease deployment.

I've tried the "Calculate Permissions" tool in the "Security" tab of my project under visual studio, and the answer is quite clear :

---------------------------
Microsoft Visual Studio
---------------------------
This application requires full trust to run correctly.

However, I've not been able to figure out why full trust is required. I've tried to change the security settings to "partial trust", but the application raises a SecurityException immediately upon launch :

System.Security.SecurityException   {"Request failed.", Action= "System.Security.Permissions.SecurityAction.LinkDemand"
   at MyNameSpace.Program.Main(String[] args)
   at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
   at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
   at System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel)
   at System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()
   at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
   at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext)
   at System.Activator.CreateInstance(ActivationContext activationContext)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.runTryCode(Object userData)
   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

My software probably doesn't need full trust (I only connect to a webserver using https, and access the filesystem only upon user request, for importation/exportation purposes)

How can I figure out why my application requires full trust?

A: 

Hrm, just a guess, but is it running off of a network share? .NET seems to assign trust based on the location the code is being run from. If it's from anywhere but your local hard drive then you're going to have security issues.

Jeffrey Cameron
I think you are looking at my question in a wrong way. Running the file locally instead of from a netshare would change the zone, thus elevating the default permissions. I don't want my program to require any kind of elevation to run!
Brann
Ahh it appears I did misunderstand, sorry Brann
Jeffrey Cameron
A: 

Without seeing the code for your application, it's impossible to tell. There is something that is requiring full trust in your app that you might have overlooked (perhaps a dependency?).

casperOne
Isn't there a way to mimick the CLR logic (which is able to determine that I need full trust immediatly upon lanch) ?And isn't it possible to tell the CLR to launch the program anwyay, and to raise exceptions when my code requires some elevatio, if it ever does?
Brann
A: 

The exception message is telling you why you can't run with partial trust:

System.Security.Permissions.SecurityAction.LinkDemand

If you copy and paste that into Google, you will find several relevant articles on MSDN that might help you to discover why your application requires full trust.

dave-ilsw
+5  A: 

It seems my problem is caused by the fact that my assembly is strongly signed.

Quoted from msdn

In strong-named assemblies, a LinkDemand is applied to all publicly accessible methods, properties, and events therein to restrict their use to fully trusted callers. To disable this feature, you must apply the AllowPartiallyTrustedCallersAttributeattribute.

I'm adding the needed attribute to my assembly, and I'll let you know how things turn out :

[assembly:AllowPartiallyTrustedCallers]

Update : I've added the attribute to my assemblies, but I'm also using some .net assemblies.

Not all .net assemblies can be used by partially trusted assemblies (here's a list), namely, WCF assemblies (ie System.ServiceModel) is not on the list

However, Microsoft states that it's possible to use WCF in a partial trust environment (see here)

I've tried to remove all the unneeded assemblies from my references, I've used the AllowPartiallyTrustedCallers in all my assemblies, and I'm still stucked...

Brann
Brann, you should use the comment and edit features, rather than repeatedly adding answers. I recommend merging your three answers into this single answer, and note the times of each edit/update before the content of that update.
jrista
@jrista : those three answers are different (and point to different directions), so I don't really see how the fact that all three were posted by me is relevant ...
Brann
+2  A: 

Microsoft has a tool called permcalc which analyse an assembly and produces a detailed xml output file which looks like this :

<Type Name="MyClass">
<Method Sig="instance void .ctor()">
<Demand>
<PermissionSet version="1" class="System.Security.PermissionSet">
  <IPermission version="1" class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Unrestricted="true" /> 
  <IPermission version="1" class="System.Security.Permissions.ReflectionPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Unrestricted="true" /> 
...
Brann
A: 

Your stack-trace does not show the type of permission being demanded.

AllowPartiallyTrustedCallers won't help you in this case. It should be specified on the calling target, e.g. when some partially trusted code calls into your trusted assembly. In your situation you should examine whether your app calls into assemblies that do not have this attribute defined. If yes then your app will need to run in full-trust and won't work in partial trust at all (this is how CAS is enforced and is by design.)

Otherwise use permcalc. It will show you the permissions that should then be enabled in the security settings of the project. However I'm not sure if after including all those perms you will still have "partial trust" or rather full trust with a few stripped-down permissions. This is due to the fact that partial trust is very restrictive (open security.config and look at the enabled permissions!), as far as I know WebPermission is not there (which is needed to send http requests), same with FileIOPermission.

liggett78
regarding AllowPartiallyTrustedCallers, that's what I did, but I feel like the msdn doc is not up to date (I've posted in this thread a contradiction between the msdn doc and a msdn sample..)
Brann
Partial trust is not so restrictive that you say. When using partial trust, the elevation level depends on your zone, or can be customized, so you can have FileIOPermission if you need it (although FileDialogPermission is probably enough in most cases).
Brann
Sure you can customize permissions, but default partial trust has like 6-7 of them (LocalIntranet a couple of more).
liggett78
MSDN docs for APTC is alright. Please re-read my answer. APTC should be applied to the call TARGET, not the calling (e.g. your) assembly.That's why when you call into assembly A from .NET that does not have APTC set, you're out of luck, because runtime ensures that your partial trust code can't call
liggett78
...fully trusted .NET code in GAC. This is what MSDN means by LinkDemand on every public method etc.
liggett78
I applied the attribute to my own assemblies because my main assembly calls my other assemblies (so those assemblies should have the attribute applied, shouldn't they?)
Brann
Dunno, the point of APTC is security "switch" from partial to full trust. Say an assembly in GAC is capable of sending mails, but partial trust has no SocketPermission.If you call into this fully-trusted assembly (that is decorated with APTC), then you'll be able to open sockets and send mails...
liggett78
...but in your situation all assemblies are private to the app and thus all run in partial trust, I guess.
liggett78
A: 

Adding the requirePermission='false' attribute in the app.config's configsections helps a lot :

 <sectionGroup name="system.net" type="System.Net.Configuration.NetSectionGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <section requirePermission="false" name="defaultProxy" type="System.Net.Configuration.DefaultProxySection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
    </sectionGroup>

It made the trick for me !

Brann