How do I access enviroment variables in a WPF Browser application - c#

HI am interested in obtaining getting the Enviroment.UserName in a Wpf Browser application.
But I have run into a SecurityException. What changes should I make obtain the enviroment variables.
Update:
the application is run on my company intranet.

The Environment.UserName property getter asks for a demand on the EnvironmentPermission.Read permission. Yeah, that's going to blow in a sand-boxed environment such as created to run code securely inside a browser. A web app has no business obtaining privileged information such as the user name. It is half-way to being able to crack the user's login credentials, albeit that the password would be a bit harder to guess.
No can do, if you want the user to reveal her user name then you are going to have to ask her politely. And do make sure that's a name that you provide, don't expect her to reveal the name she uses to logon to her machine.

Related

Authenticating users using Windows logon

I want to try and avoid forcing users to logon to use my applications, so I am wondering if there is a secure was I can use a Windows authenticated user?
I can't see this working, personally, because at some point my application is going to have to send the users login username and grab the permissions.
Assuming this connection is encrypted...I'm guessing a malicious user could still decompile my application, change the code to impersonate a user and recompile. Even if I obfuscated the code, I am sure there must exist methods around this.
Any ideas?

Impersonate a user

We are developing a C# .NET windows service.
Our service is running under the system account, and we are trying to impersonate the logged in user USER.
The impersonation works ok, i.e. when calling System.Security.Principal.WindowsIdentity.GetCurrent() after the impersonation we get the correct user 'USER'.
The problem is that when we try to access the user profile we do not get the expected results.
One example is accessing the registry CURRENT_USER. We get an access denied error.
When using a third party function, which we assume uses the registry in part, we get the details for the "real" (prior to impersonation) user.
Also when callingEnvironment.ExpandEnvironmentVariables("%TEMP%") we get the system profile instead of the logged-in user profile.
Is there a way to completly impersonate a different user?.
I know we can use LoadUserProfile to get a specific user profile, but this is not good for us, because we are running a third party dll that uses the current user profile.
Our impersonation code is base on this
As you have discovered, impersonation won't set up HKEY_CURRENT_USER or the environment.
This is because the impersonation token is per-thread, and HKCU and environment are per-process.
If you need to access the user's usual environment, you will need to use HKEY_USERS\SID and the impersonated user's SID e.g. HKEY_USERS\S-1-5-21-12345678-12345678-12345678-1234 for example. Call LoadUserProfile to ensure the key is loaded. (If it is supposed to be the the currently logged-on user it should be loaded already, so you should probably not do that, but check it exists and return an error if not).
You can also work out what their usual environment would be, because this is under the key "Environment" within the HKCU. You merely need to combine that with the system environment.
If the third party DLL actually requires HKCU and the environment to be set up correctly, you will need to create a process within the user's logon session to host the DLL, and send the results of whatever operation back somehow. If only the environment is required, you can create a child process and set the environment manually.
However you haven't said why you want to do this. It sounds like you have settled on this as a portion of the solution to a larger problem. If possible I'd recommend that you see if there is a way to do what you need without getting the user's environment or HKCU at all.
Why can't the DLL just run directly in the user's own session? Why is a service required at all? Can you re-architect your solution so there is a user-mode part which runs in the logon session and hosts the third-party DLL, and it communicates with the service so that the service only does what is absolutely required?
I notice that the code doesn't call LoadUserProfile, so the users profile isn't loaded.
Note in the remarks of that function, HKEY_CURRENT_USER still isn't replaced though.
I think you can solve this issue (before calling the third party DLL) by calling RegOverridePredefKey.
Note that a lot of voodoo might be involved in getting this all working right - I'd try to make sure the override happens as late as possible before the third party call, and is reverted as soon as possible afterwards (hoping that this is all a single call to the library).
As an alternative, I'd seriously try looking around for a different 3rd party offering that doesn't require all of this jumping through hoops.

Log into application with Windows Network Authentication

