コード例 #1
0
ファイル: pwupd.c プロジェクト: FreeBSDFoundation/freebsd
static int
pw_update(struct passwd * pwd, char const * user)
{
	struct passwd	*pw = NULL;
	struct passwd	*old_pw = NULL;
	int		 rc, pfd, tfd;

	if ((rc = pwdb_check()) != 0)
		return (rc);

	if (pwd != NULL)
		pw = pw_dup(pwd);

	if (user != NULL)
		old_pw = GETPWNAM(user);

	if (pw_init(conf.etcpath, NULL))
		err(1, "pw_init()");
	if ((pfd = pw_lock()) == -1) {
		pw_fini();
		err(1, "pw_lock()");
	}
	if ((tfd = pw_tmp(-1)) == -1) {
		pw_fini();
		err(1, "pw_tmp()");
	}
	if (pw_copy(pfd, tfd, pw, old_pw) == -1) {
		pw_fini();
		close(tfd);
		err(1, "pw_copy()");
	}
	fsync(tfd);
	close(tfd);
	/*
	 * in case of deletion of a user, the whole database
	 * needs to be regenerated
	 */
	if (pw_mkdb(pw != NULL ? pw->pw_name : NULL) == -1) {
		pw_fini();
		err(1, "pw_mkdb()");
	}
	free(pw);
	pw_fini();

	return (0);
}
コード例 #2
0
ファイル: auth_chap_md5.c プロジェクト: china-east-soft/CSSV
static void chap_send_failure(struct chap_auth_data_t *ad)
{
    struct chap_failure_t msg = {
        .hdr.proto = htons(PPP_CHAP),
        .hdr.code = CHAP_FAILURE,
        .hdr.id = ad->id,
        .hdr.len = htons(sizeof(msg) - 1 - 2),
        .message = MSG_FAILURE,
    };

    if (conf_ppp_verbose)
        log_ppp_info2("send [CHAP Failure id=%x \"%s\"]\n", msg.hdr.id, MSG_FAILURE);

    ppp_chan_send(ad->ppp, &msg, ntohs(msg.hdr.len) + 2);
}

static void chap_send_success(struct chap_auth_data_t *ad)
{
    struct chap_success_t msg =	{
        .hdr.proto = htons(PPP_CHAP),
        .hdr.code = CHAP_SUCCESS,
        .hdr.id = ad->id,
        .hdr.len = htons(sizeof(msg)-1-2),
        .message = MSG_SUCCESS,
    };

    if (conf_ppp_verbose)
        log_ppp_info2("send [CHAP Success id=%x \"%s\"]\n", msg.hdr.id, MSG_SUCCESS);

    ppp_chan_send(ad->ppp, &msg, ntohs(msg.hdr.len) + 2);
}

static void chap_send_challenge(struct chap_auth_data_t *ad)
{
    struct chap_challenge_t msg =	{
        .hdr.proto = htons(PPP_CHAP),
        .hdr.code = CHAP_CHALLENGE,
        .hdr.id = ++ad->id,
        .hdr.len = htons(sizeof(msg) - 2),
        .val_size = VALUE_SIZE,
    };

    read(urandom_fd, ad->val, VALUE_SIZE);
    memcpy(msg.val, ad->val, VALUE_SIZE);

    if (conf_ppp_verbose) {
        log_ppp_info2("send [CHAP Challenge id=%x <", msg.hdr.id);
        print_buf(msg.val, VALUE_SIZE);
        log_ppp_info2(">]\n");
    }

    ppp_chan_send(ad->ppp, &msg, ntohs(msg.hdr.len) + 2);

    if (conf_timeout && !ad->timeout.tpd)
        triton_timer_add(ad->ppp->ctrl->ctx, &ad->timeout, 0);
}

