Re: [orientdb] Security: plain passwords in server xml config

197 visninger
Gå til det første ulæste opslag

Luca Garulli

ulæst,
25. mar. 2013, 04.05.2925.03.2013
til orient-database
Hi,
I see a new issue about this:


But instead of writing the changes you did in an email could you kindly send a pull request to be checked and merged quickly?

Thanks in advance,
Lvc@


On 13 March 2013 09:23, hoogs <hoog...@gmail.com> wrote:
Hi Luca,

I've been watching for a while but have now taken the plunge using orientdb with a java app.  Its a nice piece of work, well done and thank you!

I'm a little uneasy with plain text passwords in orientdb-server-config.xml and propose some minor changes in the current dev branch.  I'm also a little uneasy about use of unencrypted binary and text sockets for the server, but I can see how you expect a user to manage their own SSL layer, or use OpenVPN on your commerical service, which I don't know much about.

You already have the encryption machinery in the code so what I've added is basically:

1. a passphrase hasher invoked by starting ./server.sh with a "-p" argument (only for the linux script).  The server is started and asks twice for a passphrase, then displays your existing digest2String SHA-256 hash, before quitting.  The user pastes the hash into the pass value in the xml config file.
2. a request for the root passphrase on server startup and shutdown.  At least then the jvm instance invocation is somewhat secure.  This will present a problem when automated spawning of instances, which I'm not doing just at the moment.
3. the same hash-based authentication when a client tries to log into the server over the http socket.  The password is still transmitted plain, but at least it is stored in the xml as a hash.

I noticed in current git repo (yesterday), in orientdb-server-config.xml you did not have the root user, perhaps you add that separately when building releases, so I've added:

        <!-- Default root password is "root" -->
        <user resources="*" password="4813494D137E1631BBA301D5ACAB6E7BB7AA74CE1185D456565EF51D737677B2" name="root"/>
        <user resources="connect,server.listDatabases" password="guest" name="guest"/>

The password is just the hash of the string "root" as a default and OServerMain checks if this has been changed and aborts if not, forcing the user to change it.

In bin/server.sh I've simply added "$@" right at the end so that the -p switch can be transmitted to

java -server $JAVA_OPTS $JAVA_OPTS_SCRIPT $ORIENTDB_SETTINGS -Djava.util.logging.config.file="$LOG_FILE" -Dorientdb.config.file="$CONFIG_FILE" -Dorientdb.www.path="$WWW_PATH" -Dorientdb.build.number="@BUILD@" -  >cp "$ORIENTDB_HOME/lib/orientdb-server-@VERSION@.jar:$ORIENTDB_HOME/lib/*" com.orientechnologies.orient.server.OServerMain "$@"

Most changes are in OServerMain where I've modified the main function and added some helpers (importing OSecurityManager):

    public static void main(final String[] args) throws Exception {
 
        if (args.length > 0 && args[0].trim().startsWith("-p"))
        {
            System.out.println("OrientDB server passphrase generator");
            System.out.print("Enter passphrase  : ");
            char[] chars1 = System.console().readPassword();
            String input1 = new String(chars1);
            System.out.print("Repeat passphrase : ");
                             
            char[] chars2 = System.console().readPassword();
            String input2 = new String(chars2);
 
            if (input1 == null || input2 == null)
            {
                System.out.println("No input received.");
                System.exit(1);
            }
            else if (!input1.equals(input2))
            {
                System.out.println("Phrases do not match, try again.");
                System.exit(1);
            }
 
            System.out.println
            (
                "The hash is       : "
              + OSecurityManager.instance().digest2String(input1)
            );
            System.exit(0);
        }
 
        OServerMain.create().startup();
 
        String correct = server().getUser("root").password;
        // Default hash of "root"
        String defaultPhrase =
              "4813494D137E1631BBA301D5ACAB6E7B"
            + "B7AA74CE1185D456565EF51D737677B2";
 
        if (correct.equals(defaultPhrase))
        {
            String linesep = System.getProperty("line.separator");
            System.out.println
            (
                linesep + linesep
              + "Passphrase has not been changed from default."
              + linesep
              + "Restart server with -p switch to set new passphrase."
              + linesep
              + "A longer phrase with alphanumerics enhances security."
            );
            System.exit(1);
        }
 
        requestRootPassPhrase();
        // The string input could now be retained as a
        // key for data encryption
 
        server().activate();
    }
 
    public static void requestRootPassPhrase()
    throws Exception
    {
        System.out.println();
        System.out.print("Enter root passphrase: ");
        char[] chars = System.console().readPassword();
        String input = new String(chars);
 
        if (grantAuthority("root", input))
        {
            System.out.println("Passphrase OK.");
        }
        else
        {
            System.out.println("Passphrase incorrect.");
            System.exit(1);
        }
    }
 
    /**
     * Grant authority by comparing the stored hash of the correct password
     * against the given string.
     * 
     * @param iUserName
     *          Username to authenticate
     * @param iPassword
     *          Password in clear
     * @return true if authentication is ok, otherwise false
     */
    public static boolean grantAuthority
    (
        String iUserName,
        String iPassword
    )
    throws Exception
    {
        if (server() == null) create();
        String correct = server().getUser(iUserName).password;
        String hashed =
            OSecurityManager
            .instance()
            .digest2String
            (
                iPassword
            );
        if (hashed.equals(correct)) return true;
        return false;
    }

In OServer I just replaced this line

if (user != null && (iPassword == null || user.password.equals(iPassword))) {

with this

if (user != null && (iPassword == null || OServerMain.grantAuthority(iUserName, iPassword))) {

finally, I've inserted this call to the OServerMain request at the top of the try block in OServerShutdown.main

OServerMain.requestRootPassPhrase();

System.out.println("Sending shutdown command to remote OrientDB Server instance...");

I'm happy to commit to the repo, or else here are some ideas for getting rid of plain passwords from the xml with minimal pain.

Cheers
hoogs

--
 
---
You received this message because you are subscribed to the Google Groups "OrientDB" group.
To unsubscribe from this group and stop receiving emails from it, send an email to orient-databa...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Svar alle
Svar til forfatter
Videresend
0 nye opslag