Changeset: be1139fb4cc6 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=be1139fb4cc6
Modified Files:
configure.ag
tools/merovingian/ChangeLog
tools/merovingian/client/Makefile.ag
tools/merovingian/daemon/Makefile.ag
tools/merovingian/daemon/argvcmds.c
tools/merovingian/daemon/client.c
tools/merovingian/daemon/controlrunner.c
tools/merovingian/daemon/controlrunner.h
tools/merovingian/daemon/discoveryrunner.c
tools/merovingian/daemon/handlers.c
tools/merovingian/daemon/merovingian.c
tools/merovingian/daemon/monetdbd.1.in
tools/merovingian/utils/control.c
Branch: default
Log Message:
merovingian: join controlport with port
Control (TCP) connections are now handled over the (mapi)client
TCP connection, usually 50000. This removes the need for an additional
port. Since the control speak is different than the mapi speak (hence
the different port), a mapi-compatible ritual for control connections is
now used. For ease of use, the monetdb tool currently speaks both the
old control protocol as well as the new mapi-based protocol to log into
remote merovingian servers. The local UNIX-socket protocol hasn't
changed.
- instead of sending a dummy challenge, send out a meaningfull challenge
such that control connections can do proper authorisation
bump protover announced by merovingian to 9 to tell control-pass hash
- remove controlport, introduce control boolean, upgrade existing
controlport to control boolean
- passphrase is converted to the backend-configured hash
- disable incomplete peering support (control proto v2)
- deprecate control_hash in favour of the mapi authentication
protocol
- implement mapi-compatible authorisation in control client library
- monetdbd set passphrase=XXX now accepts a regular string to convert to
the backend-configured hash, or a hash prefixed by {hashtype}, e.g.
{SHA512}xxxxx...
- update manpages, changelogs
- document changing which properties are immediately acted upon at
runtime
diffs (truncated from 2048 to 300 lines):
diff --git a/configure.ag b/configure.ag
--- a/configure.ag
+++ b/configure.ag
@@ -290,6 +290,7 @@ MD5|SHA1|RIPEMD160|SHA224|SHA256|SHA384|
;;
esac
AC_DEFINE_UNQUOTED([MONETDB5_PASSWDHASH], "$MONETDB5_PASSWDHASH", [The used
password hash algorithm])
+AC_SUBST([MONETDB5_PASSWDHASH])
AC_DISABLE_STATIC
AC_ENABLE_SHARED
diff --git a/tools/merovingian/ChangeLog b/tools/merovingian/ChangeLog
--- a/tools/merovingian/ChangeLog
+++ b/tools/merovingian/ChangeLog
@@ -1,6 +1,16 @@
# ChangeLog file for sql/src/backends/monet5/merovingian
# This file is updated with mchangelog
+* Wed Aug 31 2011 Fabian Groffen <[email protected]>
+- The control passphrase has been turned into a hash of the password, for
+ a more stronger authorisation model as used by mclients. On upgrade,
+ any existing passphrase is converted to the hashed version of the
+ passphrase.
+- The monetdbd controlport option has been removed in favour of a
+ boolean control option. On upgrade, when controlport was set to
+ a non-zero value and a passphrase was set, control is set to true,
+ or false otherwise.
+
* Fri Aug 19 2011 Fabian Groffen <[email protected]>
- The monetdbd discoveryport option has been removed in favour of a
boolean discovery option. On upgrade, when discoveryport was set to
diff --git a/tools/merovingian/client/Makefile.ag
b/tools/merovingian/client/Makefile.ag
--- a/tools/merovingian/client/Makefile.ag
+++ b/tools/merovingian/client/Makefile.ag
@@ -33,7 +33,9 @@ bin_monetdb = {
../../../monetdb5/misc/libsabaoth \
../../../common/stream/libstream \
../../../common/utils/libmutils \
+ ../../../common/utils/libmcrypt \
$(UUID_LIBS) \
+ $(openssl_LIBS) \
$(curl_LIBS) \
$(SOCKET_LIBS) \
$(MALLOC_LIBS)
diff --git a/tools/merovingian/daemon/Makefile.ag
b/tools/merovingian/daemon/Makefile.ag
--- a/tools/merovingian/daemon/Makefile.ag
+++ b/tools/merovingian/daemon/Makefile.ag
@@ -54,6 +54,7 @@ bin_monetdbd = {
../../../common/stream/libstream \
../../../clients/mapilib/libmapi \
../../../common/utils/libmutils \
+ ../../../common/utils/libmcrypt \
$(UUID_LIBS) \
$(curl_LIBS) \
$(SOCKET_LIBS) \
diff --git a/tools/merovingian/daemon/argvcmds.c
b/tools/merovingian/daemon/argvcmds.c
--- a/tools/merovingian/daemon/argvcmds.c
+++ b/tools/merovingian/daemon/argvcmds.c
@@ -27,6 +27,7 @@
#include <signal.h> /* kill */
#include <mutils.h> /* MT_lockf */
+#include <mcrypt.h> /* mcrypt_BackendSum */
#include <utils/utils.h>
#include <utils/properties.h>
@@ -89,7 +90,6 @@ int
command_create(int argc, char *argv[])
{
char path[2048];
- char buf[48];
char *p;
char *dbfarm;
struct stat sb;
@@ -130,9 +130,8 @@ command_create(int argc, char *argv[])
return(1);
}
- generateSalt(buf, sizeof(buf));
phrase[0].key = "passphrase";
- phrase[0].val = buf;
+ phrase[0].val = NULL;
phrase[1].key = NULL;
if (writeProps(phrase, dbfarm) != 0) {
fprintf(stderr, "unable to create file in directory '%s': %s\n",
@@ -241,7 +240,7 @@ command_get(confkeyval *ckv, int argc, c
} else if (strcmp(p, "controlsock") == 0) {
kv = findConfKey(ckv, "sockdir");
value = kv->val;
- kv = findConfKey(ckv, "controlport");
+ kv = findConfKey(ckv, "port");
snprintf(buf, sizeof(buf), "%s/" CONTROL_SOCK "%d",
value, kv->ival);
value = buf;
@@ -278,6 +277,7 @@ int
command_set(confkeyval *ckv, int argc, char *argv[])
{
char *p = NULL;
+ char h[256];
char *property;
char *dbfarm = LOCALSTATEDIR "/monetdb5/dbfarm";
confkeyval *kv;
@@ -321,7 +321,7 @@ command_set(confkeyval *ckv, int argc, c
strcmp(property, "controlsock") == 0)
{
fprintf(stderr, "set: mapisock and controlsock are deduced from
"
- "sockdir, port and controlport, change those
instead\n");
+ "sockdir and port, change those instead\n");
return(1);
}
@@ -329,22 +329,28 @@ command_set(confkeyval *ckv, int argc, c
fprintf(stderr, "set: no such property: %s\n", property);
return(1);
}
- /* special trick to make it easy to use a different port with one
- * command */
- if (strcmp(property, "port") == 0) {
- int oport = kv->ival;
- char *e;
- if ((e = setConfVal(kv, p)) != NULL) {
- fprintf(stderr, "set: failed to set property port:
%s\n", e);
- free(e);
- return(1);
+ if (strcmp(property, "passphrase") == 0) {
+ char dohash = 1;
+ /* allow to either set a hash ({X}xxx), or convert the given
+ * string to its hash */
+ if (*p == '{') {
+ char *q;
+ if ((q = strchr(p + 1, '}')) != NULL) {
+ *q = '\0';
+ if (strcmp(p + 1, MONETDB5_PASSWDHASH) != 0) {
+ fprintf(stderr, "set: passphrase hash
'%s' incompatible, "
+ "expected '%s'\n",
+ h, MONETDB5_PASSWDHASH);
+ return(1);
+ }
+ *q = '}';
+ dohash = 0;
+ }
}
- kv = findConfKey(ckv, "controlport");
- if (kv != NULL && kv->ival == oport + 1) {
- oport = atoi(p);
- snprintf(buf, sizeof(buf), "%d", oport + 1);
- property = "controlport";
- p = buf;
+ if (dohash == 1) {
+ p = mcrypt_BackendSum(p, strlen(p));
+ snprintf(h, sizeof(h), "{%s}%s", MONETDB5_PASSWDHASH,
p);
+ p = h;
}
}
if ((p = setConfVal(kv, p)) != NULL) {
diff --git a/tools/merovingian/daemon/client.c
b/tools/merovingian/daemon/client.c
--- a/tools/merovingian/daemon/client.c
+++ b/tools/merovingian/daemon/client.c
@@ -32,6 +32,7 @@
#endif
#include <msabaoth.h>
+#include <mcrypt.h>
#include <stream.h>
#include <stream_socket.h>
#include <utils/utils.h> /* freeConfFile */
@@ -41,6 +42,7 @@
#include "forkmserver.h"
#include "proxy.h"
#include "multiplex-funnel.h"
+#include "controlrunner.h"
#include "client.h"
typedef struct _mplist {
@@ -55,6 +57,7 @@ handleClient(int sock, char isusock)
{
stream *fdin, *fout;
char buf[8096];
+ char chal[32];
char *user = NULL, *algo = NULL, *passwd = NULL, *lang = NULL;
char *database = NULL, *s;
char dbmod[64];
@@ -68,6 +71,7 @@ handleClient(int sock, char isusock)
char mydoproxy;
sabdb redirs[24]; /* do we need more? */
int r = 0;
+ char *algos;
fdin = socket_rastream(sock, "merovingian<-client (read)");
if (fdin == 0)
@@ -103,17 +107,22 @@ handleClient(int sock, char isusock)
}
}
- /* note that we claim to speak proto 8 here */
- mnstr_printf(fout, "%s:merovingian:8:%s:%s:",
- "void", /* some bs */
- "md5,plain", /* we actually don't look at the password
*/
+ /* note: since Jan2012 we speak proto 9 for control connections */
+ chal[31] = '\0';
+ generateSalt(chal, 31);
+ algos = mcrypt_getHashAlgorithms();
+ mnstr_printf(fout, "%s:merovingian:9:%s:%s:%s:",
+ chal,
+ algos,
#ifdef WORDS_BIGENDIAN
- "BIG"
+ "BIG",
#else
- "LIT"
+ "LIT",
#endif
+ MONETDB5_PASSWDHASH
);
mnstr_flush(fout);
+ free(algos);
/* get response */
buf[0] = '\0';
@@ -270,6 +279,15 @@ handleClient(int sock, char isusock)
return(NO_ERR);
}
+ if (strcmp(lang, "control") == 0) {
+ /* handle control client */
+ if (control_authorise(host, chal, algo, passwd, sock))
+ control_handleclient(sock, host);
+ close_stream(fout);
+ close_stream(fdin);
+ return(NO_ERR);
+ }
+
if (strcmp(lang, "resolve") == 0) {
/* ensure the pattern ends with '/\*' such that we force a
* remote entry, including those for local databases, this
diff --git a/tools/merovingian/daemon/controlrunner.c
b/tools/merovingian/daemon/controlrunner.c
--- a/tools/merovingian/daemon/controlrunner.c
+++ b/tools/merovingian/daemon/controlrunner.c
@@ -34,6 +34,7 @@
#include <pthread.h>
#include <msabaoth.h>
+#include <mcrypt.h>
#include <utils/utils.h>
#include <utils/properties.h>
#include <utils/database.h>
@@ -41,7 +42,6 @@
#include "merovingian.h"
#include "discoveryrunner.h" /* broadcast, remotedb */
-#include "peering.h"
#include "forkmserver.h"
#include "controlrunner.h"
@@ -115,43 +115,561 @@ recvWithTimeout(int msgsock, char *buf,
return(recv(msgsock, buf, buflen, 0));
}
-void
-controlRunner(void *d)
+char
+control_authorise(
+ const char *host,
+ const char *chal,
+ const char *algo,
+ const char *passwd,
+ int sock)
{
- int *socks = (int *)d;
- int usock = socks[0];
- int tsock = socks[1];
- int sock = -1;
+ char *pwd;
+ char buf[24];
+ size_t len;
+
+ if (getConfNum(_mero_props, "control") == 0 ||
+ getConfVal(_mero_props, "passphrase") == NULL)
+ {
+ Mfprintf(_mero_ctlout, "%s: remote control disabled\n", host);
+ len = snprintf(buf, sizeof(buf), "access denied\n");
+ send(sock, buf, len, 0);
+ close(sock);
+ return 0;
+ }
+
+ pwd = mcrypt_hashPassword(algo,
+ getConfVal(_mero_props, "passphrase"), chal);
+ if (strcmp(pwd, passwd) != 0) {
+ Mfprintf(_mero_ctlout, "%s: permission denied "
+ "(bad passphrase)\n", host);
+ len = snprintf(buf, sizeof(buf), "access denied\n");
+ send(sock, buf, len, 0);
+ close(sock);
+ return 0;
+ }
+
+ len = snprintf(buf, sizeof(buf), "OK\n");
+ send(sock, buf, len, 0);
+
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list