static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *hdr)
{
    MD5_CTX md5_ctx;
    uint8_t md5[MD5_DIGEST_LENGTH];
    char *passwd;
    char *name;
    int r;
    struct chap_challenge_t *msg = (struct chap_challenge_t*)hdr;

    if (ad->timeout.tpd)
        triton_timer_del(&ad->timeout);

    if (conf_ppp_verbose) {
        log_ppp_info2("recv [CHAP Response id=%x <", msg->hdr.id);
        print_buf(msg->val, msg->val_size);
        log_ppp_info2(">, name=\"");
        print_str(msg->name, ntohs(msg->hdr.len) - sizeof(*msg) + 2);
        log_ppp_info2("\"]\n");
    }

    if (msg->hdr.id != ad->id) {
        if (conf_ppp_verbose)
            log_ppp_warn("chap-md5: id mismatch\n");
        return;
    }

    if (msg->val_size != VALUE_SIZE) {
        log_ppp_error("chap-md5: incorrect value-size (%i)\n", msg->val_size);
        chap_send_failure(ad);
        if (ad->started)
            ppp_terminate(ad->ppp, TERM_USER_ERROR, 0);
        else
            ppp_auth_failed(ad->ppp, NULL);
        return;
    }

    name = _strndup(msg->name,ntohs(msg->hdr.len) - sizeof(*msg) + 2);

    if (conf_any_login) {
        if (ppp_auth_successed(ad->ppp, name)) {
            chap_send_failure(ad);
            ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
            _free(name);
            return;
        }
        chap_send_success(ad);
        ad->started = 1;
        return;
    }

    r = pwdb_check(ad->ppp, name, PPP_CHAP, CHAP_MD5, ad->id, ad->val, VALUE_SIZE, msg->val);

    if (r == PWDB_NO_IMPL) {
        passwd = pwdb_get_passwd(ad->ppp,name);
        if (!passwd)
        {
            _free(name);
            if (conf_ppp_verbose)
                log_ppp_warn("chap-md5: user not found\n");
            chap_send_failure(ad);
            return;
        }

        MD5_Init(&md5_ctx);
        MD5_Update(&md5_ctx,&msg->hdr.id,1);
        MD5_Update(&md5_ctx,passwd,strlen(passwd));
        MD5_Update(&md5_ctx,ad->val,VALUE_SIZE);
        MD5_Final(md5,&md5_ctx);

        if (memcmp(md5,msg->val,sizeof(md5)))
        {
            if (conf_ppp_verbose)
                log_ppp_warn("chap-md5: challenge response mismatch\n");
            chap_send_failure(ad);
            if (ad->started)
                ppp_terminate(ad->ppp, TERM_USER_ERROR, 0);
            else
                ppp_auth_failed(ad->ppp, name);
            _free(name);
        } else {
            if (!ad->started) {
                if (ppp_auth_successed(ad->ppp, name)) {
                    chap_send_failure(ad);
                    ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
                    _free(name);
                } else {
                    chap_send_success(ad);
                    ad->started = 1;
                    if (conf_interval)
                        triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
                }
            } else
                _free(name);
        }
        _free(passwd);
    } else if (r == PWDB_DENIED) {
        chap_send_failure(ad);
        if (ad->started)
            ppp_terminate(ad->ppp, TERM_USER_ERROR, 0);
        else
            ppp_auth_failed(ad->ppp, name);
        _free(name);
    } else {
        if (!ad->started) {
            if (ppp_auth_successed(ad->ppp, name)) {
                chap_send_failure(ad);
                ppp_terminate(ad->ppp, TERM_AUTH_ERROR, 0);
                _free(name);
            } else {
                chap_send_success(ad);
                ad->started = 1;
                if (conf_interval)
                    triton_timer_add(ad->ppp->ctrl->ctx, &ad->interval, 0);
            }
        } else {
            chap_send_success(ad);
            _free(name);
        }
    }
}

static int chap_check(uint8_t *ptr)
{
    return *ptr == CHAP_MD5;
}

static int chap_restart(struct ppp_t *ppp, struct auth_data_t *auth)
{
    struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth);

    chap_send_challenge(d);

    return 0;
}

static struct ppp_auth_handler_t chap=
{
    .name          = "CHAP-md5",
    .init          = auth_data_init,
    .free          = auth_data_free,
    .send_conf_req = lcp_send_conf_req,
    .recv_conf_req = lcp_recv_conf_req,
    .start         = chap_start,
    .finish        = chap_finish,
    .check         = chap_check,
    .restart       = chap_restart,
};

static void chap_recv(struct ppp_handler_t *h)
{
    struct chap_auth_data_t *d = container_of(h, typeof(*d), h);
    struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->buf;

    if (d->ppp->buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->buf_size - 2)	{
        log_ppp_warn("chap-md5: short packet received\n");
        return;
    }

    if (hdr->code == CHAP_RESPONSE)
        chap_recv_response(d, hdr);
    else
        log_ppp_warn("chap-md5: unknown code received %x\n", hdr->code);
}

static void load_config(void)
{
    const char *opt;

    opt = conf_get_opt("auth", "timeout");
    if (opt && atoi(opt) > 0)
        conf_timeout = atoi(opt);

    opt = conf_get_opt("auth", "interval");
    if (opt && atoi(opt) > 0)
        conf_interval = atoi(opt);

    opt = conf_get_opt("auth", "max-failure");
    if (opt && atoi(opt) > 0)
        conf_max_failure = atoi(opt);

    opt = conf_get_opt("auth", "any-login");
    if (opt)
        conf_any_login = atoi(opt);
}

static void auth_chap_md5_init()
{
    load_config();

    if (ppp_auth_register_handler(&chap))
        log_emerg("chap-md5: failed to register handler\n");

    triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);
}

DEFINE_INIT(4, auth_chap_md5_init);