Not sure if there is another thread with the answer, but tried looking and nothing stood out.
Our company runs Windows Server 2008 R2 and as part of the normal login procedure you type your username and password. IT sets the domain when you get your PC so that is all good. So, when you open IE, the intranet sight detects that you are person XXX YYY and then logs you into the site automatically as the right person.
Now is there any way that I can do the same with an application written in C# or VB.NET. I.e., I would like the user to not have to log in as they have already done so during Windows log in, and then use the application as the indicidual user. This is for loggin purposes and specific rights for each group. (like admins or guests etc)
You can use Environment.UserName to get the username of the current user, but you will still need to store some permissions pertaining to this user somewhere.
You can make people a member of an Active Directory group and then grant them permissions based on which group they are a member of but this will require that you (or your application) has the ability to create AD groups and move people in and out of them. If you need some pointers to this then I can find some code.

How can I demand access to a Windows share in a .NET thick-client app?

We have a thick-client that needs to access resources on a share where a client may not be logged on. The client might be on a Windows domain or it could be a mixed environment without a domain, so the user would have to log on to the server locally. In the past, one work around was to create a shortcut on the user's desktop to the share, which opens Windows Explorer, which opens a password prompt that grants or denies access to the share. How can I get the user to signon to the share without relying on Windows Explorer? What does Windows Explorer do that I can have my app do to demand access to the share?
I have read Access files from network share in c# web app, but I am doing this in a WinForms app and want it to be interactive. I have also read How to prompt for a Password, but that code just prompts for strings from the user rather than invoking the UI that demands and grants access to the share. I would rather not have my app know the user's password as much as trigger the OS to demand access for the network resource.
You could take a look at the Win32 API CredUIPromptForCredentials ( or CredUIPromptForWindowsCredential if you're running on Vista/Win2k8, you should check the winver to decide which call to make).
This method actually invokes the regular credentials prompt but you get the credentials (awful, I know).
PInvoke.Net has sample code showing how to call this function from C# (in the PInvoke sample you have to pass CREDUI_FLAGS.DO_NOT_PERSIST for flags if you've specified false in save. Weird, I know).
More info (and a unmanaged sample) on the great Keith brown wikibook on security
Once you get the credentials (in a secure string) you can then impersonate the user to get to the resource (using logonuser).
And it's ugly. I understand you want Windows to show the standard prompt dialog and you don't want to know about the credentials.
I'm wondering if a ugly hack like using System.Diagnostics.Process to launch a hidden explorer.exe on the remote UNC would not do the trick. You'd have to find a way to wait for the user to have entered the credentials and then kill the spawned explorer process.

Path.GetTempFileName -- Directory name is invalid

Running into a problem where on certain servers we get an error that the directory name is invalid when using Path.GetTempFileName. Further investigation shows that it is trying to write a file to c:\Documents and Setting\computername\aspnet\local settings\temp (found by using Path.GetTempPath). This folder exists so I'm assuming this must be a permissions issue with respect to the asp.net account.
I've been told by some that Path.GetTempFileName should be pointing to C:\Windows\Microsoft.NET\Framework\v2.0.50727\temporaryasp.net files.
I've also been told that this problem may be due to the order in which IIS and .NET where installed on the server. I've done the typical 'aspnet_regiis -i' and checked security on the folders etc. At this point I'm stuck.
Can anyone shed some light on this?
**Update:**Turns out that providing 'IUSR_ComputerName' access to the folder does the trick. Is that the correct procedure? I don't seem to recall doing that in the past, and obviously, want to follow best practices to maintain security. This is, after all, part of a file upload process.
This is probably a combination of impersonation and a mismatch of different authentication methods occurring.
There are many pieces; I'll try to go over them one by one.
Impersonation is a technique to "temporarily" switch the user account under which a thread is running. Essentially, the thread briefly gains the same rights and access -- no more, no less -- as the account that is being impersonated. As soon as the thread is done creating the web page, it "reverts" back to the original account and gets ready for the next call. This technique is used to access resources that only the user logged into your web site has access to. Hold onto the concept for a minute.
Now, by default ASP.NET runs a web site under a local account called ASPNET. Again, by default, only the ASPNET account and members of the Administrators group can write to that folder. Your temporary folder is under that account's purview. This is the second piece of the puzzle.
Impersonation doesn't happen on its own. It needs to be turn on intentionally in your web.config.
<identity impersonate="true" />
If the setting is missing or set to false, your code will execute pure and simply under the ASPNET account mentioned above. Given your error message, I'm positive that you have impersonation=true. There is nothing wrong with that! Impersonation has advantages and disadvantages that go beyond this discussion.
There is one question left: when you use impersonation, which account gets impersonated?
Unless you specify the account in the web.config (full syntax of the identity element here), the account impersonated is the one that the IIS handed over to ASP.NET. And that depends on how the user has authenticated (or not) into the site. That is your third and final piece.
The IUSR_ComputerName account is a low-rights account created by IIS. By default, this account is the account under which a web call runs if the user could not be authenticated. That is, the user comes in as an "anonymous".
In summary, this is what is happening to you:
Your user is trying to access the web site, and IIS could not authenticate the person for some reason. Because Anonymous access is ON, (or you would not see IUSRComputerName accessing the temp folder), IIS allows the user in anyway, but as a generic user. Your ASP.NET code runs and impersonates this generic IUSR___ComputerName "guest" account; only now the code doesn't have access to the things that the ASPNET account had access to, including its own temporary folder.
Granting IUSR_ComputerName WRITE access to the folder makes your symptoms go away.
But that just the symptoms. You need to review why is the person coming as "Anonymous/Guest"?
There are two likely scenarios:
a) You intended to use IIS for authentication, but the authentication settings in IIS for some of your servers are wrong.
In that case, you need to disable Anonymous access on those servers so that the usual authentication mechanisms take place. Note that you might still need to grant to your users access to that temporary folder, or use another folder instead, one to which your users already have access.
I have worked with this scenario many times, and quite frankly it gives you less headaches to forgo the Temp folder; create a dedicated folder in the server, set the proper permissions, and set its location in web.config.
b) You didn't want to authenticate people anyway, or you wanted to use ASP.NET Forms Authentication (which uses IIS's Anonymous access to bypass checks in IIS and lets ASP.NET handle the authentication directly)
This case is a bit more complicated.
You should go to IIS and disable all forms of authentication other than "Anonymous Access". Note that you can't do that in the developer's box, because the debugger needs Integrated Authentication to be enabled. So your debugging box will behave a bit different than the real server; just be aware of that.
Then, you need to decide whether you should turn impersonation OFF, or conversely, to specify the account to impersonate in the web.config. Do the first if your web server doesn't need outside resources (like a database). Do the latter if your web site does need to run under an account that has access to a database (or some other outside resource).
You have two more alternatives to specify the account to impersonate. One, you could go to IIS and change the "anonymous" account to be one with access to the resource instead of the one IIS manages for you. The second alternative is to stash the account and password encrypted in the registry. That step is a bit complicated and also goes beyond the scope of this discussion.
Good luck!
I encountered this error while diagnosing a console app that was writing in temp files. In one of my test iterations I purged all the files/directories in temp for a 'clean-slate' run. I resolved this self inflicted issue by logging out and back in again.
Could be because IIS_WPG does not have access to a temp folder. If you think it is a permission issue, run a Procmon on asp.net worker process and check for AccessDenied errors.
I was having the same problem with one of my ASP.Net applications. I was getting Path.GetTempPath() but it was throwing an exception of:
"Could not write to file "C:\Windows\Temp\somefilename", exception: Access to the path "C:\Windows\Temp\somefilename" is denied."
I tried a few suggestions on this page, but nothing helped.
In the end, I went onto the web server (IIS server) and changed permissions on the server's "C:\Windows\Temp" directory to give the "Everyone" user full read-write permissions.
And then, finally, the exception went away, and my users could download files from the application. Phew!
You can use Path.GetTempPath() to find out which directory to which it's trying to write.

Categories