We're dealing with an unusual situation involving dovecot that perhaps requires an unusual solution.
We recently required all of our POP/IMAP users to change their passwords, and in almost all cases, they dutifully did so. However, one user has several devices and machines which are repeatedly querying for email, and due to circumstances beyond anyone's control, one of his computers cannot be accessed for at least another few weeks, and therefore, the dovecot password for that user's email access cannot not be changed until that time passes.
Therefore, that computer keeps querying dovecot for email for that user with the old, now invalid password, and those queries fail.
Furthermore, due to various circumstances which are also beyond our control for the time being, we can't have that one user change his password back to the old value on the other machines and devices that he uses.
What we're wondering is whether there is some way that dovecot could be set up to recognize and accept both passwords for this one, specific user. In other words, can we somehow set up a secondary password for this email address so that both the old and the new password will allow this user to access his email?
We are using auth sql by including auth-sql.conf.ext in 10-auth.conf. Perhaps the solution to this problem would to restructure the database we are using for SQL authentication and add one or more columns, and then somehow change the SELECT statement that is used in auth-sql.conf.ext to choose between one of two passwords.
We are willing to attempt this procedure if it's the only option available, but we aren't even sure how it can be done. And in any case, we're hoping that there might be some feature of dovecot that we are unfamilar with which would allow us to set up this one user's dovecot email account to allow two different passwords for authentication without any database changes.
Is there any chance that we could do this?
Thank you in advance.
The link supplied by Allan Wind helped me (thank you!), as well as a couple other things I saw in those dovecot docs which I had overlooked in the past.
It turns out that I can supply a second userdb and passdb block in auth-sql.conf.ext, and they serve as secondary fallbacks if the primary SQL query doesn't return a match. I set up a passwd-file that is usable by both of these which contains the hash of the user's old password, and now, both passwords are working.
For example, the secondary userdb block (which should appear right below the original sql-based userdb block) looks like this:
# Fallback ...
userdb {
driver = passwd-file
args = scheme=md5-crypt username_format=%u /etc/dovecot/extra.userdb
}
The secondary passdb block is identical, except for it being named passdb instead of userdb. It must appear right after the original passdb statement in that same file.
So, all's well that ends well.
Onward!
Related
I wonder if I might ask for opinions on a simple authentication system I'm thinking about for a pet web site project where the overriding requirement is that the system should have no way to tell who the user is, i.e. have no way of identifying or contacting them.
The system does need to distinguish between these anonymous users of course, and prevent users pretending to be other users.
Perhaps in a strict sense it's not an authentication system at all, more like a distinguishing system.
A simple solution would be to assign a Guid to new users, which gets stored in a cookie/local storage/whatever and used to distinguish them.
Then give the user the facility to copy the Guid, and/or generate a URL that they can bookmark or otherwise store locally, which re-supplies the Guid to the site and stores it as a cookie again - to be used if the cookie is deleted or they want to authenticate from another machine - by using the generated URL or pasting the copied Guid into a 'login' page on the site.
This means there can be no 'I forgot my password' facility; if the user loses their credentials, they are forever lost, that's accepted.
Additionally, if the credentials are stolen, or the user's cookies are compromised, then the credential is stolen forever, there is no way for the real user to lock out the thief, that's also accepted.
Clearly the user would need to make damn sure they store this URL/Guid somewhere safe, that's accepted.
As an aside, there could be a feature that allows the user to regenerate the Guid, which might be used if they accidentally broadcast their Guid somehow, but that also means if somebody steals their Guid and uses the regenerate feature before the 'real' user realises, the real user will be locked out forever - maybe best it's unchangeable so at least if the Guid is compromised, the thief cannot lock out the real user - but this is an aside.
Given the requirement for complete anonymity / non-contactability, and accepting that losing the Guid is like losing a dollar bill, you lose it forever, it seems a reasonable and pleasantly simple solution.
This is essentially the same as having a user/password combination with no email address or other contact details, but more secure than user: sally123, password: mydogsname1968 or whatever just by virtue of it being a Guid, not something the user can remember or easily scribble on a post-it note and stick to a monitor.
It also has the advantage that a user who uses the same machine all the time (and doesn't delete cookies) never has to login or think about credentials at all.
The Guid could actually be two Guids stuck together or three of them interleaved byte by byte, whatever - a unique auto-generated chunk of data that reflects how unnecessarily paranoid the developer is feeling.
Can anyone tell me why this wouldn't be a good solution, given the anonymity/non-contactability requirements and the drawbacks accepted above, or perhaps suggest a better solution.
If it makes any difference to anything, it'll be a Net Core 5 / Blazor Web Assembly / MongoDb application, it's a pet project so doesn't have to pass muster with any client requirements or existing systems etc.
Thanks for any advice/help.
My co-workers are using a commercial program that encodes and stores login passwords on some database.
Now, I'm developing another program to achieve some other tasks, but I want my co-workers to authenticate to this program with their same username and passwords to avoid confusion.
The problem is, I don't have (and probably never will) any source code to determine which encryption algorithm they've used.
I ran some tests and observed that same passwords always produces same hashcodes with 24 characters in length. For example;
1 XeVTgalUq/gJxHtsMjMH5Q==
123456 0Q8UhOcqClGBxpqzooeFXQ==
Is there any way to determine which algorithm they've used ?
Thanks in advance,
Nope. That is the point of encryption / hashing-- it is supposed to be opaque so that it should not be easy to reverse engineer. The only thing you can do is try a few well-known hash algorithms like SHA-1 and see if the hash values match the other program. But, there's no way to know if the other program added in any "salt" or is hashing together multiple things, e.g. username + password or some other scheme. So you are probably out of luck on that front.
One idea you could try with your new program: if the user has never logged in before, allow them to log in the first time with ANY password. Tell the users that they should use the same password they did with the other program. Then, when they log in, capture that value and hash it using your own hashing scheme, then store that for future logins. So ultimately you would get the result you're aiming for (that users can use their same passwords), without having to reverse engineer the encryption scheme of the other program.
Now, clearly the drawback with this approach is that it is not secure at all for the first login. Someone could hijack another user's account if they logged in as that user before the real user had a chance to log in for the first time (and thereby lock in his password). So this is only an option if there is no sensitive data pre-loaded in the new program that could be compromised. Also you would need the ability for an administrator to reset a users' password so that if this kind of thing did happen, you could correct it easily when the real user reports that they can't log in.
We have a a large set of users who use our web application fairly infrequently (i.e. they don't visit every day or every week). As a result, they often:
forget the password they used
forget which e-mail they used on signup OR
may have actually had their e-mail address change since the last time they signed in
Often, when facing the login signup form, they'll simply create a new login record with a new/different e-mail address.
This is a problem because it's important they stay linked to their previous records, and it can cause problems if there are duplicate records for a single person in the database (note that these are not duplicate records in a database sense; from a data standpoint they're not duplicates at all, but they are duplicates in the sense that they point to a single real human being).
Right now I have a check in place that sees if there is already someone with the last name and first initial, and asks them to confirm if they are or aren't one of these other people. Obviously this is very clunky and falls flat when dealing with very common names. Also, it's confusing to display a page to a user that says, "I think you're actually this other person. Please let me know if you are this person or not."
I'm looking to hear from other developers who have had to deal with this problem, and what they came up with. I'm also interested in solutions that gracefully merge two logins.
You could easily prevent the user from signing up if they entered a duplicate username or e-mail address from what already exists in your database. You could present the user with a page that asks them to recover their password for the existing account. If the user is going to sign up with a different username and e-mail, I'd argue at that point it may be out of your control to stop the user from creating another account (unless you are gathering some sort of unique identifier from the user (e.g. social security number, etc). I wouldn't do any filtering based on name as it's never going to work 100% of the time.
Otherwise maybe a simple UI change could help alleviate the problem as well (e.g. "Returning user? Login"). Make sure the user sees that they can login with their existing account, and on that screen make sure the user can easily see that they can recover their account information if they can't remember it.
What algorithm should I use for encrypting and embedding a password for an application?
It obviously is not bullet proof, but it should be good enough to thwart someone scanning the database with a hex editor, or make it hard for someone who has the skills to use a debugger to trace the code to work out, either by scanning for the encrypted password, or using a debugger to run through the decryption code.
Object Pascal would be nice.
Major Edit
I think I did not explain myself well enough. The password needs to be decrypted back into its original form and applied. The application itself uses a local SQL database and a local webserver, and the password is fixed and can't be changed by the end users. It is to ensure that changes to be made only from within the app itself. The user passwords are only to allow access to the app itself, rather than the database
/vfclists
If you want an easy solution just stick with a good hashing algorithm like MD5 and store just the hash inside your application. Then whenever the user inserts the password you will calculate the hash of the password and check if it's equal to the one stored.
Of course this approach is a simple solution that doesn't allow you to retrieve the password if it's lost but it should work quite fine if you just need some protection..
EDIT: I mentioned MD5 that was fair good but not anymore, of course you can choose any other stronger function like SHA-2 (512/384) that is more robust. I just wanted to explain an approach more than using a specific hashing algorithm.
SHA should be ok for you, best with salt.
I don't know Object Pascal very well, but probably this will help you:
http://sourceforge.net/projects/op-crypt/
When an application has to do password checking only, it is best to save a hash. An hash can not be decrypted, but it can be checked whether the password the user enters has the same hash.
If you want to save the password so that it can be recovered, it is best to encrypt it first, using some crypto library.
I would suggest SHA1, its one way encryption, i've used it before and by far no one has decrypted it!
If you need more information on sha1 visit http://en.wikipedia.org/wiki/Secure_Hash_Algorithm and http://www.openssl.org/docs/crypto/sha.html.
PS: If you're using php you can simply encrypt with SHA1 using the sha1(); function!
I suspect that what you're aiming for is not storing passwords in the application, but trying to prevent the application itself from being run without the password, as a form of DRM. If that's the case, and you're looking to stymie people with debuggers, I think you're well into the realm of needing either a hardware dongle, or a network-based lock. Off the top of my head, I know SafeNet carry products that do this (and I've had some exposure to them in the past, they seem decent), but I don't know how well they compare to the rest of the market.
If you want as much real security as is possible in the scenario you're describing, you should require that when the system is installed an "administrator" enters the database password and his own administrator password; the application should then store a salted hash of the administrator's password, and it should store the database password encrypted with a differently-salted hash of the administrator's password. The database password (or information sufficient to reconstruct it) will be kept in memory while the program is running, but absent the administrator password there would be no way to retrieve when the program isn't running, even with full knowledge of the system.
If it's necessary to allow multiple users to access the database, an "add user" button could allow the addition of a user account. When the user types his password, use it to store hashed/encrypted data as with the administrator.
Any user with a debugger would be able to leverage his knowledge of a valid user account and password into knowledge of the database password, but someone who didn't have knowledge of a valid account password wouldn't be able to do anything.
If I am interpreting your question right, then you want to basically distribute your application to users, allow them to run it, and have the application update your database. At the same time, you want to prevent that person from being able to log in to the database and use it themselves directly.
If your program can be decompiled (like java, but I don't know about other languages like C, C++), then the person who has your application will be able to see the source code. Once they have that, there will most certainly be some way they can discover the user name and password. Even if your source code has stored the password using a reversible encryption algorithm, the person who holds your source code will be able to write similar code as yours to reverse the encryption and discover the password.
Even if your application cannot be decompiled, the user may be able to capture the network packets it sends to the database and determine the password from that. I don't know if you can communicate with the database over SSL.
Instead, I believe you need to split your application into client and server applications. You can write a restful web application, or use a messaging service (like JMS for example), and write a client application that uses it.
In that case, you may or may not want to have user accounts that are managed by your server side application. Let me be clear here, I am not talking about database accounts, but accounts that your application manages, and whose details happen to be stored in the database. If you do create user accounts, you can follow the pattern in my original answer shown below.
============== Hashing Approach, my original answer ============
As others have already mentioned, it's best to add salt to the password and use a digest algorithm before you store the password in your database. However, I think a little more detail is in order.
Using SHA1 or SHA2 with a salt value may be pretty strong, but there are even stronger methods. I highly recommend that you read this section of the spring security manual. I don't think you are using spring or java, but that section covers the concepts involved very well. Allow me to paraphrase:
Use at least an 8 byte salt value, up to 16 bytes would be great. The salt value should be different for every account, if it is the same then a cracker will only need to produce one rainbow table! It should be randomly generated. The documentation doesn't say this, but I also recommend using a secure random number generator, don't use a random number seed that produces a consistent sequence of numbers.
You should hash the password multiple times because it will cause brute force password hacking attempts to take increasingly more time. Indeed, you may want a slow password encoding algorithm instead of a fast one.
Store the raw salt value in the database along with the password, you can even store it in the same field/column. This is required so passwords can be verified in the future.
The BCryptPasswordEncoder is a good example of this.
===============
One alternative approach that may or may not solve your problem is to create a database account that has limited privileges. For example, you could create a database account that can only select, update, insert, and delete on specific tables in your database. You may not find this acceptable, because you may not want to let people do those operations directly, while you may want to let the application do those operations. It depends on your specific situation.
This is not a technical question. How do small organizations keep sensitive information that must be shared among several individuals safe, such as root passwords to production servers? Not all people that need to have access work in the same location.. new passwords can be distributed by phone, but what rules should be enforced for team members in the storing of the passwords?
UPDATE: this question is not about the proper usage of root passwords -- that was just meant as an example. Maybe a better example would be the SSL passphrase or any other password that must be shared among people performing administrative tasks. The fact is, root passwords and the like need to be generated and stored and usually more than one person needs to have access, sometimes those people work in different locations. The question is about storage protocols. Thanks.
You shouldn't be handing out (or using) root passwords to any servers, production or otherwise. You shouldn't be sharing passwords.
People should log in as themselves (authentication) with their own user ids passwords; that's one half of the picture.
When properly logged in they should be given rights (the authorization side of the picture) as appropriate. You can use things like sudo for general OS purposes, and the rights mechanisms inside databases, etc.
These are two separate issues. Don't cross the streams!
I personally recommend to people facing similar problems to use something like keepass or roboform to store passwords. These programs encrypt your passwords on a thumbdrive using a master password that the individual remembers, so that they need only remember the master password. In the event that someone looses their thumbdrive, they will have a window of time in which they can report the compromised thumbdrive, and allow you to change passwords. It will take a little bit of time, depending on the master password's strength, before the person who stole the thumb drive would be able to brute force the master password to get at all the other stored passwords.
Additionally, avoid having any account shared by more than 3 people, if at all! Instead, consider creating each individual an account with equivalent access. If a malicious employee has access to an account which they know is shared, it might be more tempting for them to do malicious things since they know you could not hold them accountable, since it could have been any of several people sharing the account.
This also means you don't have to change the password every time someone quits. Instead, you just disable/delete their account. So although you have more accounts to manage, you have less overhead when someone leaves since you don't have to notify everyone of a changed password.
Edit: Oh Roboform also has a online password sync service over SSL. So you could just have people retrieve passwords via syncing. It's kinda cool once you get used to it.
With the advent of sudo we seldom need to use a root password any more. In my old shop, the root password was written on a card, sealed in an envelope, and locked in a drawer in the sysadmins' area. Those who needed to know had keys to the drawer.
Anybody opening the envelope was required to change the password and put the new password in a new sealed envelope. The envelope was not opened often.
This system is probably really bad professional practice, but in a small shop where everybody knew everybody, it worked well.
In a prototype & R&D lab where I formerly worked, there were 'standard' lab passwords for things like root, administrative access to consoles, switches, etc. These are simple, easy to remember, and shared verbally with anyone who needed them. In general, if you could physically get into the lab, you were authorized to have these passwords.
In the manufacturing facility, new systems were built and configured for customers. The customer got to choose all the passwords, and they were printed on a set of forms that were attached to the rack with the systems. Remote access was provided as required, and the passwords were sent in an e-mail, or given over the phone. It was fully expected that the customer would change these passwords as soon as the system was delivered to them.
For the IT & Production labs, almost no one had root access. Almost everyone did have sudo access with somewhere between no limits and only the ability to mount virtual filesystems...depending on the person and the system. It was very rare to get sudo access to launch a shell as root. This left a very clear log trail of all the commands you ran as root. That log was used to tar & feather more than one person over the years.
At a help desk / support role I had many years ago, each tool expert picked their own administrative passwords. These were recorded in an envelop that was locked in a safe in the machine room. If someone needed admin access, they could open the envelop, read the password, and note in the log that they knew the password and then re-seal the password in the envelop. It was up to the tool owner to decide if the password needed to be changed. This system was used for more than 5 years...and in one case actually helped the project to survive the "bus test" (heart attack) for one team member.
Different standards for different kinds of systems and labs. That is reasonable. I find that when passwords need to be shard, it is best if the password is simple, short, and communicated verbally (either in person or over the phone). I find that the only password that should never be shared is the one for my personal account. Any root/admin/tool specific passwords should be backed up in at least one other head...if not recorded in some manner.
you can use a program like anypasswordpro to share passwords. It is encrypted and has levels of access :)
Be realistic. Whether you like it or not, people in small teams are going to write passwords on sticky notes, IM them, or be tempted to email them, especially when they perceive no threat.
One measure I've found useful with small groups is to establish an obfuscation protocol.
For example, all passwords communicated or stored via voicemail, email, IM, or paper will have
1) the order of their characters reversed
2) a random character or word placed in between each password character
3) phonetically pronounced password characters.
For example:
Password: VMaccp#ss1
Obfuscated: one 2 es df es 23 at sd pee fd see dfs see fxz ay df EM sd VEE
The key is to establish some kind of encoding that is virtually impossible for someone to figure out without knowing the protocol, which is easy to remember.
Keep in mind this is for small groups without life-or-death security. Obviously for larger groups or those protecting extremely sensitive financial data stronger more cumbersome measures are appropriate.