summaryrefslogtreecommitdiff
path: root/db
diff options
context:
space:
mode:
authorGeir Magnusson Jr <geir@pobox.com>2009-01-08 22:02:26 -0500
committerGeir Magnusson Jr <geir@pobox.com>2009-01-08 22:02:26 -0500
commitd0112b7569915aa70cec9f03db4e22f652e81b50 (patch)
tree3dc53531d73043c8e13673debebe0b1805bc15dd /db
parent6257f0c069e5594f469a0a99cb6849b80c93a926 (diff)
parentab581691b5c445496b6832c67eb5840769a20dba (diff)
downloadmongo-d0112b7569915aa70cec9f03db4e22f652e81b50.tar.gz
Merge branch 'master' of ssh://git.10gen.com/data/gitroot/p
Diffstat (limited to 'db')
-rw-r--r--db/db.cpp10
-rw-r--r--db/db.vcproj68
-rw-r--r--db/dbeval.cpp17
-rw-r--r--db/javajs.cpp62
-rw-r--r--db/javajs.h1
-rw-r--r--db/json.cpp6
-rw-r--r--db/makefile2
-rw-r--r--db/security.cpp49
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;