Exemplo n.º 1
0
/** This function is called on authentication succeed */
void
ppp_auth_ok(npppd_ppp *_this)
{
	if (npppd_ppp_bind_iface(_this->pppd, _this) != 0) {
		ppp_log(_this, LOG_WARNING, "No interface binding.");
		ppp_stop(_this, NULL);

		return;
	}
	if (_this->realm != NULL) {
		npppd_ppp_get_username_for_auth(_this->pppd, _this,
		    _this->username, _this->username);
		if (!npppd_check_calling_number(_this->pppd, _this)) {
			ppp_log(_this, LOG_ALERT,
			    "logtype=TUNNELDENY user=\"%s\" "
			    "reason=\"Calling number check is failed\"",
			    _this->username);
			    /* XXX */
			ppp_stop(_this, NULL);
			return;
		}
	}
	if (_this->peer_auth != 0) {
		/* Limit the number of connections per the user */
		if (!npppd_check_user_max_session(_this->pppd, _this)) {
			ppp_log(_this, LOG_WARNING,
			    "user %s exceeds user-max-session limit",
			    _this->username);
			ppp_stop(_this, NULL);

			return;
		}
		PPP_ASSERT(_this->realm != NULL);
	}

	if (!npppd_ppp_iface_is_ready(_this->pppd, _this)) {
		ppp_log(_this, LOG_WARNING,
		    "interface '%s' is not ready.",
		    npppd_ppp_get_iface_name(_this->pppd, _this));
		ppp_stop(_this, NULL);

		return;
	}
	if (_this->proxy_authen_resp != NULL) {
		free(_this->proxy_authen_resp);
		_this->proxy_authen_resp = NULL;
	}

	fsm_lowerup(&_this->ipcp.fsm);
	fsm_open(&_this->ipcp.fsm);
#ifdef	USE_NPPPD_MPPE
	if (MPPE_MUST_NEGO(_this)) {
		fsm_lowerup(&_this->ccp.fsm);
		fsm_open(&_this->ccp.fsm);
	}
#endif

	return;
}
Exemplo n.º 2
0
static void
lcp_timeout(void *ctx)
{
	lcp *_this;
	u_char *cp, buf[32];

	_this = ctx;
	if (_this->echo_failures >= _this->echo_max_retries) {
		fsm_log(&_this->fsm, LOG_NOTICE, "keepalive failure.");
		if (_this->fsm.ppp != NULL) {
#ifdef USE_NPPPD_RADIUS
			ppp_set_radius_terminate_cause(_this->fsm.ppp,
			    RADIUS_TERMNATE_CAUSE_IDLE_TIMEOUT);
#endif
			ppp_stop(_this->fsm.ppp, NULL);
		}
		return;
	}
	cp = buf;
	PUTLONG(_this->magic_number, cp);
	fsm_sdata(&_this->fsm, ECHOREQ, _this->fsm.id++, buf, 4);
	_this->echo_failures++;

	lcp_reset_timeout(_this);
}
Exemplo n.º 3
0
static void
chap_response(chap *_this, int authok, u_char *pktp, int lpktp)
{
	const char *realm_name;

	CHAP_ASSERT(_this != NULL);
	CHAP_ASSERT(pktp != NULL);
	CHAP_ASSERT(_this->type == PPP_AUTH_CHAP_MD5 ||
	    _this->type == PPP_AUTH_CHAP_MS_V2);

	ppp_output(_this->ppp, PPP_PROTO_CHAP, (authok)? 3 : 4, _this->challid,
	    pktp, lpktp);

	realm_name = npppd_ppp_get_realm_name(_this->ppp->pppd, _this->ppp);
	if (!authok) {
		chap_log(_this, LOG_ALERT,
		    "logtype=Failure username=\"%s\" realm=%s", _this->name,
		    realm_name);
		chap_stop(_this);
		/* Stop the PPP if the authentication is failed. */
		ppp_set_disconnect_cause(_this->ppp,
		    PPP_DISCON_AUTH_FAILED, PPP_PROTO_CHAP, 1 /* peer */, NULL);
		ppp_stop(_this->ppp, "Authentication Required");
	} else {
		strlcpy(_this->ppp->username, _this->name,
		    sizeof(_this->ppp->username));
		chap_log(_this, LOG_INFO,
		    "logtype=Success username=\"%s\" "
		    "realm=%s", _this->name, realm_name);
		chap_stop(_this);
		/* We change our state to prepare to resend requests. */
		_this->state = CHAP_STATE_SENT_RESPONSE;
		ppp_auth_ok(_this->ppp);
	}
}
Exemplo n.º 4
0
Boolean
disconnectIfVPNLocationChanged(struct service *serv)
{
	// ignore connection if it isn't ipsec, l2tp or pptp
	if (!(serv->type == TYPE_IPSEC || (serv->type == TYPE_PPP && (serv->subtype == PPP_TYPE_L2TP || serv->subtype == PPP_TYPE_PPTP)))) {
		return false;
	}

	if (didVPNLocationChange(serv)) {
		/* location changed */
		switch (serv->type) {
		case TYPE_PPP:
			serv->u.ppp.laststatus = EXIT_HANGUP;
			if (serv->subtype == PPP_TYPE_L2TP) {
				serv->u.ppp.lastdevstatus = EXIT_L2TP_NETWORKCHANGED;
			} else {
				serv->u.ppp.lastdevstatus = EXIT_PPTP_NETWORKCHANGED;
			}
			SCLog(TRUE, LOG_ERR, CFSTR("Controller: PPP disconnecting because the location changed"));
			ppp_stop(serv, SIGTERM);
			return true;
		case TYPE_IPSEC:
			serv->u.ipsec.laststatus = IPSEC_NETWORKCHANGE_ERROR;
			SCLog(TRUE, LOG_ERR, CFSTR("Controller: IPSec disconnecting because the location changed"));
			ipsec_stop(serv, SIGTERM);
			return true;
		}
	}
	return false;
}
Exemplo n.º 5
0
void
ppp_ccp_stopped(npppd_ppp *_this)
{
#ifdef USE_NPPPD_MPPE
	if (_this->mppe.required) {
		ppp_stop(_this, NULL);
		return;
	}
#endif
#ifdef USE_NPPPD_PIPEX
	ppp_on_network_pipex(_this);
#endif
}
Exemplo n.º 6
0
static void
lcp_open(fsm *f)
{
	lcp *_this;
	int peer_auth = 0;

	LCP_ASSERT(f != NULL);
	_this = &f->ppp->lcp;

	if (psm_opt_is_accepted(_this, pap))
		peer_auth = PPP_AUTH_PAP;
	else if (psm_opt_is_accepted(_this, chap))
		peer_auth = PPP_AUTH_CHAP_MD5;
	else if (psm_opt_is_accepted(_this, chapms))
		peer_auth = PPP_AUTH_CHAP_MS;
	else if (psm_opt_is_accepted(_this, chapms_v2))
		peer_auth = PPP_AUTH_CHAP_MS_V2;
	else if (psm_opt_is_accepted(_this, eap))
		peer_auth = PPP_AUTH_EAP;
	else {
		if (_this->auth_order[0] > 0) {
			fsm_log(f, LOG_INFO,
			    "failed to negotiate a auth protocol.");
			fsm_close(f, "Authentication is required");
			ppp_set_disconnect_cause(f->ppp,
			    PPP_DISCON_AUTH_PROTOCOL_UNACCEPTABLE, 
			    _this->auth_order[0] /* first one */,
			    1 /* peer refused */, NULL);
			ppp_stop(f->ppp, "Authentication is required");
			return;
		}
	}
	f->ppp->peer_auth = peer_auth;

	if (_this->xxxmru > 0 && f->ppp->peer_mru <= 0)
		f->ppp->peer_mru = _this->xxxmru;
	if (f->ppp->peer_mru <= 0)
		f->ppp->peer_mru = f->ppp->mru;

	/* checking the size of ppp->peer_mru. */
	LCP_ASSERT(f->ppp->peer_mru > 500);

	fsm_log(f, LOG_INFO, "logtype=Opened mru=%d/%d auth=%s magic=%08x/%08x"
	    , f->ppp->mru, f->ppp->peer_mru
	    , lcp_auth_string(peer_auth)
	    , f->ppp->lcp.magic_number, f->ppp->lcp.peer_magic_number
	);
	lcp_reset_timeout(_this);

	ppp_lcp_up(f->ppp);
}
Exemplo n.º 7
0
/** timer event handler for idle timer */
static void
ppp_idle_timeout(int fd, short evtype, void *context)
{
	npppd_ppp *_this;

	_this = context;

	ppp_log(_this, LOG_NOTICE, "Idle timeout(%d sec)", _this->timeout_sec);
#ifdef USE_NPPPD_RADIUS
	ppp_set_radius_terminate_cause(_this,
	    RADIUS_TERMNATE_CAUSE_IDLE_TIMEOUT);
#endif
	ppp_stop(_this, NULL);
}
Exemplo n.º 8
0
static void
pap_response(pap *_this, int authok, const char *mes)
{
	int lpktp, lmes;
	u_char *pktp, *pktp1;
	const char *realm;

	pktp = ppp_packetbuf(_this->ppp, PPP_PROTO_PAP) + HEADERLEN;
	lpktp = _this->ppp->mru - HEADERLEN;
	realm = npppd_ppp_get_realm_name(_this->ppp->pppd, _this->ppp);

	pktp1 = pktp;
	if (mes == NULL)
		lmes = 0;
	else
		lmes = strlen(mes);
	lmes = MINIMUM(lmes, lpktp - 1);

	PUTCHAR(lmes, pktp1);
	if (lmes > 0)
		memcpy(pktp1, mes, lmes);
	lpktp = lmes + 1;

	if (authok)
		ppp_output(_this->ppp, PPP_PROTO_PAP, AUTHACK, _this->auth_id,
		    pktp, lpktp);
	else
		ppp_output(_this->ppp, PPP_PROTO_PAP, AUTHNAK, _this->auth_id,
		    pktp, lpktp);

	if (!authok) {
		pap_log(_this, LOG_ALERT,
		    "logtype=Failure username=\"%s\" realm=%s", _this->name,
		    realm);
		pap_stop(_this);
		ppp_set_disconnect_cause(_this->ppp, 
		    PPP_DISCON_AUTH_FAILED, PPP_PROTO_PAP, 1 /* peer */, NULL);
		ppp_stop(_this->ppp, "Authentication Required");
	} else {
		strlcpy(_this->ppp->username, _this->name,
		    sizeof(_this->ppp->username));
		pap_log(_this, LOG_INFO,
		    "logtype=Success username=\"%s\" realm=%s", _this->name,
		    realm);
		pap_stop(_this);
		ppp_auth_ok(_this->ppp);
		/* reset the state to response request of retransmision. */
		_this->state = PAP_STATE_SENT_RESPONSE;
	}
}
Exemplo n.º 9
0
static void
lcp_rcoderej(fsm *f, u_char *inp, int inlen)
{
	uint16_t proto;
	fsm *rejfsm;

	if (inlen < 2) {
		fsm_log(f, LOG_WARNING, "Received short ProtRej packet.");
		return;
	}
	GETSHORT(proto, inp);

	rejfsm = NULL;

	switch (proto) {
	case PPP_PROTO_LCP:
		rejfsm = &f->ppp->lcp.fsm;
		break;
	case PPP_PROTO_PAP:
		fsm_log(f, LOG_WARNING, "our PAP packet is rejected");
		return;
	case PPP_PROTO_CHAP:
		fsm_log(f, LOG_WARNING, "our CHAP packet is rejected");
		return;
        case PPP_PROTO_EAP:
                fsm_log(f, LOG_ERR, "our EAP packet is rejected");
                ppp_stop(f->ppp, "Authentication Required");
                break;
	case PPP_PROTO_NCP | NCP_IPCP:
		rejfsm = &f->ppp->ipcp.fsm;
		break;
	case PPP_PROTO_NCP | NCP_CCP:
		rejfsm = &f->ppp->ccp.fsm;
		break;
	}
	if (rejfsm == NULL) {
		fsm_log(f, LOG_WARNING,
		    "Received ProtRej packet for unknown protocol=(%d/%04x)",
		    proto, proto);
		return;
	}
	fsm_protreject(rejfsm);

	return;
}
Exemplo n.º 10
0
/** This function is called when CCP is opened */
void
ppp_ccp_opened(npppd_ppp *_this)
{
#ifdef USE_NPPPD_MPPE
	if (_this->ccp.mppe_rej == 0) {
		if (_this->mppe_started == 0) {
			mppe_start(&_this->mppe);
		}
	} else {
		ppp_log(_this, LOG_INFO, "mppe is rejected by peer");
		if (_this->mppe.required)
			ppp_stop(_this, "MPPE is requred");
	}
#endif
#ifdef USE_NPPPD_PIPEX
	ppp_on_network_pipex(_this);
#endif
}
Exemplo n.º 11
0
/** called when the lcp is up */
void
ppp_lcp_up(npppd_ppp *_this)
{
#ifdef USE_NPPPD_MPPE
	if (MPPE_REQUIRED(_this) && !MPPE_MUST_NEGO(_this)) {
		ppp_log(_this, LOG_ERR, "MPPE is required, auth protocol must "
		    "be MS-CHAP-V2 or EAP");
		ppp_stop(_this, "Encryption required");
		return;
	}
#endif
	/*
	 * Use our MRU value even if the peer insists on larger value.
	 * We set the peer_mtu here, the value will be used as the MTU of the
	 * routing entry.  So we will not receive packets larger than the MTU.
	 */
	if (_this->peer_mru > _this->mru)
		_this->peer_mru = _this->mru;

	if (_this->peer_auth != 0 && _this->auth_runonce == 0) {
		if (AUTH_IS_PAP(_this)) {
			pap_start(&_this->pap);
			_this->auth_runonce = 1;
			return;
		}
		if (AUTH_IS_CHAP(_this)) {
			chap_start(&_this->chap);
			_this->auth_runonce = 1;
			return;
		}
#ifdef USE_NPPPD_EAP_RADIUS
                if (AUTH_IS_EAP(_this)) {
                        eap_init(&_this->eap, _this);
                        eap_start(&_this->eap);
                        return;
                }
#endif
	}
	if (_this->peer_auth == 0)
		ppp_auth_ok(_this);
}
Exemplo n.º 12
0
/**
 * receiving ConfRej.
 */
