extern int
crypto_verify_sign(void * key, char *buffer, unsigned int buf_size,
		   char *signature, unsigned int sig_size)
{
	int retry = RETRY_COUNT;
	uid_t uid;
	gid_t gid;
	void *buf_out = NULL;
	int   buf_out_size;
	int   rc = 0;
	munge_err_t err;
	munge_ctx_t ctx = (munge_ctx_t) key;

    again:
	err = munge_decode(signature, ctx, &buf_out, &buf_out_size,
			   &uid, &gid);

	if (err != EMUNGE_SUCCESS) {
		if ((err == EMUNGE_SOCKET) && retry--) {
			debug("Munge decode failed: %s (retrying ...)",
			      munge_ctx_strerror(ctx));
			usleep(RETRY_USEC);	/* Likely munged too busy */
			goto again;
		}
		if (err == EMUNGE_SOCKET)
			error("If munged is up, restart with --num-threads=10");

#ifdef MULTIPLE_SLURMD
		if (err != EMUNGE_CRED_REPLAYED) {
			rc = err;
			goto end_it;
		} else {
			debug2("We had a replayed crypto, but this "
			       "is expected in multiple slurmd mode.");
		}
#else
		if (err == EMUNGE_CRED_REPLAYED)
			rc = ESIG_CRED_REPLAYED;
		else
			rc = err;
		goto end_it;
#endif
	}


	if ((uid != slurm_user) && (uid != 0)) {
		error("crypto/munge: Unexpected uid (%d) != SLURM uid (%d)",
		      (int) uid, (int) slurm_user);
		rc = ESIG_BAD_USERID;
	}
	else if (buf_size != buf_out_size)
		rc = ESIG_BUF_SIZE_MISMATCH;
	else if (memcmp(buffer, buf_out, buf_size))
		rc = ESIG_BUF_DATA_MISMATCH;
end_it:
	if (buf_out)
		free(buf_out);
	return rc;
}
Esempio n. 2
0
File: msg.c Progetto: artpol84/slurm
static char *_decrypt(char *msg, uid_t *uid)
{
	void *buf_out = NULL;
	int buf_out_size = 0, err;
	gid_t gid;

	err = munge_decode(msg, ctx, &buf_out, &buf_out_size, uid, &gid);
	if (err != EMUNGE_SUCCESS) {
		info("slurmctld/nonstop: munge_decode error: %s",
		     munge_strerror(err));
		xfree(buf_out);
	}
	return (char *) buf_out;
}
Esempio n. 3
0
/* Checkauth is called in the handling of a TATTACH request with valid afid.
 * Validate the credential that should now be dangling off afid.
 * Returns 1=success (auth is good, send RATTACH)
 *         0=failure (send RLERROR with np_rerror ())
 */
static int
checkauth(Npfid *fid, Npfid *afid, char *aname)
{
    da_t da;
    int ret = 0;
    char a[128];

    if (!fid || !afid || !afid->aux) {
        np_uerror (EIO);
        err ("checkauth: invalid arguments");
        goto done;
    }
    da = afid->aux;
    assert (da->magic == DIOD_AUTH_MAGIC);

    snprintf (a, sizeof(a), "checkauth(%s@%s:%s)", fid->user->uname,
              np_conn_get_client_id (fid->conn), aname ? aname : "<NULL>");
#if HAVE_LIBMUNGE
    if (!da->datastr) {
        msg ("%s: munge cred missing", a);
        goto done;
    }
    da->mungerr = munge_decode (da->datastr, da->mungectx, NULL, 0,
                                &da->mungeuid, NULL);
    if (da->mungerr != EMUNGE_SUCCESS) {
        np_uerror (EPERM);
        err ("%s: munge cred decode: %s", a, munge_strerror (da->mungerr));
        goto done;
    }
    assert (afid->user->uid == fid->user->uid); /* enforced in np_attach */
    if (afid->user->uid != da->mungeuid) {
        np_uerror (EPERM);
        err ("%s: munge cred uid mismatch: %d", a, da->mungeuid);
        goto done;
    }
    ret = 1;
#else
    np_uerror (EPERM);
    err ("%s: diod was not built with support for auth services", a);
#endif
done:
    return ret;
}
Esempio n. 4
0
static int authenticate(opal_sec_cred_t *cred)
{
    munge_err_t rc;
    
    opal_output_verbose(2, opal_sec_base_framework.framework_output,
                        "sec: munge validate_cred %s", cred->credential);

    /* parse the inbound string */
    if (EMUNGE_SUCCESS != (rc = munge_decode(cred->credential, NULL, NULL, NULL, NULL, NULL))) {
        opal_output_verbose(2, opal_sec_base_framework.framework_output,
                            "sec: munge failed to decode credential: %s",
                            munge_strerror(rc));
        return OPAL_ERR_AUTHENTICATION_FAILED;
    }

    opal_output_verbose(2, opal_sec_base_framework.framework_output,
                        "sec: munge credential valid");
    return OPAL_SUCCESS;
}
Esempio n. 5
0
/*
 * Decode the munge encoded credential `m_str' placing results, if validated,
 * into slurm credential `c'
 */
