⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 radius.c

📁 linux下的ppp协议簇开源代码; 可以进行linux内核级的pppoe拨号
💻 C
📖 第 1 页 / 共 3 页
字号:
	u_char *p = cpassword;	if (response_len != MS_CHAP2_RESPONSE_LEN)	    return 0;	*p++ = id;	/* The idiots use a different field order in RADIUS than PPP */	memcpy(p, rmd->Flags, sizeof(rmd->Flags));	p += sizeof(rmd->Flags);	memcpy(p, rmd->PeerChallenge, sizeof(rmd->PeerChallenge));	p += sizeof(rmd->PeerChallenge);	memcpy(p, rmd->Reserved, sizeof(rmd->Reserved));	p += sizeof(rmd->Reserved);	memcpy(p, rmd->NTResp, sizeof(rmd->NTResp));	rc_avpair_add(&send, PW_MS_CHAP_CHALLENGE,		      challenge, challenge_len, VENDOR_MICROSOFT);	rc_avpair_add(&send, PW_MS_CHAP2_RESPONSE,		      cpassword, MS_CHAP2_RESPONSE_LEN + 1, VENDOR_MICROSOFT);	break;    }#endif    }    if (*remote_number) {	rc_avpair_add(&send, PW_CALLING_STATION_ID, remote_number, 0,		       VENDOR_NONE);    } else if (ipparam)	rc_avpair_add(&send, PW_CALLING_STATION_ID, ipparam, 0, VENDOR_NONE);    /* Add user specified vp's */    if (rstate.avp)	rc_avpair_insert(&send, NULL, rc_avpair_copy(rstate.avp));    /*     * make authentication with RADIUS server     */    if (rstate.authserver) {	result = rc_auth_using_server(rstate.authserver,				      rstate.client_port, send,				      &received, radius_msg, req_info);    } else {	result = rc_auth(rstate.client_port, send, &received, radius_msg,			 req_info);    }    if (result == OK_RC) {	if (!rstate.done_chap_once) {	    if (radius_setparams(received, radius_msg, req_info, digest,				 challenge, message, message_space) < 0) {		error("%s", radius_msg);		result = ERROR_RC;	    } else {		rstate.done_chap_once = 1;	    }	}    }    rc_avpair_free(received);    rc_avpair_free (send);    return (result == OK_RC);}/*********************************************************************** %FUNCTION: make_username_realm* %ARGUMENTS:*  user -- the user given to pppd* %RETURNS:*  Nothing* %DESCRIPTION:*  Copies user into rstate.user.  If it lacks a realm (no "@domain" part),* then the default realm from the radiusclient config file is added.***********************************************************************/static voidmake_username_realm(char *user){    char *default_realm;    if ( user != NULL ) {	strlcpy(rstate.user, user, sizeof(rstate.user));    }  else {	rstate.user[0] = 0;    }    default_realm = rc_conf_str("default_realm");    if (!strchr(rstate.user, '@') &&	default_realm &&	(*default_realm != '\0')) {	strlcat(rstate.user, "@", sizeof(rstate.user));	strlcat(rstate.user, default_realm, sizeof(rstate.user));    }}/*********************************************************************** %FUNCTION: radius_setparams* %ARGUMENTS:*  vp -- received value-pairs*  msg -- buffer in which to place error message.  Holds up to BUF_LEN chars* %RETURNS:*  >= 0 on success; -1 on failure* %DESCRIPTION:*  Parses attributes sent by RADIUS server and sets them in pppd.***********************************************************************/static intradius_setparams(VALUE_PAIR *vp, char *msg, REQUEST_INFO *req_info,		 struct chap_digest_type *digest, unsigned char *challenge,		 char *message, int message_space){    u_int32_t remote;    int ms_chap2_success = 0;#ifdef MPPE    int mppe_enc_keys = 0;	/* whether or not these were received */    int mppe_enc_policy = 0;    int mppe_enc_types = 0;#endif    /* Send RADIUS attributes to anyone else who might be interested */    if (radius_attributes_hook) {	(*radius_attributes_hook)(vp);    }    /*     * service type (if not framed then quit),     * new IP address (RADIUS can define static IP for some users),     */    while (vp) {	if (vp->vendorcode == VENDOR_NONE) {	    switch (vp->attribute) {	    case PW_SERVICE_TYPE:		/* check for service type       */		/* if not FRAMED then exit      */		if (vp->lvalue != PW_FRAMED) {		    slprintf(msg, BUF_LEN, "RADIUS: wrong service type %ld for %s",			     vp->lvalue, rstate.user);		    return -1;		}		break;	    case PW_FRAMED_PROTOCOL:		/* check for framed protocol type       */		/* if not PPP then also exit            */		if (vp->lvalue != PW_PPP) {		    slprintf(msg, BUF_LEN, "RADIUS: wrong framed protocol %ld for %s",			     vp->lvalue, rstate.user);		    return -1;		}		break;	    case PW_SESSION_TIMEOUT:		/* Session timeout */		maxconnect = vp->lvalue;		break;#ifdef MAXOCTETS	    case PW_SESSION_OCTETS_LIMIT:		/* Session traffic limit */		maxoctets = vp->lvalue;		break;	    case PW_OCTETS_DIRECTION:		/* Session traffic limit direction check */		maxoctets_dir = ( vp->lvalue > 4 ) ? 0 : vp->lvalue ;		break;#endif	    case PW_ACCT_INTERIM_INTERVAL:		/* Send accounting updates every few seconds */		rstate.acct_interim_interval = vp->lvalue;		/* RFC says it MUST NOT be less than 60 seconds */		/* We use "0" to signify not sending updates */		if (rstate.acct_interim_interval &&		    rstate.acct_interim_interval < 60) {		    rstate.acct_interim_interval = 60;		}		break;	    case PW_FRAMED_IP_ADDRESS:		/* seting up remote IP addresses */		remote = vp->lvalue;		if (remote == 0xffffffff) {		    /* 0xffffffff means user should be allowed to select one */		    rstate.any_ip_addr_ok = 1;		} else if (remote != 0xfffffffe) {		    /* 0xfffffffe means NAS should select an ip address */		    remote = htonl(vp->lvalue);		    if (bad_ip_adrs (remote)) {			slprintf(msg, BUF_LEN, "RADIUS: bad remote IP address %I for %s",				 remote, rstate.user);			return -1;		    }		    rstate.choose_ip = 1;		    rstate.ip_addr = remote;		}		break;	    case PW_CLASS:		/* Save Class attribute to pass it in accounting request */		if (vp->lvalue <= MAXCLASSLEN) {		    rstate.class_len=vp->lvalue;		    memcpy(rstate.class, vp->strvalue, rstate.class_len);		} /* else too big for our buffer - ignore it */		break;	    }#ifdef CHAPMS	} else if (vp->vendorcode == VENDOR_MICROSOFT) {	    switch (vp->attribute) {	    case PW_MS_CHAP2_SUCCESS:		if ((vp->lvalue != 43) || strncmp(vp->strvalue + 1, "S=", 2)) {		    slprintf(msg,BUF_LEN,"RADIUS: bad MS-CHAP2-Success packet");		    return -1;		}		if (message != NULL)		    strlcpy(message, vp->strvalue + 1, message_space);		ms_chap2_success = 1;		break;#ifdef MPPE	    case PW_MS_CHAP_MPPE_KEYS:		if (radius_setmppekeys(vp, req_info, challenge) < 0) {		    slprintf(msg, BUF_LEN,			     "RADIUS: bad MS-CHAP-MPPE-Keys attribute");		    return -1;		}		mppe_enc_keys = 1;		break;	    case PW_MS_MPPE_SEND_KEY:	    case PW_MS_MPPE_RECV_KEY:		if (radius_setmppekeys2(vp, req_info) < 0) {		    slprintf(msg, BUF_LEN,			     "RADIUS: bad MS-MPPE-%s-Key attribute",			     (vp->attribute == PW_MS_MPPE_SEND_KEY)?			     "Send": "Recv");		    return -1;		}		mppe_enc_keys = 1;		break;	    case PW_MS_MPPE_ENCRYPTION_POLICY:		mppe_enc_policy = vp->lvalue;	/* save for later */		break;	    case PW_MS_MPPE_ENCRYPTION_TYPES:		mppe_enc_types = vp->lvalue;	/* save for later */		break;#endif /* MPPE */#if 0	    case PW_MS_PRIMARY_DNS_SERVER:	    case PW_MS_SECONDARY_DNS_SERVER:	    case PW_MS_PRIMARY_NBNS_SERVER:	    case PW_MS_SECONDARY_NBNS_SERVER:		break;#endif	    }#endif /* CHAPMS */	}	vp = vp->next;    }    /* Require a valid MS-CHAP2-SUCCESS for MS-CHAPv2 auth */    if (digest && (digest->code == CHAP_MICROSOFT_V2) && !ms_chap2_success)	return -1;#ifdef MPPE    /*     * Require both policy and key attributes to indicate a valid key.     * Note that if the policy value was '0' we don't set the key!     */    if (mppe_enc_policy && mppe_enc_keys) {	mppe_keys_set = 1;	/* Set/modify allowed encryption types. */	if (mppe_enc_types)	    set_mppe_enc_types(mppe_enc_policy, mppe_enc_types);    }#endif    return 0;}#ifdef MPPE/*********************************************************************** %FUNCTION: radius_setmppekeys* %ARGUMENTS:*  vp -- value pair holding MS-CHAP-MPPE-KEYS attribute*  req_info -- radius request information used for encryption* %RETURNS:*  >= 0 on success; -1 on failure* %DESCRIPTION:*  Decrypt the "key" provided by the RADIUS server for MPPE encryption.*  See RFC 2548.***********************************************************************/static intradius_setmppekeys(VALUE_PAIR *vp, REQUEST_INFO *req_info,		   unsigned char *challenge){    int i;    MD5_CTX Context;    u_char  plain[32];    u_char  buf[16];    if (vp->lvalue != 32) {	error("RADIUS: Incorrect attribute length (%d) for MS-CHAP-MPPE-Keys",	      vp->lvalue);	return -1;    }    memcpy(plain, vp->strvalue, sizeof(plain));    MD5_Init(&Context);    MD5_Update(&Context, req_info->secret, strlen(req_info->secret));    MD5_Update(&Context, req_info->request_vector, AUTH_VECTOR_LEN);    MD5_Final(buf, &Context);    for (i = 0; i < 16; i++)	plain[i] ^= buf[i];    MD5_Init(&Context);    MD5_Update(&Context, req_info->secret, strlen(req_info->secret));    MD5_Update(&Context, vp->strvalue, 16);    MD5_Final(buf, &Context);    for(i = 0; i < 16; i++)	plain[i + 16] ^= buf[i];    /*     * Annoying.  The "key" returned is just the NTPasswordHashHash, which     * the NAS (us) doesn't need; we only need the start key.  So we have     * to generate the start key, sigh.  NB: We do not support the LM-Key.     */    mppe_set_keys(challenge, &plain[8]);    return 0;    }/*********************************************************************** %FUNCTION: radius_setmppekeys2* %ARGUMENTS:*  vp -- value pair holding MS-MPPE-SEND-KEY or MS-MPPE-RECV-KEY attribute*  req_info -- radius request information used for encryption* %RETURNS:*  >= 0 on success; -1 on failure* %DESCRIPTION:*  Decrypt the key provided by the RADIUS server for MPPE encryption.*  See RFC 2548.***********************************************************************/static intradius_setmppekeys2(VALUE_PAIR *vp, REQUEST_INFO *req_info){    int i;    MD5_CTX Context;    u_char  *salt = vp->strvalue;    u_char  *crypt = vp->strvalue + 2;    u_char  plain[32];    u_char  buf[MD5_HASH_SIZE];    char    *type = "Send";    if (vp->attribute == PW_MS_MPPE_RECV_KEY)	type = "Recv";    if (vp->lvalue != 34) {	error("RADIUS: Incorrect attribute length (%d) for MS-MPPE-%s-Key",	      vp->lvalue, type);	return -1;    }    if ((salt[0] & 0x80) == 0) {	error("RADIUS: Illegal salt value for MS-MPPE-%s-Key attribute", type);	return -1;    }    memcpy(plain, crypt, 32);    MD5_Init(&Context);    MD5_Update(&Context, req_info->secret, strlen(req_info->secret));    MD5_Update(&Context, req_info->request_vector, AUTH_VECTOR_LEN);    MD5_Update(&Context, salt, 2);    MD5_Final(buf, &Context);    for (i = 0; i < 16; i++)	plain[i] ^= buf[i];    if (plain[0] != sizeof(mppe_send_key) /* 16 */) {	error("RADIUS: Incorrect key length (%d) for MS-MPPE-%s-Key attribute",	      (int) plain[0], type);	return -1;    }    MD5_Init(&Context);    MD5_Update(&Context, req_info->secret, strlen(req_info->secret));    MD5_Update(&Context, crypt, 16);    MD5_Final(buf, &Context);    plain[16] ^= buf[0]; /* only need the first byte */    if (vp->attribute == PW_MS_MPPE_SEND_KEY)	memcpy(mppe_send_key, plain + 1, 16);    else	memcpy(mppe_recv_key, plain + 1, 16);    return 0;}#endif /* MPPE *//*********************************************************************** %FUNCTION: radius_acct_start* %ARGUMENTS:*  None* %RETURNS:*  Nothing* %DESCRIPTION:*  Sends a "start" accounting message to the RADIUS server.***********************************************************************/static voidradius_acct_start(void){    UINT4 av_type;    int result;    VALUE_PAIR *send = NULL;    ipcp_options *ho = &ipcp_hisoptions[0];    u_int32_t hisaddr;    if (!rstate.initialized) {	return;    }    rstate.start_time = time(NULL);    strncpy(rstate.session_id, rc_mksid(), sizeof(rstate.session_id));    rc_avpair_add(&send, PW_ACCT_SESSION_ID,		   rstate.session_id, 0, VENDOR_NONE);    rc_avpair_add(&send, PW_USER_NAME,		   rstate.user, 0, VENDOR_NONE);    if (rstate.class_len > 0)	rc_avpair_add(&send, PW_CLASS,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -