Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm currently managing and re-factoring a piece of software that has been used at my company for over a decade now. One of the elements of this application is a sort of admin or power-user mode which provides things like some additional/internal input as well as the ability to turn off input limits.

Historically this mode has been turned on by placing a specifically named file in a specific place in the windows system directory (both of which were hard coded into the application), the file being named 'something.DLL', even though it was an empty ASCII file and not a dll.

So I recently added some code and a little modal form that allows the user to enter an admin password to turn this functionality on. It is a set password, not user specific. When the correct password is entered, it does sort of the same thing by creating a 'key file' in the applications root directory so that the program can start in admin mode if that file is present.

Now the manager of the department that this software is mostly for doesn't like that idea so much. He thinks that if we have just a simple, preset password that it will easily 'get out', and he doesn't want inexperienced users accessing those extra features.

So my question is, what other methods are there for providing this kind of access that would be somewhat more secure? It's pretty much just me when it comes to maintaining and managing this software, so anything that isn't almost completely built in or automated wouldn't help (such as sending requests for 'license keys' or something similar to that).

Notes: This application is written in VB.NET (.NET 4.0), and I am currently planning on using click-once deployment when the new version is done.

share|improve this question
1  
Someone has to make a decision which users are "unexperienced" and which are not. Who makes that decision? Who has to put that decisions into the system? –  Doc Brown Sep 24 '13 at 20:59

5 Answers 5

up vote 13 down vote accepted

If you have Active Directory, you can test for membership in an Active Directory Group:

public bool IsInADGroup(string ADGroupName)
    {
        bool result = false;
        List<string> myGroups = new List<string>();

        using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, SystemInformation.UserDomainName))
        {
            using (PrincipalSearchResult<Principal> src = UserPrincipal.FindByIdentity(pc, SystemInformation.UserName).GetGroups(pc))
            {
                src.ToList().ForEach(sr => myGroups.Add(sr.SamAccountName));
            }
        }
        result = myGroups.Contains(ADGroupName);
        return result;
    }
share|improve this answer
    
This is a very good answer, and something I will definitely keep in mind for this and other projects. However the real issue is the users of this program outside of our company. We provide it for both our sister companies and a few external, 3rd party users. I'm actually thinking at this point that it will be best to just completely disable these features for those outside our network and use your suggestion for internal purposes. –  Anthony Sep 25 '13 at 0:35

The manager is right about the password getting out. Its not a matter of if, but when.

Since Active Directory isn't an option for some users, you could create a signed text file with a list of windows login names that are allowed super user access. This assumes that people are not sharing computers or logins.

The user names would just go in an easily distributed text file that would be put in the application's folder. The important part is to sign the list of user names. Keep it very simple. One user name per row and put the hash on the last line. Embed some sort of secret key in your program binary and hash it with the usernames. The secret key will prevent people from modifying the file and then calculating the hash themselves (which is probably far-fetched to start with).

UserName1
UserName2
.
.
.
UserName34
<HashOfUserNamesAndSecretKey>

This, of course, requires someone somewhere to act as the admin of the list of authorized users. The admin should have a program (written by you!) that generates the file and hash. If nothing else, it could just take an text file of user names and add the hash.

In the interest of being thorough, someone who has been revoked access could grab the copy of the file that still has their login name in it. Whenever they wanted access, they could just put their copy in place. Probably not something to worry about, though.

share|improve this answer

Since Active Directory is not an option, I would hash the current date. Use elements with the most entropy first (day of month) and those with least entropy last (year). If need be, add a domain-specific salt (a customer ID, company name, etc. since it is used outside your company). This should produce a very different password each day that is practically impossible for end users to guess, and it can be different for different companies that use the software.

This is essentially a chicken and egg problem since the software needs to be able to authenticate the user without phoning home. So make an egg with a really obscure cracking mechanism: while security through obscurity is not real security, this is the best you have given the parameters of your problem.

This is also better than placing a text file somewhere: that is no better than a static password because once the secret gets out, game over.

share|improve this answer

Use Access Control Lists.

The quick and dirty way to do this is to remove all permissions from the application directory (including read permission), then add these permissions for any users who are permitted to run the application. Of course, a user with permission could just as easily copy the application directory to a public location, but this is unlikely to happen accidentally, whereas password sharing can easily happen accidentally.

This assumes, of course, that the computers involved are secured (hopefully with active directory).

share|improve this answer
    
If the computers involved are secured with active directory it might be best simply to secure the advanced functionality by membership to a security group. Users can be added to the group on an as-needed basis and file system permissions are non-relevant –  Kevin Sep 24 '13 at 20:38
    
@Kevin: Agreed. I think Dan's Answer covers that. –  Brian Sep 25 '13 at 13:14

My preference is as @Dan suggested - use active directory. If this is not possible, then a password generator based on time can be useful. In a similar situation, (very distant past) one my company I worked for used 9999-MMDD. This did get out after a couple of years. If you threw in hhmm and mixed it up a bit you might get a year or two out of it before someone lets the cat out the bag.

You could always write a program that generates a password using a similar, but more complex strategy. Throw in the used name an machine name as well. You manager can run that program to get the current password for just that machine. Store some information in the file so its not valid if copied to another machine or if a different user is logged in. Its then up to you manager to keep the program secure and if the cat gets out, its his fault.

This scheme is considered weak and unreliable from a cyrpto perspective, but is adequate for the problem you have.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.