Skip to content

Commit

Permalink
Change munge authentication message
Browse files Browse the repository at this point in the history
The munge authentication message previously consisted of
the local and remote addresses of the transport between
the two peers. This message presumed that both peers see
the same addresses (albeit swapped). This assumption is
false in many routed and NAT'd environments.

This patch changes the message to "MungeAuthentication"
which is validated by the receiving peer. In order to
support backward compatability with older plugins, an
option 'compat' has been added. This option, when set, will
use the previous message format so that newer aggregators
can connect to older samplers. The receive path supports
either, specifically, if the new message doesn't match
it tries the old format.
  • Loading branch information
tom95858 committed Jul 13, 2023
1 parent 7868bb5 commit 5348e27
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 50 deletions.
19 changes: 13 additions & 6 deletions ldms/man/ldms_auth_munge.man
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,22 @@ ldms_auth_munge \- LDMS authentication using munge
.SH SYNOPSIS
.HP
.I ldms_app
.BI "-a munge [-A socket=" PATH ]
.BI "-a munge [-A socket=PATH,compat=1 ]"


.SH DESCRIPTION
\fBldms_auth_munge\fR relies on \fBmunge\fR service (see \fBmunge\fR(7)) to
authenticate users. Munge daemon (\fBmunged\fR) must be up and running. The
optional \fBsocket\fR option can be used to specify the path to munged unix
domain socket in the case that munged wasn't using the default path.

\fBldms_auth_munge\fR relies on the \fBmunge\fR service (see \fBmunge\fR(7)) to
authenticate users. The munge daemon (\fBmunged\fR) must be up and running.

The optional \fBsocket\fR option can be used to specify the path to
the munged unix domain socket in the case that munged wasn't using the
default path or there are multiple munge domains configured.

The optional \fBcompat\fR option is used to be backward compatible
with older versions of the auth plugin that sent authentication
messages that assumed that the remote and local IP addresses would be
the same on both sides of the connection. This is not true in many
environments.