static int
lcp_rejci(fsm *f, u_char *inp, int inlen)
{
	int chapalg, authproto, type, len, mru;
	u_char *inp0;
	lcp *_this;

#define	remlen()	(inlen - (inp - inp0))
#define	LCP_OPT_REJECTED(opt)				\
	if (!psm_opt_is_requested(&f->ppp->lcp, opt))	\
		goto fail;				\
	psm_opt_set_rejected(&f->ppp->lcp, opt, 1);

	f->ppp->lcp.recv_ress++;
	inp0 = inp;
	_this = &f->ppp->lcp;
	while (remlen() >= 2) {
		GETCHAR(type, inp);
		GETCHAR(len, inp);

		if (len <= 0 || remlen() + 2 < len)
			goto fail;

		switch (type) {
		case PPP_LCP_MAGICNUMBER:
			if (f->ppp->lcp.echo_interval > 0)
				goto fail;
			inp += 4;
			break;
		case PPP_LCP_MRU:
			LCP_OPT_REJECTED(mru);
			GETSHORT(mru, inp);
			break;
		case PPP_LCP_AUTH_PROTOCOL:
			if (len < 4)
				goto fail;
			GETSHORT(authproto, inp);
			switch (authproto) {
			case PPP_AUTH_PAP:
                                if (len != 4)
                                        goto fail;
				LCP_OPT_REJECTED(pap);
				break;
			case PPP_AUTH_CHAP:
				chapalg = 0;
				if (len == 5)
					GETCHAR(chapalg, inp);
				switch (chapalg) {
				case PPP_AUTH_CHAP_MD5:
					LCP_OPT_REJECTED(chap);
					break;
				case PPP_AUTH_CHAP_MS:
					LCP_OPT_REJECTED(chapms);
					break;
				case PPP_AUTH_CHAP_MS_V2:
					LCP_OPT_REJECTED(chapms_v2);
					break;
				default:
					fsm_log(f, LOG_INFO,
					    "Rejected chap algorithm is "
					    "unknown(%d).", chapalg);
					break;
				}
				break;
                         case PPP_AUTH_EAP:
                                if (len != 4)
                                        goto fail;
                                LCP_OPT_REJECTED(eap);
                                break;
			}
			if (NO_AUTH_AGREEABLE(_this)) {
				fsm_log(f, LOG_INFO, "No authentication "
				    "protocols are agreeable.");
				ppp_set_disconnect_cause(f->ppp,
				    PPP_DISCON_AUTH_PROTOCOL_UNACCEPTABLE,
				    authproto, 1 /* rejected by peer */, NULL);
				ppp_stop(f->ppp, "Authentication is required");
				return 1;
			}
			break;
		case PPP_LCP_PFC:
			if (len != 2)
				goto fail;
			LCP_OPT_REJECTED(pfc);
			break;
		case PPP_LCP_ACFC:
			if (len != 2)
				goto fail;
			LCP_OPT_REJECTED(acfc);
			break;
		default:
			goto fail;
		}
	}
	return 1;
fail:
	log_printf(LOG_ERR, "Received unexpected ConfRej.");
	if (debug_get_debugfp() != NULL)
		show_hd(debug_get_debugfp(), inp, inlen);
	return 0;
#undef remlen
}
Exemplo n.º 13
0
/** receiving ConfNak. */
static int
lcp_nakci(fsm *f, u_char *inp, int inlen)
{
	int chapalg, authproto, type, len, mru;
	u_char *inp0;
	lcp *_this;
	const char *peer_auth = "unknown";

#define	remlen()	(inlen - (inp - inp0))
#define	LCP_OPT_REJECTED(opt)				\
	if (!psm_opt_is_requested(&f->ppp->lcp, opt))	\
		goto fail;				\
	psm_opt_set_rejected(&f->ppp->lcp, opt, 1);

	f->ppp->lcp.recv_ress++;
	inp0 = inp;
	_this = &f->ppp->lcp;
	while (remlen() >= 2) {
		GETCHAR(type, inp);
		GETCHAR(len, inp);

		if (len <= 0 || remlen() + 2 < len)
			goto fail;

		switch (type) {
		case PPP_LCP_MRU:
			if (len < 4)
				goto fail;
			GETSHORT(mru, inp);
			fsm_log(f, LOG_NOTICE,
			    "ignored ConfNak from the peer: mru=%d", mru);
			_this->xxxmru = mru;
			break;
		case PPP_LCP_AUTH_PROTOCOL:
			if (len < 4)
				goto fail;
			switch (_this->lastauth) {
			case PPP_AUTH_PAP:
				psm_opt_set_rejected(_this, pap, 1);
				break;
			case PPP_AUTH_CHAP_MD5:
				psm_opt_set_rejected(_this, chap, 1);
				break;
			case PPP_AUTH_CHAP_MS:
				psm_opt_set_rejected(_this, chapms, 1);
				break;
			case PPP_AUTH_CHAP_MS_V2:
				psm_opt_set_rejected(_this, chapms_v2, 1);
				break;
                        case PPP_AUTH_EAP:
                                psm_opt_set_rejected(_this, eap, 1);
                                break;
			}
			GETSHORT(authproto, inp);
			switch (authproto) {
			case PPP_AUTH_PAP:
				if (psm_opt_is_requested(_this, pap))
					psm_opt_set_accepted(_this, pap, 1);
				peer_auth = "pap";
				break;
			case PPP_AUTH_CHAP:
				chapalg = 0;
				if (len == 5)
					GETCHAR(chapalg, inp);
				switch (chapalg) {
				case PPP_AUTH_CHAP_MD5:
					if (psm_opt_is_requested(_this, chap))
						psm_opt_set_accepted(_this,
						    chap, 1);
					peer_auth = "chap";
					break;
				case PPP_AUTH_CHAP_MS:
					if (psm_opt_is_requested(_this, chapms))
						psm_opt_set_accepted(_this,
						    chapms, 1);
					peer_auth = "mschap";
					break;
				case PPP_AUTH_CHAP_MS_V2:
					if (psm_opt_is_requested(_this,
					    chapms_v2))
						psm_opt_set_accepted(_this,
						    chapms_v2, 1);
					peer_auth = "mschap_v2";
					break;
				default:
					fsm_log(f, LOG_INFO,
					    "Nacked chap algorithm is "
					    "unknown(%d).", chapalg);
					peer_auth = "unknown";
					break;
				}
				break;
                        case PPP_AUTH_EAP:
                                if (len != 4)
                                        goto fail;
                                peer_auth = "eap";
				if (psm_opt_is_requested(_this, eap))
					psm_opt_set_accepted(_this, eap, 1);
                                break;
			}
			if (NO_AUTH_AGREEABLE(_this)) {
				fsm_log(f, LOG_INFO, "No authentication "
				    "protocols are agreeable.  peer's "
				    "auth proto=%s",
				    peer_auth);
				ppp_set_disconnect_cause(f->ppp,
				    PPP_DISCON_AUTH_PROTOCOL_UNACCEPTABLE, 
				    authproto, 2 /* couldn't accept peer's */,
				    NULL);
				ppp_stop(f->ppp, "Authentication is required");
				return 1;
			}
			break;
		case PPP_LCP_PFC:
			if (len != 2)
				goto fail;
			LCP_OPT_REJECTED(pfc);
			break;
		case PPP_LCP_ACFC:
			if (len != 2)
				goto fail;
			LCP_OPT_REJECTED(acfc);
			break;
		default:
			goto fail;
		}
	}
	return 1;
fail:
	log_printf(LOG_ERR, "Received unexpected ConfNak.");
	if (debug_get_debugfp() != NULL)
		show_hd(debug_get_debugfp(), inp, inlen);
	return 0;
#undef remlen
#undef LCP_OPT_REJECTED
}
Exemplo n.º 14
0
static int
npppd_iface_setup_ip(npppd_iface *_this)
{
	int sock, if_flags, changed;
	struct in_addr gw, assigned;
	struct sockaddr_in *sin0;
	struct ifreq ifr;
	struct ifaliasreq ifra;
	npppd_ppp *ppp;

	NPPPD_IFACE_ASSERT(_this != NULL);

	sock = -1;
	changed = 0;
	memset(&ifr, 0, sizeof(ifr));

	/* get address which was assigned to interface */
	assigned.s_addr = INADDR_NONE;
	memset(&ifr, 0, sizeof(ifr));
	memset(&ifra, 0, sizeof(ifra));
	strlcpy(ifr.ifr_name, _this->ifname, sizeof(ifr.ifr_name));
	strlcpy(ifra.ifra_name, _this->ifname, sizeof(ifra.ifra_name));
	sin0 = (struct sockaddr_in *)&ifr.ifr_addr;

	if (priv_get_if_addr(_this->ifname, &assigned) != 0) {
		if (errno != EADDRNOTAVAIL) {
			npppd_iface_log(_this, LOG_ERR,
			    "get ip address failed: %m");
			goto fail;
		}
		assigned.s_addr = 0;
	}

	if (assigned.s_addr != _this->ip4addr.s_addr)
		changed = 1;

	if (priv_get_if_flags(_this->ifname, &if_flags) != 0) {
		npppd_iface_log(_this, LOG_ERR,
		    "ioctl(,SIOCGIFFLAGS) failed: %m");
		goto fail;
	}
	if_flags = ifr.ifr_flags;
	if (_this->set_ip4addr != 0 && changed) {
		do {
			struct in_addr dummy;
			if (priv_delete_if_addr(_this->ifname) != 0) {
				if (errno == EADDRNOTAVAIL)
					break;
				npppd_iface_log(_this, LOG_ERR,
				    "delete ipaddress %s failed: %m",
				    _this->ifname);
				goto fail;
			}
			if (priv_get_if_addr(_this->ifname, &dummy) != 0) {
				if (errno == EADDRNOTAVAIL)
					break;
				npppd_iface_log(_this, LOG_ERR,
				    "cannot get ipaddress %s failed: %m",
				    _this->ifname);
				goto fail;
			}
		} while (1);

		/* ifconfig tun1 down */
		if (priv_set_if_flags(_this->ifname,
		    if_flags & ~(IFF_UP | IFF_BROADCAST)) != 0) {
			npppd_iface_log(_this, LOG_ERR,
			    "disabling %s failed: %m", _this->ifname);
			goto fail;
		}
		if (priv_set_if_addr(_this->ifname, &_this->ip4addr) != 0 &&
		    errno != EEXIST) {
			npppd_iface_log(_this, LOG_ERR,
			    "Cannot assign tun device ip address: %m");
			goto fail;
		}
		assigned.s_addr = _this->ip4addr.s_addr;

	}
	_this->ip4addr.s_addr = assigned.s_addr;
	if (npppd_iface_ip_is_ready(_this)) {
		if (changed) {
			/*
			 * If there is a PPP session which was assigned
			 * interface IP address, disconnect it.
			 */
			ppp = npppd_get_ppp_by_ip(_this->npppd, _this->ip4addr);
			if (ppp != NULL) {
				npppd_iface_log(_this, LOG_ERR,
				    "Assigning %s, but ppp=%d is using "
				    "the address. Requested the ppp to stop",
				    inet_ntoa(_this->ip4addr), ppp->id);
				ppp_stop(ppp, "Administrative reason");
			}
		}
		/* ifconfig tun1 up */
		if (priv_set_if_flags(_this->ifname,
		    if_flags | IFF_UP | IFF_MULTICAST) != 0) {
			npppd_iface_log(_this, LOG_ERR,
			    "enabling %s failed: %m", _this->ifname);
			goto fail;
		}
		/*
		 * Add routing entry to communicate from host itself to
		 * _this->ip4addr.
		 */
		gw.s_addr = htonl(INADDR_LOOPBACK);
		in_host_route_add(&_this->ip4addr, &gw, LOOPBACK_IFNAME, 0);
	}
	close(sock); sock = -1;

	return 0;
fail:
	if (sock >= 0)
		close(sock);

	return 1;
}
Exemplo n.º 15
0
/** Start CHAP as a authenticator.  Send a challenge */
void
chap_start(chap *_this)
{
	u_char *challp, *challp0;
	int lmyname;

	CHAP_ASSERT(_this != NULL);
	CHAP_ASSERT(_this->ppp != NULL);

	if (_this->state == CHAP_STATE_PROXY_AUTHENTICATION) {
		_this->type = PPP_AUTH_CHAP_MD5;
		_this->state = CHAP_STATE_AUTHENTICATING;
		chap_authenticate(_this, _this->ppp->proxy_authen_resp,
		    _this->ppp->lproxy_authen_resp);
		return;
	}

	if (_this->state == CHAP_STATE_INITIAL ||
	    _this->state == CHAP_STATE_SENT_CHALLENGE) {
		if (_this->ntry > 0) {
			_this->ntry--;
			_this->type = _this->ppp->peer_auth;

			/* The type is supported? */
			if (_this->type != PPP_AUTH_CHAP_MS_V2 &&
			    _this->type != PPP_AUTH_CHAP_MD5) {
				chap_log(_this, LOG_ALERT,
				    "Requested authentication type(0x%x) "
				    "is not supported.", _this->type);
				ppp_set_disconnect_cause(_this->ppp, 
				    PPP_DISCON_AUTH_PROTOCOL_UNACCEPTABLE,
				    PPP_PROTO_CHAP, 2 /* local */, NULL);
				ppp_stop(_this->ppp, "Authentication Required");
				return;
			}


#ifdef USE_NPPPD_MPPE
			/* The peer must use MS-CHAP-V2 as the type */
			if (MPPE_IS_REQUIRED(_this->ppp) &&
			    _this->type != PPP_AUTH_CHAP_MS_V2) {
				chap_log(_this, LOG_ALERT,
				    "mppe is required but try to start chap "
				    "type=0x%02x", _this->type);
				ppp_set_disconnect_cause(_this->ppp,
				    PPP_DISCON_AUTH_PROTOCOL_UNACCEPTABLE,
				    PPP_PROTO_CHAP, 2 /* local */, NULL);
				ppp_stop(_this->ppp, "Authentication Required");
				return;
			}
#endif
			/* Generate a challenge packet and send it */
			challp = ppp_packetbuf(_this->ppp, PPP_AUTH_CHAP);
			challp += HEADERLEN;
			challp0 = challp;

			chap_create_challenge(_this);

			PUTCHAR(_this->lchall, challp);
			memcpy(challp, &_this->chall, _this->lchall);
			challp += _this->lchall;

			lmyname = strlen(_this->myname);

			memcpy(challp, _this->myname, lmyname);
			challp += lmyname;

			_this->challid = ++_this->pktid;

			ppp_output(_this->ppp, PPP_PROTO_CHAP, CHAP_CHALLENGE,
			    _this->challid, challp0, challp - challp0);

			_this->state = CHAP_STATE_SENT_CHALLENGE;

			TIMEOUT((void (*)(void *))chap_start, _this,
			    CHAP_TIMEOUT);
		} else {
			chap_log(_this, LOG_INFO,
			    "Client did't respond our challenage.");
			ppp_set_disconnect_cause(_this->ppp, 
			    PPP_DISCON_AUTH_FSM_TIMEOUT,
			    PPP_PROTO_CHAP, 0, NULL);
			ppp_stop(_this->ppp, "Authentication Required");
		}
	}
}