Exemple #1
0
static void source_agent_env(enum agent id)
{
    struct agent_data_t data;
    int ret = envoy_get_agent(id, &data, AGENT_ENVIRON);
    if (ret < 0)
        warn("failed to fetch envoy agent");

    switch (data.status) {
    case ENVOY_STOPPED:
    case ENVOY_STARTED:
    case ENVOY_RUNNING:
        break;
    case ENVOY_FAILED:
        warnx("agent failed to start, check envoyd's log");
    case ENVOY_BADUSER:
        warnx("connection rejected, user is unauthorized to use this agent");
    }

    if (data.type == AGENT_GPG_AGENT) {
        _cleanup_gpg_ struct gpg_t *agent = gpg_agent_connection(data.gpg, NULL);
        gpg_update_tty(agent);
    }

    if (data.gpg[0]) {
        putenvf("GPG_AGENT_INFO=%s", data.gpg);
    } else {
        unsetenv("GPG_AGENT_INFO");
    }

    putenvf("SSH_AUTH_SOCK=%s", data.sock);
}
Exemple #2
0
static int unlock(const struct agent_data_t *data, char *password)
{
    if (data->type != AGENT_GPG_AGENT)
        errx(EXIT_FAILURE, "only gpg-agent supports this operation");

    _cleanup_gpg_ struct gpg_t *agent = gpg_agent_connection(data->gpg, NULL);
    if (!agent)
        err(EXIT_FAILURE, "failed to connect to GPG_AUTH_SOCK");

    if (!password)
        read_password(&password);

    const struct fingerprint_t *fgpt = gpg_keyinfo(agent);
    for (; fgpt; fgpt = fgpt->next) {
        if (fgpt->flags & KEY_DISABLED)
            continue;

        if (gpg_preset_passphrase(agent, fgpt->fingerprint, -1, password) < 0) {
            warnx("failed to unlock key '%s'", fgpt->fingerprint);
            return 1;
        }
    }

    return 0;
}
Exemple #3
0
/* PAM entry point for authentication verification */
PAM_EXTERN int pam_sm_authenticate(pam_handle_t _unused_ *ph, int _unused_ flags,
                                   int _unused_ argc, const char _unused_ **argv)
{
    struct agent_data_t data;
    const struct passwd *pwd;
    const char *user, *password;
    enum agent id = AGENT_DEFAULT;
    int ret;

    ret = pam_get_user(ph, &user, NULL);
    if (ret != PAM_SUCCESS) {
        syslog(PAM_LOG_ERR, "pam-envoy: couldn't get the user name: %s",
               pam_strerror(ph, ret));
        return PAM_SERVICE_ERR;
    }

    pwd = getpwnam(user);
    if (!pwd) {
        syslog(PAM_LOG_ERR, "pam-envoy: error looking up user information: %s",
               strerror(errno));
        return PAM_SERVICE_ERR;
    }

    /* Look up the password */
    ret = pam_get_item(ph, PAM_AUTHTOK, (const void**)&password);
    if (ret != PAM_SUCCESS || password == NULL) {
        if (ret == PAM_SUCCESS)
            syslog(PAM_LOG_WARN, "pam-envoy: no password is available for user");
        else
            syslog(PAM_LOG_WARN, "pam-envoy: no password is available for user: %s",
                   pam_strerror(ph, ret));
        return PAM_SUCCESS;
    }

    if (pam_get_agent(&data, id, pwd->pw_uid, pwd->pw_gid) < 0) {
        syslog(PAM_LOG_WARN, "pam-envoy: failed to get agent for user");
        return PAM_SUCCESS;
    }

    if (data.status == ENVOY_RUNNING && data.type == AGENT_GPG_AGENT) {
        _cleanup_gpg_ struct gpg_t *agent = gpg_agent_connection(data.gpg);

        if (password) {
            const struct fingerprint_t *fpt = gpg_keyinfo(agent);
            for (; fpt; fpt = fpt->next) {
                if (gpg_preset_passphrase(agent, fpt->fingerprint, -1, password) < 0)
                    syslog(PAM_LOG_ERR, "failed to unlock '%s'", fpt->fingerprint);
            }
        }

        gpg_close(agent);
    }

    return PAM_SUCCESS;
}
Exemple #4
0
static void reload_agent(struct agent_data_t *data)
{
    if (data->type != AGENT_GPG_AGENT)
        errx(EXIT_FAILURE, "only gpg-agent supports this operation");

    _cleanup_gpg_ struct gpg_t *agent = gpg_agent_connection(data->gpg, NULL);
    if (!agent)
        err(EXIT_FAILURE, "failed to connect to GPG_AUTH_SOCK");

    gpg_reload_agent(agent);
}
Exemple #5
0
static void source_env(struct agent_data_t *data)
{
    if (data->type == AGENT_GPG_AGENT) {
        _cleanup_gpg_ struct gpg_t *agent = gpg_agent_connection(data->gpg);
        if (!agent)
            warn("failed to connect to GPG_AUTH_SOCK");
        else
            gpg_update_tty(agent);
    }

    putenvf("SSH_AUTH_SOCK=%s", data->sock);
}
Exemple #6
0
/* PAM entry point for session creation */
PAM_EXTERN int pam_sm_open_session(pam_handle_t *ph, int _unused_ flags,
                                   int argc, const char **argv)
{
    struct agent_data_t data;
    const struct passwd *pwd;
    const char *user;
    enum agent id = AGENT_DEFAULT;
    int ret;

    ret = pam_get_user(ph, &user, NULL);
    if (ret != PAM_SUCCESS) {
        syslog(PAM_LOG_ERR, "pam-envoy: couldn't get the user name: %s",
               pam_strerror(ph, ret));
        return PAM_SERVICE_ERR;
    }

    pwd = getpwnam(user);
    if (!pwd) {
        syslog(PAM_LOG_ERR, "pam-envoy: error looking up user information: %s",
               strerror(errno));
        return PAM_SERVICE_ERR;
    }

    if (argc > 1) {
        syslog(PAM_LOG_WARN, "pam-envoy: too many arguments");
        return PAM_SUCCESS;
    } else if (argc == 1) {
        id = lookup_agent(argv[0]);
    }

    if (pam_get_agent(&data, id, pwd->pw_uid, pwd->pw_gid) < 0) {
        syslog(PAM_LOG_WARN, "pam-envoy: failed to get agent for user");
        return PAM_SUCCESS;
    }

    if (data.type == AGENT_GPG_AGENT) {
        _cleanup_gpg_ struct gpg_t *agent = gpg_agent_connection(data.gpg);
        gpg_update_tty(agent);

        pam_setenv(ph, "GPG_AGENT_INFO=%s", data.gpg);
    }

    pam_setenv(ph, "SSH_AUTH_SOCK=%s", data.sock);
    pam_setenv(ph, "SSH_AGENT_PID=%d", data.pid);

    return PAM_SUCCESS;
}