Skip to content

Commit

Permalink
fix threaded auth JAVA-72
Browse files Browse the repository at this point in the history
  • Loading branch information
erh committed Dec 30, 2009
1 parent 37148cb commit 184f8a4
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 19 deletions.
23 changes: 20 additions & 3 deletions src/main/com/mongodb/DB.java
Expand Up @@ -251,15 +251,29 @@ public void dropDatabase()
*/
public boolean authenticate(String username, char[] passwd )
throws MongoException {
String hash = _hash( username , passwd );
if ( ! _doauth( username , hash.getBytes() ) )
return false;
_username = username;
_authhash = hash.getBytes();
return true;
}

boolean reauth(){
if ( _username == null || _authhash == null )
throw new IllegalStateException( "no auth info!" );
return _doauth( _username , _authhash );
}

private boolean _doauth( String username , byte[] hash ){
BasicDBObject res = (BasicDBObject) command(new BasicDBObject("getnonce", 1));

if (res.getInt("ok") != 1) {
throw new MongoException("Error - unable to get nonce value for authentication.");
}

String nonce = res.getString("nonce");
String key = nonce + username + _hash( username , passwd );
String key = nonce + username + new String( hash );

BasicDBObject cmd = new BasicDBObject();

Expand All @@ -268,8 +282,8 @@ public boolean authenticate(String username, char[] passwd )
cmd.put("nonce", nonce);
cmd.put("key", Util.hexMD5(key.getBytes()));

res = (BasicDBObject) command(cmd);

res = (BasicDBObject)command(cmd);
return res.getInt("ok") == 1;
}

Expand Down Expand Up @@ -344,4 +358,7 @@ public void forceError()
protected boolean _readOnly = false;
private WriteConcern _concern = WriteConcern.NORMAL;

String _username;
byte[] _authhash = null;

}
12 changes: 6 additions & 6 deletions src/main/com/mongodb/DBApiLayer.java
Expand Up @@ -47,28 +47,28 @@ protected DBApiLayer( String root , DBConnector connector ){

protected void doInsert( ByteBuffer buf , WriteConcern concern )
throws MongoException {
_connector.say( 2002 , buf , concern );
_connector.say( this , 2002 , buf , concern );
}
protected void doDelete( ByteBuffer buf , WriteConcern concern )
throws MongoException {
_connector.say( 2006 , buf , concern );
_connector.say( this , 2006 , buf , concern );
}
protected void doUpdate( ByteBuffer buf , WriteConcern concern )
throws MongoException {
_connector.say( 2001 , buf , concern );
_connector.say( this , 2001 , buf , concern );
}
protected void doKillCursors( ByteBuffer buf )
throws MongoException {
_connector.say( 2007 , buf , WriteConcern.NORMAL );
_connector.say( this , 2007 , buf , WriteConcern.NORMAL );
}

protected int doQuery( ByteBuffer out , ByteBuffer in )
throws MongoException {
return _connector.call( 2004 , out , in );
return _connector.call( this , 2004 , out , in );
}
protected int doGetMore( ByteBuffer out , ByteBuffer in )
throws MongoException {
return _connector.call( 2005 , out , in );
return _connector.call( this , 2005 , out , in );
}


Expand Down
4 changes: 2 additions & 2 deletions src/main/com/mongodb/DBConnector.java
Expand Up @@ -24,6 +24,6 @@
import java.util.*;

public interface DBConnector {
public void say( int op , ByteBuffer buf , DB.WriteConcern concern ) throws MongoException;
public int call( int op , ByteBuffer out , ByteBuffer in ) throws MongoException;
public void say( DB db , int op , ByteBuffer buf , DB.WriteConcern concern ) throws MongoException;
public int call( DB db , int op , ByteBuffer out , ByteBuffer in ) throws MongoException;
}
28 changes: 27 additions & 1 deletion src/main/com/mongodb/DBPort.java
Expand Up @@ -22,6 +22,7 @@
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;
import java.util.logging.*;

import com.mongodb.util.*;
Expand Down Expand Up @@ -194,6 +195,29 @@ protected void finalize(){
}

}

void checkAuth( DB db ){
if ( db._username == null )
return;
if ( _authed.containsKey( db ) )
return;

if ( _inauth )
return;

_inauth = true;
try {
if ( db.reauth() ){
_authed.put( db , true );
return;
}
}
finally {
_inauth = false;
}

throw new MongoInternalException( "can't reauth!" );
}

final int _hashCode;
final InetSocketAddress _addr;
Expand All @@ -203,7 +227,9 @@ protected void finalize(){

private final ByteBuffer[] _array = new ByteBuffer[]{ ByteBuffer.allocateDirect( DBMessage.HEADER_LENGTH ) , null };
private SocketChannel _sock;


private boolean _inauth = false;
private Map<DB,Boolean> _authed = Collections.synchronizedMap( new WeakHashMap<DB,Boolean>() );

private static Logger _rootLogger = Logger.getLogger( "com.mongodb.port" );
}
14 changes: 8 additions & 6 deletions src/main/com/mongodb/DBTCPConnector.java
Expand Up @@ -121,10 +121,11 @@ public void requestEnsureConnection(){
_threadPort.get().requestEnsureConnection();
}

public void say( int op , ByteBuffer buf , DB.WriteConcern concern )
public void say( DB db , int op , ByteBuffer buf , DB.WriteConcern concern )
throws MongoException {
MyPort mp = _threadPort.get();
DBPort port = mp.get( true );
port.checkAuth( db );

try {
port.say( new DBMessage( op , buf ) );
Expand All @@ -150,15 +151,16 @@ public void say( int op , ByteBuffer buf , DB.WriteConcern concern )
}
}

public int call( int op , ByteBuffer out , ByteBuffer in )
public int call( DB db , int op , ByteBuffer out , ByteBuffer in )
throws MongoException {
return _call( op , out , in , 2 );
return _call( db , op , out , in , 2 );
}

private int _call( int op , ByteBuffer out , ByteBuffer in , int retries )
private int _call( DB db , int op , ByteBuffer out , ByteBuffer in , int retries )
throws MongoException {
MyPort mp = _threadPort.get();
DBPort port = mp.get( false );
port.checkAuth( db );

try {
DBMessage a = new DBMessage( op , out );
Expand All @@ -174,7 +176,7 @@ private int _call( int op , ByteBuffer out , ByteBuffer in , int retries )
throw new MongoException( "not talking to master and retries used up" );
in.position( 0 );

return _call( op , out , in , retries -1 );
return _call( db , op , out , in , retries -1 );
}
}

Expand All @@ -184,7 +186,7 @@ private int _call( int op , ByteBuffer out , ByteBuffer in , int retries )
mp.error( ioe );
if ( _error() && retries > 0 ){
in.position( 0 );
return _call( op , out , in , retries - 1 );
return _call( db , op , out , in , retries - 1 );
}
throw new MongoException.Network( "can't call something" , ioe );
}
Expand Down
4 changes: 3 additions & 1 deletion src/test/com/mongodb/JavaClientTest.java
Expand Up @@ -361,6 +361,8 @@ public void testMulti(){

@Test
public void testAuth(){
assertEquals( "26e3d12bd197368526409177b3e8aab6" , _db._hash( "e" , new char[]{ 'j' } ) );

DBCollection u = _db.getCollection( "system.users" );
try {
assertEquals( 0 , u.find().count() );
Expand All @@ -375,7 +377,7 @@ public void testAuth(){
u.remove( new BasicDBObject() );
assertEquals( 0 , u.find().count() );
}

}

@Test
Expand Down

0 comments on commit 184f8a4

Please sign in to comment.