Esempio n. 1
0
/** callback function which works for each PPP session */
static int
npppd_iface_network_input_delegate(struct radish *radish, void *args0)
{
	npppd_ppp *ppp;
	struct sockaddr_npppd *snp;
	struct npppd_iface_network_input_arg *args;

	snp = radish->rd_rtent;

	if (snp->snp_type == SNP_PPP) {
		args = args0;
		ppp = snp->snp_data_ptr;
		if (ppp_iface(ppp) != args->_this)
			return 0;
#ifdef	USE_NPPPD_MPPE
		if (MPPE_SEND_READY(ppp)) {
			/* output via MPPE if MPPE started */
			mppe_pkt_output(&ppp->mppe, PPP_PROTO_IP, args->pktp,
			    args->lpktp);
		} else if (MPPE_IS_REQUIRED(ppp)) {
			/* in case MPPE not started but MPPE is mandatory, */
			/* it is not necessary to log because of multicast. */
			return 0;
		}
#endif
		ppp_output(ppp, PPP_PROTO_IP, 0, 0, args->pktp, args->lpktp);
	}

	return 0;
}
Esempio n. 2
0
static void
npppd_iface_network_input_ipv4(npppd_iface *_this, u_char *pktp, int lpktp)
{
	struct ip *iphdr;
	npppd *_npppd;
	npppd_ppp *ppp;
	struct npppd_iface_network_input_arg input_arg;

	NPPPD_IFACE_ASSERT(_this != NULL);
	NPPPD_IFACE_ASSERT(pktp != NULL);

	iphdr = (struct ip *)pktp;
	_npppd = _this->npppd;

	if (lpktp < sizeof(iphdr)) {
		npppd_iface_log(_this, LOG_ERR, "Received short packet.");
		return;
	}
	if (IN_MULTICAST(ntohl(iphdr->ip_dst.s_addr))) {
		NPPPD_IFACE_ASSERT(((npppd *)(_this->npppd))->rd != NULL);
		input_arg._this = _this;
		input_arg.pktp = pktp;
		input_arg.lpktp = lpktp;
		/* delegate */
		rd_walktree(((npppd *)(_this->npppd))->rd,
		    npppd_iface_network_input_delegate, &input_arg);
		return;
	}
	ppp = npppd_get_ppp_by_ip(_npppd, iphdr->ip_dst);
	if (ppp == NULL) {
#ifdef NPPPD_DEBUG
		log_printf(LOG_INFO, "%s received a packet to unknown "
		    "%s.", _this->ifname, inet_ntoa(iphdr->ip_dst));
#endif
		return;
	}
#ifndef NO_ADJUST_MSS
	if (ppp->adjust_mss) {
		adjust_tcp_mss(pktp, lpktp, MRU_IPMTU(ppp->peer_mru));
	}
#endif
	if (ppp->timeout_sec > 0 && !ip_is_idle_packet(iphdr, lpktp))
		ppp_reset_idle_timeout(ppp);

#ifdef	USE_NPPPD_MPPE
	if (MPPE_SEND_READY(ppp)) {
		/* output via MPPE if MPPE started */
		mppe_pkt_output(&ppp->mppe, PPP_PROTO_IP, pktp, lpktp);
		return;
	} else if (MPPE_IS_REQUIRED(ppp)) {
		/* in case MPPE not started but MPPE is mandatory */
		ppp_log(ppp, LOG_WARNING, "A packet received from network, "
		    "but MPPE is not started.");
		return;
	}
#endif
	ppp_output(ppp, PPP_PROTO_IP, 0, 0, pktp, lpktp);
}
Esempio n. 3
0
/***********************************************************************
 * Proxy Authentication
 ***********************************************************************/
int
chap_proxy_authen_prepare(chap *_this, dialin_proxy_info *dpi)
{

	CHAP_ASSERT(dpi->auth_type == PPP_AUTH_CHAP_MD5);
	CHAP_ASSERT(_this->state == CHAP_STATE_INITIAL);

	_this->pktid = dpi->auth_id;

#ifdef USE_NPPPD_MPPE
	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", dpi->auth_type);
		return -1;
	}
#endif
	/* authentication */
	if (strlen(dpi->username) >= sizeof(_this->name)) {
		chap_log(_this, LOG_NOTICE,
		    "\"Proxy Authen Name\" is too long.");
		return -1;
	}
	if (dpi->lauth_chall >= sizeof(_this->chall)) {
		chap_log(_this, LOG_NOTICE,
		    "\"Proxy Authen Challenge\" is too long.");
		return -1;
	}

	/* copy the authenticaiton properties */
	CHAP_ASSERT(_this->ppp->proxy_authen_resp == NULL);
	if ((_this->ppp->proxy_authen_resp = malloc(dpi->lauth_resp)) ==
	    NULL) {
		chap_log(_this, LOG_ERR, "malloc() failed in %s(): %m",
		    __func__);
		return -1;
	}
	memcpy(_this->ppp->proxy_authen_resp, dpi->auth_resp,
	    dpi->lauth_resp);
	_this->ppp->lproxy_authen_resp = dpi->lauth_resp;

	_this->challid = dpi->auth_id;
	strlcpy(_this->name, dpi->username, sizeof(_this->name));

	memcpy(_this->chall, dpi->auth_chall, dpi->lauth_chall);
	_this->lchall = dpi->lauth_chall;

	_this->state = CHAP_STATE_PROXY_AUTHENTICATION;

	return 0;
}
Esempio n. 4
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");
		}
	}
}