static int
_decode_cred(slurm_auth_credential_t *c, char *socket)
{
	int retry = 2;
	munge_err_t e;
	munge_ctx_t ctx;

	if (c == NULL)
		return SLURM_ERROR;

	xassert(c->magic == MUNGE_MAGIC);

	if (c->verified)
		return SLURM_SUCCESS;

	if ((ctx = munge_ctx_create()) == NULL) {
		error("munge_ctx_create failure");
		return SLURM_ERROR;
	}
	if (socket &&
	    (munge_ctx_set(ctx, MUNGE_OPT_SOCKET, socket) != EMUNGE_SUCCESS)) {
		error("munge_ctx_set failure");
		munge_ctx_destroy(ctx);
		return SLURM_ERROR;
	}

    again:
	c->buf = NULL;
	e = munge_decode(c->m_str, ctx, &c->buf, &c->len, &c->uid, &c->gid);
	if (e != EMUNGE_SUCCESS) {
		if (c->buf) {
			free(c->buf);
			c->buf = NULL;
		}
		if ((e == EMUNGE_SOCKET) && retry--) {
			error ("Munge decode failed: %s (retrying ...)",
				munge_ctx_strerror(ctx));
#ifdef MULTIPLE_SLURMD
			sleep(1);
#endif
			goto again;
		}
#ifdef MULTIPLE_SLURMD
		/* In multple slurmd mode this will happen all the
		 * time since we are authenticating with the same
		 * munged.
		 */
		if (e != EMUNGE_CRED_REPLAYED) {
#endif
			/*
			 *  Print any valid credential data
			 */
			error ("Munge decode failed: %s",
			       munge_ctx_strerror(ctx));
			_print_cred(ctx);
			if (e == EMUNGE_CRED_REWOUND)
				error("Check for out of sync clocks");

			c->cr_errno = e + MUNGE_ERRNO_OFFSET;
#ifdef MULTIPLE_SLURMD
		} else {
			debug2("We had a replayed cred, "
			       "but this is expected in multiple "
			       "slurmd mode.");
			e = 0;
		}
#endif
		goto done;
	}

	c->verified = true;

     done:
	munge_ctx_destroy(ctx);
	return e ? SLURM_ERROR : SLURM_SUCCESS;
}
Esempio n. 6
0
File: server.c Progetto: RPI-HPC/cq
int main(int argc, char *argv[])
{
	int rc = 1;
	int ret;

	signal(SIGINT, signal_handler);

	int c;
	char ep[28];
	const char *host = "0.0.0.0";
	char *ohost = NULL;
	int port = 48005;

	void *ctx = NULL;
	void *fe = NULL;
	void *be = NULL;

	while ((c = getopt (argc, argv, "h:p:")) != -1)
		switch (c) {
			case 'h':
				ohost = strdup(optarg);
				break;
			case 'p':
				port = atoi(optarg);
		}

	pid_t pid = spawn_worker();
	printf("Spawned worker w/ pid %d\n", pid);

	if (ohost != NULL)
		host = ohost;

	snprintf(ep, 28, "tcp://%s:%d", host, port);
	if (ohost != NULL)
		free(ohost);

	ctx = zmq_ctx_new();
	if (ctx == NULL)
		goto finished;

	fe = zmq_socket(ctx, ZMQ_ROUTER);
	if (fe == NULL)
		goto finished;

	be = zmq_socket(ctx, ZMQ_DEALER);
	if (be == NULL)
		goto finished;

	ret = zmq_bind(fe, ep);
	if (ret < 0) {
		fprintf(stderr, "Unable to bind socket\n");
		goto finished;
	}

	zmq_bind(be, WORKER_IPC);

	zmq_pollitem_t items [] = {
		{ fe, 0, ZMQ_POLLIN, 0 },
		{ be,  0, ZMQ_POLLIN, 0 }
	};

	printf("Waiting for messages...\n");

	void *cred;
	void *buf;
	int len;

	while (1) {
		zmq_msg_t message;
		zmq_msg_t out;
		ret = zmq_poll(items, 2, -1);

		if (ret < 0)
			if (errno == EINTR) {
				break;
			}

		if (items[0].revents & ZMQ_POLLIN) {
			while (1) {
				zmq_msg_init(&message);
				zmq_msg_recv(&message, fe, 0);
				int more = zmq_msg_more(&message);

				if (!more) {
					cred = zmq_msg_data(&message);

					munge_err_t err = munge_decode(cred, NULL, &buf, &len, NULL, NULL);
					if (err != EMUNGE_SUCCESS)
						fprintf(stderr, "Munge failed to decode\n");

					zmq_msg_init_data(&out, buf, len, free_buf, NULL);
					zmq_msg_send(&out, be, 0);
					zmq_msg_close(&out);
				} else {
					zmq_msg_send(&message, be, more? ZMQ_SNDMORE: 0);
				}

				zmq_msg_close(&message);
				if (!more)
					break;
			}
		}
		if (items[1].revents & ZMQ_POLLIN) {
			while (1) {
				zmq_msg_init(&message);
				zmq_msg_recv(&message, be, 0);
				int more = zmq_msg_more(&message);
				zmq_msg_send(&message, fe, more? ZMQ_SNDMORE: 0);
				zmq_msg_close(&message);
				if (!more)
					break;
			}
		}
	}

	rc = 0;

	printf("Shutting down\n");

finished:
	printf("Stopping workers...\n");

	pid_t w;
	int status;
	do {
		w = waitpid(pid, &status, 0);
		if (w == -1) {
			fprintf(stderr, "Unable to wait\n");
			break;
		}
	} while (!WIFEXITED(status) && !WIFSIGNALED(status));

	printf("Finishing cleanup\n");
	ret = zmq_close(fe);
	if (ret < 0)
		fprintf(stderr, "Failed to close frontend socket\n");

	ret = zmq_close(be);
	if (ret < 0)
		fprintf(stderr, "Failed to close backend socket\n");

	ret = zmq_ctx_destroy(ctx);
	if(ret < 0)
		fprintf(stderr, "Failed to stop ZMQ\n");

	return rc;
}
Esempio n. 7
0
File: remunge.c Progetto: dun/munge
void *
remunge (conf_t conf)
{
/*  Worker thread responsible for encoding/decoding/validating credentials.
 */
    tdata_t         tdata;
    int             cancel_state;
    unsigned long   n;
    unsigned long   got_encode_err;
    unsigned long   got_decode_err;
    struct timeval  t_start;
    struct timeval  t_stop;
    double          delta;
    munge_err_t     e;
    char           *cred;
    void           *data;
    int             dlen;
    uid_t           uid;
    gid_t           gid;

    tdata = create_tdata (conf);

    pthread_cleanup_push ((thread_cleanup_f) remunge_cleanup, tdata);

    if ((errno = pthread_mutex_lock (&conf->mutex)) != 0) {
        log_errno (EMUNGE_SNAFU, LOG_ERR, "Failed to lock mutex");
    }
    while (conf->num_creds - conf->shared.num_creds_done > 0) {

        pthread_testcancel ();

        if ((errno = pthread_setcancelstate
                    (PTHREAD_CANCEL_DISABLE, &cancel_state)) != 0) {
            log_errno (EMUNGE_SNAFU, LOG_ERR,
                "Failed to disable thread cancellation");
        }
        n = ++conf->shared.num_creds_done;

        if ((errno = pthread_mutex_unlock (&conf->mutex)) != 0) {
            log_errno (EMUNGE_SNAFU, LOG_ERR, "Failed to unlock mutex");
        }
        got_encode_err = 0;
        got_decode_err = 0;
        data = NULL;

        GET_TIMEVAL (t_start);
        e = munge_encode(&cred, tdata->ectx, conf->payload, conf->num_payload);
        GET_TIMEVAL (t_stop);

        delta = DIFF_TIMEVAL (t_stop, t_start);
        if (delta > conf->warn_time) {
            output_msg ("Credential #%lu encoding took %0.3f seconds",
                n, delta);
        }
        if (e != EMUNGE_SUCCESS) {
            output_msg ("Credential #%lu encoding failed: %s (err=%d)",
                n, munge_ctx_strerror (tdata->ectx), e);
            ++got_encode_err;
        }
        else if (conf->do_decode) {

            GET_TIMEVAL (t_start);
            e = munge_decode (cred, tdata->dctx, &data, &dlen, &uid, &gid);
            GET_TIMEVAL (t_stop);

            delta = DIFF_TIMEVAL (t_stop, t_start);
            if (delta > conf->warn_time) {
                output_msg ("Credential #%lu decoding took %0.3f seconds",
                    n, delta);
            }
            if (e != EMUNGE_SUCCESS) {
                output_msg ("Credential #%lu decoding failed: %s (err=%d)",
                    n, munge_ctx_strerror (tdata->dctx), e);
                ++got_decode_err;
            }

/*  FIXME:
 *    The following block does some validating of the decoded credential.
 *    It should have a cmdline option to enable this validation check.
 *    The decode ctx should also be checked against the encode ctx.
 *    This becomes slightly more difficult in that it must also take
 *    into account the default field settings.
 *
 *    This block should be moved into a separate function (or more).
 *    The [cred], [data], [dlen], [uid], and [gid] vars could be placed
 *    into the tdata struct to facilitate parameter passing.
 */
#if 0
            else if (conf->do_validate) {
                if (getuid () != uid) {
                output_msg (
                    "Credential #%lu UID %d does not match process UID %d",
                    n, uid, getuid ());
                }
                if (getgid () != gid) {
                    output_msg (
                        "Credential #%lu GID %d does not match process GID %d",
                        n, gid, getgid ());
                }
                if (conf->num_payload != dlen) {
                    output_msg (
                        "Credential #%lu payload length mismatch (%d/%d)",
                        n, conf->num_payload, dlen);
                }
                else if (data && memcmp (conf->payload, data, dlen) != 0) {
                    output_msg ("Credential #%lu payload mismatch", n);
                }
            }
#endif /* 0 */

            /*  The 'data' parm can still be set on certain munge errors.
             */
            if (data != NULL) {
                free (data);
            }
        }
        if (cred != NULL) {
            free (cred);
        }
        if ((errno = pthread_setcancelstate
                    (cancel_state, &cancel_state)) != 0) {
            log_errno (EMUNGE_SNAFU, LOG_ERR,
                "Failed to enable thread cancellation");
        }
        if ((errno = pthread_mutex_lock (&conf->mutex)) != 0) {
            log_errno (EMUNGE_SNAFU, LOG_ERR, "Failed to lock mutex");
        }
        conf->shared.num_encode_errs += got_encode_err;
        conf->shared.num_decode_errs += got_decode_err;
    }
    pthread_cleanup_pop (1);
    return (NULL);
}