📄 radiusd.c
字号:
continue; } /* Attribute vp1 is different from vp2. */ *p_why = "string mismatch"; return (0); /* Not a duplicate */ } if ((pw_vp1 != NULL_VP) || (pw_vp2 != NULL_VP)) { logit (LOG_DAEMON, LOG_INFO, "%s: More than one password in request (ignored)", func); } else /* Save the passwords for later processing. */ { pw_vp1 = vp1; pw_vp2 = vp2; } } /* end of for each of the attribute in both requests */ /* * At this point, all that's left to compare are the passwords. * Since this attribute is a User-Password, * just decrypt it and compare the passwords. * * Note that the caller is informed what the password * in auth1 was via the p_pw1 and p_pw_vp1 parameters. */ if (*p_pw_vp1 == NULL_VP) { *p_pw_vp1 = pw_vp1; /* Save it. */ } else { if (*p_pw_vp1 != pw_vp1) { logit (LOG_DAEMON, LOG_CRIT, "%s: Internal error, *p_pw_vp1 != pw_vp1", func); pw1 = (char *) NULL; /* Force decryption again. */ } } /* * Check to see if the password of the incoming request has been * decrypted. * * Warning: This code assumes that only ONE User-Password will * be present in a request at a time. */ if (pw1 == (char *) NULL) { /* * Indicate that the password of the new * request has been decrypted. */ pw1 = pw1_buff; /* Decrypt the newly arrived password. */ get_passwd (auth1, pw1, (char *) NULL, (char *) NULL); *p_pw1 = pw1; } /* Try to decrypt the password that is on the queue. */ if (get_passwd (auth2, pw2, (char *) NULL, (char *) NULL) != 0) { /* Unable to get a password decrypted. Not a match. */ *p_why = "queued User-Password fail"; return (0); /* Assume not a duplicate */ } /* Compare the passwords. (Passwords shouldn't have NULL's in them.) */ if (strcmp (pw1, pw2) != 0) /* Passwords aren't the same. */ { /* Safety, clear the passwords. */ memset ((char *) pw1_buff, 0, sizeof (pw1_buff)); memset ((char *) pw2, 0, sizeof (pw2)); *p_why = "User-Password mismatch"; return (0); } /* Safety, clear the passwords. */ memset ((char *) pw1_buff, 0, sizeof (pw1_buff)); memset ((char *) pw2, 0, sizeof (pw2)); return (1); /* Everything matches. */} /* end of authreq_dup_check () *//************************************************************************* * * Function: authreq_q_size * * Purpose: Indicate current length of authentication or accounting queue. * *************************************************************************/static intauthreq_q_size (authreq)AUTH_REQ *authreq;{ int count; for (count = 0; authreq != (AUTH_REQ *) NULL; authreq = authreq->next) { count++; } return count;} /* end of authreq_q_size () *//************************************************************************* * * Function: authreq_holdtime * * Purpose: Compute cleanup hold time for the given AUTH_REQ. * * Returns: hold time in seconds. * *************************************************************************/intauthreq_holdtime (authreq)AUTH_REQ *authreq;{ int hold_time; /* By default, use the value configured in the clients file. */ hold_time = authreq->client->reply_holdtime; if (hold_time == 0) /* Then, use what's left in the authreq */ { hold_time = authreq->ttl; } /* Calculate the average holding (floored) time now. */ if ((hold_time = cleanup_delay (hold_time)) > 0) { return hold_time; } return 1; /* Safety */} /* end of authreq_holdtime () *//************************************************************************* * * Function: build_acct_req * * Purpose: Build an acct-request structure, fill out the header and * other values and attach attribute-value pairs as needed. * * Returns: a pointer to an authreq data structure, * or NULL, if the queue is too full. * *************************************************************************/AUTH_REQ *build_acct_req (authreq, status, session_id, stime, pairs)AUTH_REQ *authreq; /* optional (may be NULL), so ignore */int status; /* required! */char *session_id; /* optional (may be NULL), so create */time_t stime; /* session time */VALUE_PAIR *pairs; /* optional (may be NULL), so ignore */{ int flag; int qcount = 0; UINT4 ip; /* Dummy value for find_client_by_name() call */ time_t now = time (0); AUTH_REQ *acctreq; VALUE_PAIR *vp; VALUE_PAIR *name; VALUE_PAIR *nas; VALUE_PAIR **prev_ptr; FILE *debugout = stdout; char buf[AUTH_STRING2_LEN]; static int id = -1; static char *func = "build_acct_req"; dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func)); if (ddt != (FILE *) NULL) { debugout = ddt; } /* * Allocate the new accounting data structure. */ if ((acctreq = (AUTH_REQ *) calloc (1, sizeof (AUTH_REQ))) == (AUTH_REQ *) NULL) { logit (LOG_DAEMON, LOG_ALERT, "%s: FATAL out of memory", func); abort (); } authreq_mf.m++; /* * Fill header fields */ acctreq->ipaddr = get_our_addr (); acctreq->udp_port = 0; /* dummy values -- don't care */ acctreq->rep_id = 0; /* dummy values -- don't care */ acctreq->fwd_id = 0; acctreq->code = PW_ACCOUNTING_REQUEST; memset ((char *) acctreq->repvec, 0, sizeof (authreq->repvec)); memset ((char *) acctreq->fwdvec, 0, sizeof (authreq->fwdvec)); if (authreq != (AUTH_REQ *) NULL) /* Pick up client from here. */ { acctreq->client = authreq->client; } else { if (find_client_by_name (RADIUS_LOCALSERVER, &ip, &acctreq->client) < 0) { acctreq->client = (CLIENT_ENTRY *) NULL; } } acctreq->ttlslice = MAX_ACCT_REQUEST_TIME; /* About three minutes. */ acctreq->ttl = MAX_ACCT_REQUEST_TIME; acctreq->timer = DEFAULT_TIMER_VALUE; acctreq->retry_cnt = 0; acctreq->seqch_cnt = 0; acctreq->retry_limit = default_retry_limit; acctreq->seqch_limit = default_seqch_limit; acctreq->vers_in = 0; acctreq->vers_out = 0; acctreq->flags = 0; acctreq->realm_filter = (char *) NULL; if (authreq != (AUTH_REQ *) NULL) /* Pick up state from where we are. */ { acctreq->state = authreq->state; acctreq->debug_flag = authreq->debug_flag; } else { acctreq->state = ST_INIT; acctreq->debug_flag = 0; /* No special debugging. */ } acctreq->sws = 0; if (global_acct_q.hold > 0) { SAR_HOLD(acctreq); /* Set hold flag in sws. */ } acctreq->repstatus = -2; /* invalid value */ acctreq->fsmstatus = EV_NAK; /* initial value */ acctreq->cur_count = 0; acctreq->onqueue = now; acctreq->starthg = now; acctreq->startlas = now; acctreq->fsm_aatv = (AATV *) NULL; acctreq->direct_aatv = (AATV *) NULL; acctreq->event_q = (EVENT_ENT *) NULL; acctreq->proc_q = (PROC_ENT *) NULL; acctreq->next = (AUTH_REQ *) NULL; acctreq->request = NULL_VP; acctreq->cur_request = NULL_VP; acctreq->user_check = NULL_VP; acctreq->user_deny = NULL_VP; if (pairs != NULL_VP) { dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: pairs list:", func)); debug_list (debugout, pairs); } flag = 0; if (authreq != (AUTH_REQ *) NULL) { dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: authreq->cur_request:", func)); debug_list (debugout, authreq->cur_request); if (get_vp (authreq->cur_request, PW_ACCT_STATUS_TYPE) == NULL_VP) { avpair_add (&acctreq->request, PW_ACCT_STATUS_TYPE, &status, 0); } if (status == PW_STATUS_MODEM_STOP) { if (get_vp (authreq->cur_request, PW_ACCT_SESSION_TIME) == NULL_VP) { avpair_add (&acctreq->request, PW_ACCT_SESSION_TIME, &stime, 0); } } if ((vp = get_vp (authreq->cur_request, PW_ACCT_SESSION_ID)) == NULL_VP) { flag = 1; /* Since no Acct-Session-Id can be present */ } } else /* was NULL */ { flag = 1; avpair_add (&acctreq->request, PW_ACCT_STATUS_TYPE, &status, 0); avpair_add (&acctreq->request, PW_ACCT_SESSION_TIME, &stime, 0); } if (flag == 1) /* This ACCT packet needs an Acct-Session-Id */ { if (session_id == (char *) NULL) /* create unique one */ { sprintf (buf, "%08X", ++id); } else /* use the one given by the caller */ { memcpy (buf, session_id, 8); } avpair_add (&acctreq->request, PW_ACCT_SESSION_ID, buf, 8); } if (pairs != NULL_VP) { list_copy (&acctreq->request, pairs); } if ((authreq != (AUTH_REQ *) NULL) && (authreq->cur_request != NULL_VP)) { list_copy (&acctreq->request, authreq->cur_request); } /* Remove attributes which should never be in ACCT packet (per RFC) */ for (prev_ptr = &acctreq->request, vp = *prev_ptr; vp != NULL_VP; vp = *prev_ptr) { switch (vp->ap->vendor_id) { default: /* No special treatment for unknown vendors. */ break; case VC_RADIUS: /* Standard attribute space. */ switch (vp->attribute) { case PW_USER_PASSWORD: case PW_CHAP_PASSWORD: case PW_REPLY_MESSAGE: case PW_STATE: /* Remove these from the request list. */ *prev_ptr = vp->next; avpair_free (vp); continue; default: break; } break; case VC_MERIT: /* Merit vendor specific attributes. */ switch (vp->attribute) { case PW_PROXY_ACTION: /* Remove these from the request list. */ *prev_ptr = vp->next; avpair_free (vp); continue; default: break; } break; } /* Leave all others in request list. */ prev_ptr = &vp->next; } list_copy (&acctreq->cur_request, acctreq->request); debug_list (debugout, acctreq->cur_request); if (enqueue_authreq (&global_acct_q, acctreq) == (AUTH_REQ *) NULL) { name = get_vp (acctreq->cur_request, PW_USER_NAME); nas = get_vp (acctreq->cur_request, PW_NAS_IDENTIFIER); vp = get_vp (acctreq->cur_request, PW_NAS_PORT); logit (LOG_DAEMON, LOG_INFO, "%s: global_acct_q.limit (%d) exceeded (%d)", func, global_acct_q.limit, qcount); logit (LOG_DAEMON, LOG_INFO, "%s: Acct-Status-Type %d - %s on port %ld of %s", func, status, (name != NULL_VP) ? name->strvalue : "'?'", (vp != NULL_VP) ? vp->lvalue : -1, (nas != NULL_VP) ? nas->strvalue : "'?'"); /* Mark it free'd so that free_authreq_final() does free it. */ SAR_FREED(acctreq); free_authreq_final (acctreq); return (AUTH_REQ *) NULL; /* Rejected */ } return acctreq;} /* end of build_acct_req () *//************************************************************************* * * Function: call_action * * Purpose: Calls the action function specified by the AATV argument. * * Returns: The result (return code or "event") of the action function. * *************************************************************************/intcall_action (aatv, authreq, value, afpar)AATV *aatv;AUTH_REQ *authreq;int value;char *afpar;{ int i; int old_debug = debug_flag; int pid; int result; AATV *previous_aatv = (AATV *) NULL; PROC_ENT *pe; VALUE_PAIR *vp; sigset_t signals; struct sigaction action; char buffer[AUTH_STRING1_LEN]; static char *func = "call_action"; if (aatv == (AATV *) NULL) { dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: configuration error: NULL AATV, value %d and '%s'", func, value, (afpar == (char *) NULL) ? "?" : afpar)); return EV_FATAL; } dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: AATV '%s', type %d, value %d and '%s'", func, aatv->id, aatv->aatvfunc_type, value, (afpar == (char *) NULL) ? "?" : afpar)); if (authreq != (AUTH_REQ *) NULL) { if (aatv != authreq->fsm_aatv) { if (authreq->fsm_aatv != (AATV *) NULL) { authreq->direct_aatv = aatv; } else /* Need to init fsm_aatv value */ { authreq->fsm_aatv = aatv; } } /* * Modi
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -