Пример #1
0
/**
 * Set RADIUS attributes for RADIUS authentication request.
 * Return 0 on success.
 */
int
ppp_set_radius_attrs_for_authreq(npppd_ppp *_this,
    radius_req_setting *rad_setting, RADIUS_PACKET *radpkt)
{
	/* RFC 2865 "5.4 NAS-IP-Address" or RFC3162 "2.1. NAS-IPv6-Address" */
	if (radius_prepare_nas_address(rad_setting, radpkt) != 0)
		goto fail;

	/* RFC 2865 "5.6. Service-Type" */
	if (radius_put_uint32_attr(radpkt, RADIUS_TYPE_SERVICE_TYPE,
	    RADIUS_SERVICE_TYPE_FRAMED) != 0)
		goto fail;

	/* RFC 2865 "5.7. Framed-Protocol" */
	if (radius_put_uint32_attr(radpkt, RADIUS_TYPE_FRAMED_PROTOCOL,
	    RADIUS_FRAMED_PROTOCOL_PPP) != 0)
		goto fail;

	if (_this->calling_number[0] != '\0') {
		if (radius_put_string_attr(radpkt,
		    RADIUS_TYPE_CALLING_STATION_ID, _this->calling_number) != 0)
			return 1;
	}
	return 0;
fail:
	return 1;
}
Пример #2
0
static int
radius_acct_request(npppd *pppd, npppd_ppp *ppp, int stop)
{
	RADIUS_PACKET *radpkt;
	RADIUS_REQUEST_CTX radctx;
	radius_req_setting *rad_setting;
	char buf[128];

	if (ppp->username[0] == '\0')
		return 0;

	radpkt = NULL;
	radctx = NULL;
	rad_setting = npppd_auth_radius_get_radius_acct_setting(ppp->realm);
	if (!radius_req_setting_has_server(rad_setting))
		return 0;
	if ((radpkt = radius_new_request_packet(RADIUS_CODE_ACCOUNTING_REQUEST))
	    == NULL)
		goto fail;

	if (radius_prepare(rad_setting, (void *)(uintptr_t)ppp->id, &radctx,
	    npppd_ppp_radius_acct_reqcb, 0) != 0)
		goto fail;

    /* NAS Information */
	/*
	 * RFC 2865 "5.4.  NAS-IP-Address" or RFC 3162 "2.1. NAS-IPv6-Address"
	 */
	if (radius_prepare_nas_address(rad_setting, radpkt) != 0)
		goto fail;

	/* RFC 2865 "5.41. NAS-Port-Type" */
	ATTR_INT32(RADIUS_TYPE_NAS_PORT_TYPE, RADIUS_NAS_PORT_TYPE_VIRTUAL);

	/* RFC 2865 "5.5. NAS-Port" */
	ATTR_INT32(RADIUS_TYPE_NAS_PORT, ppp->id);
	    /* npppd has no physical / virtual ports in design. */

	/* RFC 2865 5.31. Calling-Station-Id */
	if (ppp->calling_number[0] != '\0')
		ATTR_STR(RADIUS_TYPE_CALLING_STATION_ID, ppp->calling_number);

    /* Tunnel Protocol Information */
	switch (ppp->tunnel_type) {
	case PPP_TUNNEL_L2TP:
		/* RFC 2868 3.1. Tunnel-Type */
		ATTR_INT32(RADIUS_TYPE_TUNNEL_TYPE, RADIUS_TUNNEL_TYPE_L2TP);
		if (l2tp_put_tunnel_attributes(radpkt, ppp->phy_context) != 0)
			goto fail;
		break;
	case PPP_TUNNEL_PPTP:
		/* RFC 2868 3.1. Tunnel-Type */
		ATTR_INT32(RADIUS_TYPE_TUNNEL_TYPE, RADIUS_TUNNEL_TYPE_PPTP);
		if (pptp_put_tunnel_attributes(radpkt, ppp->phy_context) != 0)
			goto fail;
		break;
	}

    /* Framed Protocol (PPP) Information */
	/* RFC 2865 5.1 User-Name */
	ATTR_STR(RADIUS_TYPE_USER_NAME, ppp->username);

	/* RFC 2865 "5.7. Service-Type" */
	ATTR_INT32(RADIUS_TYPE_SERVICE_TYPE, RADIUS_SERVICE_TYPE_FRAMED);

	/* RFC 2865 "5.8. Framed-Protocol" */
	ATTR_INT32(RADIUS_TYPE_FRAMED_PROTOCOL, RADIUS_FRAMED_PROTOCOL_PPP);

	/* RFC 2865 "5.8. Framed-IP-Address" */
	if (ppp_ip_assigned(ppp) && !stop)
		ppp->realm_framed_ip_address = ppp->ppp_framed_ip_address;
	if (ppp->realm_framed_ip_address.s_addr != INADDR_ANY) {
		ATTR_INT32(RADIUS_TYPE_FRAMED_IP_ADDRESS,
		    ntohl(ppp->realm_framed_ip_address.s_addr));
	}

    /* Accounting */
	/* RFC 2866  5.1. Acct-Status-Type */
	ATTR_INT32(RADIUS_TYPE_ACCT_STATUS_TYPE, (stop)
	    ? RADIUS_ACCT_STATUS_TYPE_STOP : RADIUS_ACCT_STATUS_TYPE_START);

	/* RFC 2866  5.2.  Acct-Delay-Time */
	ATTR_INT32(RADIUS_TYPE_ACCT_DELAY_TIME, 0);

	if (stop) {
		/* RFC 2866  5.3 Acct-Input-Octets */
		ATTR_INT32(RADIUS_TYPE_ACCT_INPUT_OCTETS,
		    (uint32_t)(ppp->ibytes & 0xFFFFFFFFU));	/* LSB 32bit */

		/* RFC 2866  5.4 Acct-Output-Octets */
		ATTR_INT32(RADIUS_TYPE_ACCT_OUTPUT_OCTETS,
		    (uint32_t)(ppp->obytes & 0xFFFFFFFFU));	/* LSB 32bit */
	}

	/* RFC 2866  5.5 Acct-Session-Id */
	snprintf(buf, sizeof(buf), "%08X%08X", pppd->boot_id, ppp->id);
	ATTR_STR(RADIUS_TYPE_ACCT_SESSION_ID, buf);

	/* RFC 2866 5.6.  Acct-Authentic */
	ATTR_INT32(RADIUS_TYPE_ACCT_AUTHENTIC, RADIUS_ACCT_AUTHENTIC_RADIUS);

	if (stop) {
		/* RFC 2866 5.7. Acct-Session-Time */
		ATTR_INT32(RADIUS_TYPE_ACCT_SESSION_TIME,
		    ppp->end_monotime - ppp->start_monotime);

		/* RFC 2866  5.8 Acct-Input-Packets */
		ATTR_INT32(RADIUS_TYPE_ACCT_INPUT_PACKETS, ppp->ipackets);

		/* RFC 2866  5.9 Acct-Output-Packets */
		ATTR_INT32(RADIUS_TYPE_ACCT_OUTPUT_PACKETS, ppp->opackets);

		/* RFC 2866  5.10. Acct-Terminate-Cause */
		if (ppp->terminate_cause != 0)
			ATTR_INT32(RADIUS_TYPE_ACCT_TERMINATE_CAUSE,
			    ppp->terminate_cause);

		/* RFC 2869  5.1 Acct-Input-Gigawords */
		ATTR_INT32(RADIUS_TYPE_ACCT_INPUT_GIGAWORDS, ppp->ibytes >> 32);

		/* RFC 2869  5.2 Acct-Output-Gigawords */
		ATTR_INT32(RADIUS_TYPE_ACCT_OUTPUT_GIGAWORDS,
		    ppp->obytes >> 32);
	}

	radius_set_request_authenticator(radpkt,
	    radius_get_server_secret(radctx));

	/* Send the request */
	radius_request(radctx, radpkt);

	return 0;

fail:
	ppp_log(ppp, LOG_WARNING, "radius accounting request failed: %m");

	if (radctx != NULL)
		radius_cancel_request(radctx);
	if (radpkt != NULL)
		radius_delete_packet(radpkt);

	return -1;
}