📄 authenticate.c
字号:
return EV_NAK; } } list_cat (&authreq->cur_request, user_reply); } else { if (authreq->user_deny == NULL_VP) { /* Look in the database only if both lists are NULL. */ if ((retval = user_find ((char *) authreq->client->file_pfx, namepair->strvalue, protocol, (VALUE_PAIR **) NULL, &authreq->user_deny, (VALUE_PAIR **) NULL, 0)) < 0) { logit (LOG_AUTH, LOG_ERR, "%s: from %s - Problem in user_find()", func, ip_hostname (authreq->ipaddr)); } else { if (retval > 0) { if (user_find ((char *) authreq->client->file_pfx, "DEFAULT", protocol, (VALUE_PAIR **) NULL, &authreq->user_deny, (VALUE_PAIR **) NULL, 0) != 0) { logit (LOG_AUTH, LOG_ERR, "%s: from %s - Invalid/missing 'DEFAULT' entry", func, ip_hostname (authreq-> ipaddr)); } } } } } result = EV_ACK; /* assume good until proven otherwise */ /* No null names allowed */ if (*namepair->strvalue == '\0') { result = EV_NAK; }/* #ifdef USR_CCA */ /* RESOURCE MANAGEMENT *//* if (authreq->code == PW_ACCESS_REQUEST && result != EV_NAK && * (term_act = get_vp (authreq->cur_request, * PW_TERMINATION_ACTION)) != NULL_VP) * { * if (term_act->lvalue == PW_MANAGE_RESOURCES) * { * result = resource_mgmt (authreq); * if (result == EV_ACK) * { * res_assigned = TRUE; * } * } * } *//* #endif * USR_CCA */ /* * See if this is strictly an authentication check. * Throw out all but pw and pw expiration items if it is. */ if ((auth_item = get_vp (authreq->cur_request, PW_SERVICE_TYPE)) != NULL_VP && (auth_item->lvalue == PW_AUTHENTICATE_ONLY)) { for (prev_ptr = &authreq->user_check, check_item = *prev_ptr; check_item != NULL_VP; check_item = *prev_ptr) { if (check_item->ap->flags & ATTR_CONFIG) { switch (check_item->attribute) { case CI_PROHIBIT: if (check_item->lvalue == PW_AUTH_ONLY) { result = EV_NAK; } /* Leave in user_check list */ prev_ptr = &check_item->next; continue; case CI_ENCRYPTED_PASSWORD: case CI_USER_PASSWORD: case CI_AUTHENTICATION_TYPE: found_pw = 1; /***FALLTHROUGH***/ case CI_EXPIRATION: case CI_SERVER_NAME: /* Leave in user_check list */ prev_ptr = &check_item->next; continue; default: break; } } /* Remove all others from list */ *prev_ptr = check_item->next; avpair_free (check_item); } if (found_pw == 0) /* Authenticate-Only requires a password! */ { result = EV_NAK; } } /* Check those check items */ dprintf(4, (LOG_AUTH, LOG_DEBUG, "%s: about to check user_check items", func)); for (check_item = authreq->user_check; ((result == EV_ACK) && (check_item != NULL_VP)); check_item = check_item->next) { if (check_item->ap->flags & ATTR_CONFIG) { switch (check_item->attribute) { /* * Check expiration date if we are doing password * aging. */ case CI_EXPIRATION: /* Has this user's password expired */ retval = pw_expired (check_item->lvalue, user_reply); if (retval < 0) { reply_sprintf (0, authreq, "Password Has Expired");#ifdef ASCEND result = EV_PW_EXPIRED; } else if (retval > 0) { reply_sprintf (0, authreq, "Password will expire in %d days", retval);#else /* ASCEND */ result = EV_NAK;#endif /* ASCEND */ } if (retval > 0) { reply_sprintf (RS_IF_ACK, authreq, "Password Will Expire in %d Days", retval); } break; case CI_SERVER_NAME: server_name = check_item->strvalue; break; case CI_AUTHENTICATION_TYPE: case CI_SIMULTANEOUS_USE: case CI_COMMENT: case CI_PROHIBIT: case CI_SERVICE_CLASS: break; case CI_ENCRYPTED_PASSWORD: retval = get_passwd (authreq, pwmsg, check_item->strvalue, check_item->strvalue); if (retval != 0) { result = EV_NAK; } memset ((char *) pwmsg, '\0', sizeof (pwmsg)); break; case CI_USER_PASSWORD: /* * Pass password to get_passwd() so it will * do CHAP and PASSWORD check for us. */#ifdef ASCEND /* * If this is Ascend ARADES authentication, * this is the wrong place to check this. * This will fail since the password is * not sent in the Access-Request. */ if ((auth_item = get_vp_vend (authreq->cur_request, PW_ASCEND_ARADES, VC_ASCEND)) != NULL_VP) { break; }#endif /* ASCEND */ retval = get_passwd (authreq, pwmsg, check_item->strvalue, (char *) NULL); if (retval != 0) { dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: invalid password, retval = %d", func, retval)); result = EV_NAK; } /* Test Code for Challenge */ if (strcmp (pwmsg, "challenge") == 0 && retval == 1) { memset ((char *) pwmsg, 0, sizeof (pwmsg)); reply_sprintf (RS_IF_ACK, authreq, "You want me to challenge you??\r\nOkay I will"); avpair_add (&authreq->cur_request, PW_STATE, "1", -1); result = EV_ACC_CHAL; } memset ((char *) pwmsg, 0, sizeof (pwmsg)); break; default: break; } continue; } /* * Process check items that didn't require special processing * above. Just look for the matching attribute in the * request. */ result = check_request (authreq, check_item, CHK_ACCEPT | CHK_ONCE); } /* end of "Check those check items" */ /* Check those deny items */ if (result == EV_ACK) { result = check_request (authreq, authreq->user_deny, CHK_DENY | CHK_MESSAGE); } /* end of "Check those deny items" */ if ((result == EV_ACK) && (check_item = get_vp_ci (authreq->user_check, CI_AUTHENTICATION_TYPE, 0)) != NULL_VP) { if (authtype_tv[check_item->lvalue] == (AATV *) NULL) { logit (LOG_DAEMON, LOG_ERR, "%s: FATAL: Unsupported authentication type %d for %s", func, check_item->lvalue, namepair->strvalue); logit (LOG_DAEMON, LOG_ERR, "%s: CHECK THE MAKEFILE BUILD!", func); result = EV_FATAL; } else {#ifdef MERIT_LAS /* * See if it's one of the authentication types * which allow caching. If so, call the AATV * which checks the cache before calling the * authentication AATV. */ cache_token = 0; for (i = 0; token_caching_auth_type[i]; i++) { if (check_item->lvalue == token_caching_auth_type[i]) { cache_token = 1; } } if (cache_token > 0) { result = call_action (rad_cache_chk_aatv, authreq, 0, server_name); } else#endif /* MERIT_LAS */ { result = call_action (authtype_tv[check_item->lvalue], authreq, 0, server_name); } } }/* #ifdef USR_CCA if (result != EV_ACK && result != EV_WAIT && res_assigned == TRUE) { if ((framed_ip_vp = get_vp (authreq->cur_request, PW_FRAMED_IP_ADDRESS)) != NULL_VP) { framed_ip = framed_ip_vp->lvalue; } if ((nas_vp = get_vp (authreq->cur_request, PW_NAS_IP_ADDRESS)) != NULL_VP) { nas = nas_vp->lvalue; } if ((nas_port_vp = get_vp (authreq->cur_request, PW_NAS_PORT)) != NULL_VP) { nas_port = nas_port_vp->lvalue; } free_resources (namepair->strvalue, framed_ip, nas, nas_port); }*//* #endif * USR_CCA */#ifdef USR_CCA /* RESOURCE MANAGEMENT */ /* For Local-VPN type, CI_AUTHENTICATON_TYPE will be NULL */ if (result != EV_NAK && check_item == NULL_VP) { if (authreq->code == PW_ACCESS_REQUEST && (term_act = get_vp (authreq->cur_request, PW_TERMINATION_ACTION)) != NULL_VP) { if (term_act->lvalue == PW_MANAGE_RESOURCES) { result = resource_mgmt (authreq); /* if (result == EV_ACK) { res_assigned = TRUE; } */ } } }#endif /* USR_CCA */ return result;} /* end of rad_authenticate () */static void rad_2rad_init PROTO((AATV *));static int radius_pass PROTO((AUTH_REQ *, int, char *));static AATV rad2rad_aatv = DEF_AATV_SOCKET_TYPE("RAD2RAD", AA_RAD, rad_2rad_init, radius_pass, rad_2rad_recv);AATVPTR rad_2rad_aatv = & rad2rad_aatv;/************************************************************************* * * Function: rad_2rad_init * * Purpose: Perform RADIUS to RADIUS initialization. * *************************************************************************/static voidrad_2rad_init (aatv)AATV *aatv;{ struct sockaddr_in lclsin; static char *func = "rad_2rad_init"; dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: entered", func)); if (aatv->sockfd == -1) { aatv->sockfd = setupsock (&lclsin, 0); } return;} /* end of rad_2rad_init () *//************************************************************************* * * Function: radius_pass * * Purpose: Have remote RADIUS system handle authentication for this * RADIUS to RADIUS request. * * Returns: EV_ACK if valid userid and pw, * EV_NAK if invalid, * EV_WAIT if request issued. * *************************************************************************/static intradius_pass (authreq, value, realm)AUTH_REQ *authreq;int value;char *realm;{ VALUE_PAIR *vp; char id[AUTH_ID_LEN + 1]; int code; static char *func = "radius_pass"; code = authreq->code;#ifdef USR_CCA if (code != PW_NAS_REB_REQ && (vp = get_vp_vend (authreq->cur_request, PW_USER_ID, VC_MERIT)) == NULL_VP)#else /* USR_CCA */ if ((vp = get_vp_vend (authreq->cur_request, PW_USER_ID, VC_MERIT)) == NULL_VP)#endif /* USR_CCA */ { logit (LOG_DAEMON, LOG_ALERT, "%s: Improper userid specification", func); reply_message (authreq, EC_INTERNAL, func); return EV_NAK; } strcpy (id, vp->strvalue); /* * If no server system DNS name is provided, a default is used. * Set #define DEFAULT_RADIUS_SERVER (or set it in authfile) * to the name of the default server system to use for * RADIUS authentication. */ if ((realm == NULL) || (realm[0] == '\0')) { realm = default_radius_server; } dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: name = %s realm = %s", func, id, realm)); /* Check to see if we are the server for this realm */#ifdef USR_CCA if (code != PW_NAS_REB_REQ && strcasecmp (ourhostname, realm) == 0)#else /* USR_CCA */ if (strcasecmp (ourhostname, realm) == 0)#endif /* USR_CCA */ { dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: handle locally", func)); /* Treat this one just like Unix-PW authentication */ return call_action (authtype_tv[AA_UNIX], authreq, 0, realm); } dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: handle remotely", func)); if (radius_send ((char *) authreq->fsm_aatv->id, code, 0, realm, authreq, rad2rad_aatv.sockfd) == -1) { return EV_NAK; } return EV_WAIT; /* RC says to expect reply later */} /* end of radius_pass () */static int slow_pass PROTO((AUTH_REQ *, int, char *));static AATV slow_aatv = DEF_AATV_FREPLY_TYPE("SLOW", AA_SLOW, NULL, slow_pass, 2);AATVPTR rad_slow_aatv = & slow_aatv;/************************************************************************* * * Function: slow_pass * * Purpose: Enable flexible debugging of realm type autthentication. * *************************************************************************/static intslow_pass (authreq, value, af_param)AUTH_REQ *authreq;int value;char *af_param;{ int authprot; int type; char *agent; char *filter; char *pfx = (char *) NULL; char *realm; VALUE_PAIR *rlm_vp = NULL_VP; VALUE_PAIR *vp; static char *func = "slow_pass"; dprintf(1, (LOG_AUTH, LOG_DEBUG, "%s: entered", func)); /* If there is a prefix assocated with this authreq, get it. */ if (authreq != (AUTH_REQ *) NULL) { if (authreq->client != (CLIENT_ENTRY *) NULL) { pfx = authreq->client->file_pfx; } } if (af_param == (char *) NULL) { reply_sprintf (RS_LOG, authreq, "%s: Missing sub-realm", func); return EV_NAK; } /* Get realm for messages, etc. */ rlm_vp = get_vp_vend (authreq->cur_request, PW_USER_REALM, VC_MERIT); /* Determine authentication protocol type */ if (get_vp (authreq->cur_request, PW_CHAP_PASSWORD)) { authprot = PW_PROTTYPE_CHAP; } else { authprot = PW_PROTTYPE_PW; } /* Try to match the realm name in the authfile. */ if (find_auth_type (af_param, authprot, pfx, &type, &agent, &realm, &filter) != 0) { reply_sprintf (RS_LOG, authreq, "%s: Invalid authentication sub-realm: '%s'", func, af_param); return EV_NAK; } /* Check the various different types... */ switch (type) { case AA_SLOW: reply_sprintf (RS_LOG, authreq, "%s: Slow won't stack realm (%s)", func, af_param); return EV_NAK; case AA_REALM: reply_sprintf (RS_LOG, authreq, "%s: Invalid type '%d' in authfile", func, type); return EV_NAK;#ifdef USR_CCA case AA_LOCAL_VPN: /* * This is an error since all users belonging to a * Local VPN must be defined in the local users file, * so this function must not be called in the first * place. */ vp = get_vp (authreq->cur_request, PW_USER_NAME); logit (LOG_AUTH, LOG_ERR, "%s: User %s of realm %s not defined", func, vp->strvalue, af_param); return EV_NAK;#endif /* USR_CCA */ } /* end of switch */ if (authtype_tv[type] == (AATV *) NULL) { reply_sprintf (RS_LOG, authreq, "%s: Unsupported authentication type %d", func, type); return EV_NAK; } rad_sleep (10, "%s (xxx, %d, '%s'), sleeping", func, value, agent); return call_action (authtype_tv[type], authreq, value, agent);} /* end of slow_pass () */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -