diff options
author | Geir Magnusson Jr <geir@pobox.com> | 2009-01-08 22:02:26 -0500 |
---|---|---|
committer | Geir Magnusson Jr <geir@pobox.com> | 2009-01-08 22:02:26 -0500 |
commit | d0112b7569915aa70cec9f03db4e22f652e81b50 (patch) | |
tree | 3dc53531d73043c8e13673debebe0b1805bc15dd /db | |
parent | 6257f0c069e5594f469a0a99cb6849b80c93a926 (diff) | |
parent | ab581691b5c445496b6832c67eb5840769a20dba (diff) | |
download | mongo-d0112b7569915aa70cec9f03db4e22f652e81b50.tar.gz |
Merge branch 'master' of ssh://git.10gen.com/data/gitroot/p
Diffstat (limited to 'db')
-rw-r--r-- | db/db.cpp | 10 | ||||
-rw-r--r-- | db/db.vcproj | 68 | ||||
-rw-r--r-- | db/dbeval.cpp | 17 | ||||
-rw-r--r-- | db/javajs.cpp | 62 | ||||
-rw-r--r-- | db/javajs.h | 1 | ||||
-rw-r--r-- | db/json.cpp | 6 | ||||
-rw-r--r-- | db/makefile | 2 | ||||
-rw-r--r-- | db/security.cpp | 49 |
8 files changed, 198 insertions, 17 deletions
diff --git a/db/db.cpp b/db/db.cpp index d28b5f43bd0..fba497131c6 100644 --- a/db/db.cpp +++ b/db/db.cpp @@ -272,6 +272,8 @@ void clearTmpFiles() { } } +Timer startupSrandTimer; + void segvhandler(int x); void initAndListen(int listenPort, const char *appserverLoc = null) { clearTmpFiles(); @@ -305,6 +307,9 @@ void initAndListen(int listenPort, const char *appserverLoc = null) { repairDatabases(); + /* this is for security on certain platforms */ + srand(curTimeMillis() ^ startupSrandTimer.micros()); + listen(listenPort); } @@ -315,6 +320,7 @@ void pipeSigHandler( int signal ); int main(int argc, char* argv[], char *envp[] ) { + srand(curTimeMillis()); boost::filesystem::path::default_name_check( boost::filesystem::no_check ); { @@ -331,8 +337,6 @@ int main(int argc, char* argv[], char *envp[] ) #if !defined(_WIN32) signal(SIGPIPE, pipeSigHandler); #endif - srand(curTimeMillis()); - UnitTest::runTests(); if ( argc >= 2 ) { @@ -532,7 +536,7 @@ void mysighandler(int x) { cout << "got kill or ctrl c signal " << x << ", will terminate after current cmd ends" << endl; { dblock lk; - problem() << " now exiting" << endl; + log() << "now exiting" << endl; exit(12); } } diff --git a/db/db.vcproj b/db/db.vcproj index bf1b32c5e33..62bca326d45 100644 --- a/db/db.vcproj +++ b/db/db.vcproj @@ -356,6 +356,10 @@ >
</File>
<File
+ RelativePath=".\security.cpp"
+ >
+ </File>
+ <File
RelativePath="..\stdafx.cpp"
>
<FileConfiguration
@@ -395,6 +399,62 @@ >
</File>
<File
+ RelativePath="..\util\md5.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="release_nojni|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\util\md5main.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="release_nojni|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="0"
+ />
+ </FileConfiguration>
+ </File>
+ <File
RelativePath="..\grid\message.cpp"
>
</File>
@@ -561,6 +621,14 @@ >
</File>
<File
+ RelativePath="..\util\md5.h"
+ >
+ </File>
+ <File
+ RelativePath="..\util\md5.hpp"
+ >
+ </File>
+ <File
RelativePath="..\util\miniwebserver.h"
>
</File>
diff --git a/db/dbeval.cpp b/db/dbeval.cpp index 0b30ea9a90c..5ca69eee6e0 100644 --- a/db/dbeval.cpp +++ b/db/dbeval.cpp @@ -35,8 +35,16 @@ const int edebug=0; bool dbEval(const char *ns, BSONObj& cmd, BSONObjBuilder& result, string& errmsg) { BSONElement e = cmd.firstElement(); - assert( e.type() == Code || e.type() == CodeWScope ); - const char *code = e.type() == Code ? e.valuestr() : e.codeWScopeCode(); + assert( e.type() == Code || e.type() == CodeWScope || e.type() == String ); + + const char *code = 0; + switch ( e.type() ){ + case String: + case Code: code = e.valuestr(); break; + case CodeWScope: code = e.codeWScopeCode(); break; + default: assert(0); + } + assert( code ); if ( ! JavaJS ) { errmsg = "db side execution is disabled"; @@ -78,10 +86,11 @@ bool dbEval(const char *ns, BSONObj& cmd, BSONObjBuilder& result, string& errmsg } if ( res ) { result.append("errno", (double) res); - errmsg = "invoke failed"; + errmsg = "invoke failed: "; + errmsg += s.getString( "error" ); return false; } - + int type = s.type("return"); if ( type == Object || type == Array ) result.append("retval", s.getObject("return")); diff --git a/db/javajs.cpp b/db/javajs.cpp index 66eb4cd168e..4967b8acfae 100644 --- a/db/javajs.cpp +++ b/db/javajs.cpp @@ -111,17 +111,32 @@ JavaJSImpl::JavaJSImpl(const char *appserverPath) { _jvm = 0; _mainEnv = 0; _dbhook = 0; - - const char * ed = findEd(appserverPath); + stringstream ss; - + string edTemp; + + const char * ed = 0; ss << "-Djava.class.path=."; - ss << SYSTEM_COLON << ed << "/build/"; + + if ( appserverPath ){ + ed = findEd(appserverPath); + + ss << SYSTEM_COLON << ed << "/build/"; + + _addClassPath( ed , ss , "include" ); + _addClassPath( ed , ss , "include/jython/" ); + _addClassPath( ed , ss , "include/jython/javalib" ); + } + else { + const char * jars = findJars(); + _addClassPath( jars , ss , "jars" ); + + edTemp += (string)jars + "/jars/babble.jar"; + ed = edTemp.c_str(); + } - _addClassPath( ed , ss , "include" ); - _addClassPath( ed , ss , "include/jython/" ); - _addClassPath( ed , ss , "include/jython/javalib" ); + #if defined(_WIN32) ss << SYSTEM_COLON << "C:\\Program Files\\Java\\jdk\\lib\\tools.jar"; #else @@ -180,11 +195,13 @@ JavaJSImpl::JavaJSImpl(const char *appserverPath) { _envs->reset( _mainEnv ); _dbhook = findClass( "ed/db/JSHook" ); - if ( _dbhook == 0 ) + if ( _dbhook == 0 ){ log() << "using classpath: " << q << endl; + printException(); + } jassert( _dbhook ); - { + if ( ed ){ jmethodID init = _mainEnv->GetStaticMethodID( _dbhook , "init" , "(Ljava/lang/String;)V" ); jassert( init ); _mainEnv->CallStaticVoidMethod( _dbhook , init , _getEnv()->NewStringUTF( ed ) ); @@ -525,6 +542,33 @@ const char * findEd() { #endif }; +const char * findJars(){ + + static list<const char*> possible; + if ( ! possible.size() ) { + possible.push_back( "./" ); + possible.push_back( "../" ); + } + + for ( list<const char*>::iterator i = possible.begin() ; i != possible.end(); i++ ) { + const char * temp = *i; + const string jarDir = ((string)temp) + "jars/"; + + path p(jarDir ); + if ( ! boost::filesystem::exists( p) ) + continue; + + log() << "found directory for jars : " << jarDir << endl; + return temp; + } + + problem() << "ERROR : can't find directory for jars - terminating" << endl; + exit(44); + return 0; + +}; + + // --- JNIEXPORT void JNICALL java_native_say(JNIEnv * env , jclass, jobject outBuffer ) { diff --git a/db/javajs.h b/db/javajs.h index 82a36ef2561..a57db1251a4 100644 --- a/db/javajs.h +++ b/db/javajs.h @@ -42,6 +42,7 @@ int javajstest(); const char * findEd(); const char * findEd(const char *); +const char * findJars(); class BSONObj; diff --git a/db/json.cpp b/db/json.cpp index 0be93b92940..1ee992d5f2e 100644 --- a/db/json.cpp +++ b/db/json.cpp @@ -179,6 +179,9 @@ struct fieldNameEnd { fieldNameEnd( ObjectBuilder &_b ) : b( _b ) {} void operator() ( const char *start, const char *end ) const { b.fieldNames.back() = b.popString(); + massert( "Field name cannot start with '$'", + b.fieldNames.back().length() == 0 || + b.fieldNames.back()[ 0 ] != '$' ); } ObjectBuilder &b; }; @@ -381,6 +384,9 @@ struct regexEnd { // worth noting here that this parser follows a short-circuit convention. So, // in the original z example on line 3, if the input was "ab", foo() would only // be called once. +// 2009-01-08 I've disallowed field names beginning with '$' (except those matching +// our special types). If we go with this convention long term, parser +// backtracking is less of a concern. struct JsonGrammar : public grammar< JsonGrammar > { public: JsonGrammar( ObjectBuilder &_b ) : b( _b ) {} diff --git a/db/makefile b/db/makefile index fdc05d8df2e..eb6267ac9e7 100644 --- a/db/makefile +++ b/db/makefile @@ -12,7 +12,7 @@ DBTEST_LIBS= $(LIBS) -lunittest JVM_LIBS = -L/opt/java/lib/ -OBJS=../stdafx.o ../util/sock.o ../grid/message.o ../util/mmap.o pdfile.o query.o jsobj.o introspect.o btree.o clientcursor.o ../util/util.o javajs.o tests.o json.o repl.o ../client/dbclient.o btreecursor.o cloner.o namespace.o commands.o matcher.o dbcommands.o dbeval.o ../util/background.o ../util/miniwebserver.o dbwebserver.o dbinfo.o instance.o dbhelpers.o lasterror.o +OBJS=../stdafx.o ../util/sock.o ../grid/message.o ../util/mmap.o pdfile.o query.o jsobj.o introspect.o btree.o clientcursor.o ../util/util.o javajs.o tests.o json.o repl.o ../client/dbclient.o btreecursor.o cloner.o namespace.o commands.o matcher.o dbcommands.o dbeval.o ../util/background.o ../util/miniwebserver.o dbwebserver.o dbinfo.o instance.o dbhelpers.o lasterror.o ../util/md5.o ../util/md5main.o security.o DBGRID_OBJS=../stdafx.o json.o ../util/sock.o ../grid/message.o ../util/util.o jsobj.o ../client/dbclient.o ../dbgrid/dbgrid.o ../dbgrid/request.o ../client/connpool.o ../dbgrid/gridconfig.o commands.o ../dbgrid/dbgrid_commands.o ../dbgrid/griddatabase.o ../client/model.o ../util/background.o ../dbgrid/shard.o lasterror.o diff --git a/db/security.cpp b/db/security.cpp new file mode 100644 index 00000000000..78177326d77 --- /dev/null +++ b/db/security.cpp @@ -0,0 +1,49 @@ +// security.cpp
+
+#include "stdafx.h"
+#include "../util/md5.hpp" + +extern "C" int do_md5_test(void); +
+typedef unsigned long long nonce;
+
+struct Security {
+ ifstream *devrandom;
+
+ nonce getNonce() {
+ nonce n;
+#if defined(__linux__)
+ devrandom->read((char*)&n, sizeof(n));
+ massert("devrandom failed", !devrandom->fail());
+#else
+ n = ((unsigned long long)rand())<<32 | rand();
+#endif
+ return n;
+ }
+
+ Security()
+ {
+#if defined(__linux__)
+ devrandom = new ifstream("/dev/urandom", ios::binary|ios::in);
+ massert( "can't open dev/urandom", devrandom->is_open() );
+#endif
+ assert( sizeof(nonce) == 8 );
+
+ if( do_md5_test() ) + massert("md5 unit test fails", false); + }
+} security;
+
+#include "commands.h"
+#include "jsobj.h"
+
+class CmdGetNonce : public Command { +public: + virtual bool logTheOp() { return false; } + virtual bool slaveOk() { return true; } + CmdGetNonce() : Command("getnonce") {} + bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { + result.append("nonce", (double) security.getNonce()); + return true; + } +} cmdGetNonce; |