.SH SEE ALSO
\fBmunge\fR(7), \fBmunged\fR(8)
98 changes: 56 additions & 42 deletions ldms/src/auth/ldms_auth_munge.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ struct ldms_auth_munge {
struct ldms_auth base;
munge_ctx_t mctx;
char *local_cred;
int compat;
struct sockaddr_storage lsin;
struct sockaddr_storage rsin;
socklen_t sin_len;
Expand All @@ -110,7 +111,7 @@ static
ldms_auth_t __auth_munge_new(ldms_auth_plugin_t plugin,
struct attr_value_list *av_list)
{
const char *munge_sock;
const char *value;
struct ldms_auth_munge *a;
munge_ctx_t mctx;
munge_err_t merr;
Expand All @@ -128,16 +129,20 @@ ldms_auth_t __auth_munge_new(ldms_auth_plugin_t plugin,
goto err1;
}

munge_sock = av_value(av_list, "socket");
if (munge_sock) {
merr = munge_ctx_set(mctx, MUNGE_OPT_SOCKET, munge_sock);
value = av_value(av_list, "socket");
if (value) {
merr = munge_ctx_set(mctx, MUNGE_OPT_SOCKET, value);
if (merr != EMUNGE_SUCCESS) {
LOG_ERROR("Failed to set MUNGE context. %s\n",
munge_strerror(merr));
goto err2;
}
}

value = av_value(av_list, "compat");
if (value)
a->compat = atoi(value);

/* Test munge connection */
merr = munge_encode(&test_cred, mctx, NULL, 0);
if (merr != EMUNGE_SUCCESS) {
Expand Down Expand Up @@ -196,33 +201,44 @@ int __auth_munge_xprt_bind(ldms_auth_t auth, ldms_t xprt)
return 0;
}

#define MUNGE_AUTH_MSG "MungeAuthenticate"

static
int __auth_munge_xprt_begin(ldms_auth_t auth, ldms_t xprt)
{
struct ldms_auth_munge *a = (void*)auth;
munge_err_t merr;
int rc;
int len;
a->sin_len = sizeof(a->lsin);
rc = ldms_xprt_sockaddr(xprt, (void*)&a->lsin,
(void*)&a->rsin, &a->sin_len);
if (rc) {
LOG_ERROR("Failed to get the socket addresses. Error %d\n", rc);
return rc;
}
/*
* zap_rdma from OVIS-4.3.7 and earlier has a bug that swaps
* local/remote addresses. Since the old peers expect to receive the
* swapped address, in order to be compatible with them, we have to send
* the swapped address in the case of rdma transport.
*/
merr = (strncmp(xprt->name, "rdma", 4) == 0)?
munge_encode(&a->local_cred, a->mctx, &a->rsin, a->sin_len):
munge_encode(&a->local_cred, a->mctx, &a->lsin, a->sin_len);

if (a->compat) {
/*
* This uses the older payload of the local/remote sin
* to be compatabile with OVIS 4.3.11 and earlier
*/
a->sin_len = sizeof(a->lsin);
rc = ldms_xprt_sockaddr(xprt, (void*)&a->lsin,
(void*)&a->rsin, &a->sin_len);
if (rc) {
LOG_ERROR("Failed to get the socket addresses. Error %d\n", rc);
return rc;
}
/*
* zap_rdma from OVIS-4.3.7 and earlier has a bug that swaps
* local/remote addresses. Since the old peers expect to receive the
* swapped address, in order to be compatible with them, we have to send
* the swapped address in the case of rdma transport.
*/
merr = (strncmp(xprt->name, "rdma", 4) == 0)?
munge_encode(&a->local_cred, a->mctx, &a->rsin, a->sin_len):
munge_encode(&a->local_cred, a->mctx, &a->lsin, a->sin_len);
} else {
merr = munge_encode(&a->local_cred, a->mctx,
MUNGE_AUTH_MSG, sizeof(MUNGE_AUTH_MSG));
}
if (merr) {
LOG_ERROR("munge_encode() failed. %s\n", munge_strerror(merr));
return EBADR; /* bad request */
return EBADR;
}
len = strlen(a->local_cred);
rc = ldms_xprt_auth_send(xprt, a->local_cred, len + 1);
Expand All @@ -242,22 +258,24 @@ int __auth_munge_xprt_recv_cb(ldms_auth_t auth, ldms_t xprt,
void *payload = NULL;
uid_t uid;
gid_t gid;
munge_err_t merr;
int len;
int cmp;
munge_err_t merr;
if (data[data_len-1] != 0)
goto invalid;
int rc = EINVAL;

merr = munge_decode(data, a->mctx, &payload, &len, &uid, &gid);
if (merr != EMUNGE_SUCCESS) {
LOG_ERROR("munge_decode() failed. %s\n", munge_strerror(merr));
goto invalid;
goto out;
}
if (len != sizeof(*sin)) {
LOG_ERROR("Bad payload\n");
goto invalid; /* bad payload */

/* Check the authentication message */
if (0 == strcmp(payload, MUNGE_AUTH_MSG)) {
rc = 0;
goto out;
}

/* check if addr match */
/* Check the expected peer address (compatability mode) */
sin = payload;
/*
* zap_rdma from OVIS-4.3.7 and earlier has a bug that swaps
Expand All @@ -266,24 +284,20 @@ int __auth_munge_xprt_recv_cb(ldms_auth_t auth, ldms_t xprt,
* swapped address in the case of rdma transport.
*/
cmp = (strncmp(xprt->name, "rdma", 4) == 0)?
memcmp(sin, &a->lsin, sizeof(*sin)):
memcmp(sin, &a->rsin, sizeof(*sin));
memcmp(sin, &a->lsin, sizeof(*sin)):
memcmp(sin, &a->rsin, sizeof(*sin));
if (cmp != 0) {
LOG_ERROR("bad address.\n");
goto invalid; /* bad addr */
LOG_ERROR("Unexpected authentication message payload.\n");
goto out;
}
/* verified */
/* Cache the peer's verified uid and gid in the transport handle. */
xprt->ruid = uid;
xprt->rgid = gid;
rc = 0;

out:
free(payload);
ldms_xprt_auth_end(xprt, 0);
return 0;

invalid:
if (payload)
free(payload);
ldms_xprt_auth_end(xprt, EINVAL);
ldms_xprt_auth_end(xprt, rc);
return 0;
}

Expand All @@ -310,7 +324,7 @@ int __auth_munge_cred_get(ldms_auth_t auth, ldms_cred_t cred)
ldms_auth_plugin_t __ldms_auth_plugin_get()
{
if (!munge_log) {
munge_log = ovis_log_register("auth_munge",
munge_log = ovis_log_register("auth.munge",
"Messages for ldms_auth_munge");
if (!munge_log) {
LOG_ERROR("Failed to register auth_munge's log. "
Expand Down
2 changes: 1 addition & 1 deletion ldms/src/auth/ldms_auth_naive.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ struct ldms_auth_naive {
ldms_auth_plugin_t __ldms_auth_plugin_get()
{
if (!nlog) {
nlog = ovis_log_register("auth_naive", "Messages for auth_naive");
nlog = ovis_log_register("auth.naive", "Messages for auth_naive");
if (!nlog) {
LOG_ERROR("Failed to register the auth_naive log.\n");
}
Expand Down
2 changes: 1 addition & 1 deletion ldms/src/auth/ldms_auth_ovis.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ struct ldms_auth_ovis {
ldms_auth_plugin_t __ldms_auth_plugin_get()
{
if (!aolog) {
aolog = ovis_log_register("auth_ovis", "Messages for ldms_auth_ovis");
aolog = ovis_log_register("auth.ovis", "Messages for ldms_auth_ovis");
if (!aolog) {
LOG_ERROR("Failed to register %s's log. Error %d\n",
__FILE__, errno);
Expand Down

0 comments on commit 5348e27

Please sign in to comment.