int rc_check(char *host, unsigned short port, char *msg) { SEND_DATA data; int result; UINT4 service_type; int timeout = rc_conf_int("radius_timeout"); int retries = rc_conf_int("radius_retries"); data.send_pairs = data.receive_pairs = NULL; /* * Fill in NAS-IP-Address or NAS-Identifier, * although it isn't neccessary */ if (rc_get_nas_id(&(data.send_pairs)) == ERROR_RC) return (ERROR_RC); /* * Fill in Service-Type */ service_type = PW_ADMINISTRATIVE; rc_avpair_add(&(data.send_pairs), PW_SERVICE_TYPE, &service_type, 0, VENDOR_NONE); rc_buildreq(&data, PW_STATUS_SERVER, host, port, timeout, retries); result = rc_send_server (&data, msg, NULL); rc_avpair_free(data.receive_pairs); return result; }
int rc_acct_using_server(SERVER *acctserver, UINT4 client_port, VALUE_PAIR *send) { SEND_DATA data; VALUE_PAIR *adt_vp; int result; time_t start_time, dtime; char msg[4096]; int i; int timeout = rc_conf_int("radius_timeout"); int retries = rc_conf_int("radius_retries"); data.send_pairs = send; data.receive_pairs = NULL; /* * Fill in NAS-IP-Address or NAS-Identifier */ if (rc_get_nas_id(&(data.send_pairs)) == ERROR_RC) return (ERROR_RC); /* * Fill in NAS-Port */ if (rc_avpair_add(&(data.send_pairs), PW_NAS_PORT, &client_port, 0, VENDOR_NONE) == NULL) return (ERROR_RC); /* * Fill in Acct-Delay-Time */ dtime = 0; if ((adt_vp = rc_avpair_add(&(data.send_pairs), PW_ACCT_DELAY_TIME, &dtime, 0, VENDOR_NONE)) == NULL) return (ERROR_RC); start_time = time(NULL); result = ERROR_RC; for(i=0; (i<acctserver->max) && (result != OK_RC) && (result != BADRESP_RC) ; i++) { if (data.receive_pairs != NULL) { rc_avpair_free(data.receive_pairs); data.receive_pairs = NULL; } rc_buildreq(&data, PW_ACCOUNTING_REQUEST, acctserver->name[i], acctserver->port[i], timeout, retries); dtime = time(NULL) - start_time; rc_avpair_assign(adt_vp, &dtime, 0); result = rc_send_server (&data, msg, NULL); } rc_avpair_free(data.receive_pairs); return result; }
int rc_acct_proxy(VALUE_PAIR *send) { SEND_DATA data; int result; char msg[4096]; int i; SERVER *acctserver = rc_conf_srv("authserver"); int timeout = rc_conf_int("radius_timeout"); int retries = rc_conf_int("radius_retries"); data.send_pairs = send; data.receive_pairs = NULL; result = ERROR_RC; for(i=0; (i<acctserver->max) && (result != OK_RC) && (result != BADRESP_RC) ; i++) { if (data.receive_pairs != NULL) { rc_avpair_free(data.receive_pairs); data.receive_pairs = NULL; } rc_buildreq(&data, PW_ACCOUNTING_REQUEST, acctserver->name[i], acctserver->port[i], timeout, retries); result = rc_send_server (&data, msg, NULL); } rc_avpair_free(data.receive_pairs); return result; }
/** Asks the server hostname on the specified port for a status message * * @param rh a handle to parsed configuration. * @param host the name of the server. * @param secret the secret used by the server. * @param port the server's port number. * @param msg must be an array of PW_MAX_MSG_SIZE or NULL; will contain the concatenation of any * PW_REPLY_MESSAGE received. * @return OK_RC (0) on success, negative on failure as return value. */ int rc_check(rc_handle *rh, char *host, char *secret, unsigned short port, char *msg) { SEND_DATA data; int result; uint32_t service_type; int timeout = rc_conf_int(rh, "radius_timeout"); int retries = rc_conf_int(rh, "radius_retries"); rc_type type; data.send_pairs = data.receive_pairs = NULL; if (rh->so_type == RC_SOCKET_TLS || rh->so_type == RC_SOCKET_DTLS) type = AUTH; else type = ACCT; /* * Fill in Service-Type */ service_type = PW_ADMINISTRATIVE; rc_avpair_add(rh, &(data.send_pairs), PW_SERVICE_TYPE, &service_type, 0, 0); rc_buildreq(rh, &data, PW_STATUS_SERVER, host, port, secret, timeout, retries); result = rc_send_server (rh, &data, msg, type); rc_avpair_free(data.receive_pairs); return result; }
int rc_auth_using_server(SERVER *authserver, UINT4 client_port, VALUE_PAIR *send, VALUE_PAIR **received, char *msg, REQUEST_INFO *info) { SEND_DATA data; int result; int i; int timeout = rc_conf_int("radius_timeout"); int retries = rc_conf_int("radius_retries"); data.send_pairs = send; data.receive_pairs = NULL; /* * Fill in NAS-IP-Address or NAS-Identifier */ if (rc_get_nas_id(&(data.send_pairs)) == ERROR_RC) return (ERROR_RC); /* * Fill in NAS-Port */ if (rc_avpair_add(&(data.send_pairs), PW_NAS_PORT, &client_port, 0, VENDOR_NONE) == NULL) return (ERROR_RC); result = ERROR_RC; for(i=0; (i<authserver->max) && (result != OK_RC) && (result != BADRESP_RC) ; i++) { if (data.receive_pairs != NULL) { rc_avpair_free(data.receive_pairs); data.receive_pairs = NULL; } rc_buildreq(&data, PW_ACCESS_REQUEST, authserver->name[i], authserver->port[i], timeout, retries); result = rc_send_server (&data, msg, info); } *received = data.receive_pairs; return result; }
/** Builds an authentication/accounting request for port id client_port with the value_pairs send and submits it to a server * * @param rh a handle to parsed configuration. * @param client_port the client port number to use (may be zero to use any available). * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME). * @param received an allocated array of received values. * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of any * %PW_REPLY_MESSAGE received. * @param add_nas_port if non-zero it will include %PW_NAS_PORT in sent pairs. * @param request_type one of standard RADIUS codes (e.g., %PW_ACCESS_REQUEST). * @return received value_pairs in received, messages from the server in msg and %OK_RC (0) on success, negative * on failure as return value. */ int rc_aaa(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received, char *msg, int add_nas_port, int request_type) { SEND_DATA data; VALUE_PAIR *adt_vp = NULL; int result; int i, skip_count; SERVER *aaaserver; int timeout = rc_conf_int(rh, "radius_timeout"); int retries = rc_conf_int(rh, "radius_retries"); int radius_deadtime = rc_conf_int(rh, "radius_deadtime"); double start_time = 0; double now = 0; time_t dtime; unsigned type; if (request_type != PW_ACCOUNTING_REQUEST) { aaaserver = rc_conf_srv(rh, "authserver"); type = AUTH; } else { aaaserver = rc_conf_srv(rh, "acctserver"); type = ACCT; } if (aaaserver == NULL) return ERROR_RC; data.send_pairs = send; data.receive_pairs = NULL; if (add_nas_port != 0) { /* * Fill in NAS-Port */ if (rc_avpair_add(rh, &(data.send_pairs), PW_NAS_PORT, &client_port, 0, 0) == NULL) return ERROR_RC; } if (request_type == PW_ACCOUNTING_REQUEST) { /* * Fill in Acct-Delay-Time */ dtime = 0; now = rc_getctime(); adt_vp = rc_avpair_get(data.send_pairs, PW_ACCT_DELAY_TIME, 0); if (adt_vp == NULL) { adt_vp = rc_avpair_add(rh, &(data.send_pairs), PW_ACCT_DELAY_TIME, &dtime, 0, 0); if (adt_vp == NULL) return ERROR_RC; start_time = now; } else { start_time = now - adt_vp->lvalue; } } skip_count = 0; result = ERROR_RC; for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != REJECT_RC) ; i++, now = rc_getctime()) { if (aaaserver->deadtime_ends[i] != -1 && aaaserver->deadtime_ends[i] > start_time) { skip_count++; continue; } if (data.receive_pairs != NULL) { rc_avpair_free(data.receive_pairs); data.receive_pairs = NULL; } rc_buildreq(rh, &data, request_type, aaaserver->name[i], aaaserver->port[i], aaaserver->secret[i], timeout, retries); if (request_type == PW_ACCOUNTING_REQUEST) { dtime = now - start_time; rc_avpair_assign(adt_vp, &dtime, 0); } result = rc_send_server (rh, &data, msg, type); if (result == TIMEOUT_RC && radius_deadtime > 0) aaaserver->deadtime_ends[i] = start_time + (double)radius_deadtime; } if (result == OK_RC || result == REJECT_RC || skip_count == 0) goto exit; result = ERROR_RC; for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != REJECT_RC) ; i++) { if (aaaserver->deadtime_ends[i] == -1 || aaaserver->deadtime_ends[i] <= start_time) { continue; } if (data.receive_pairs != NULL) { rc_avpair_free(data.receive_pairs); data.receive_pairs = NULL; } rc_buildreq(rh, &data, request_type, aaaserver->name[i], aaaserver->port[i], aaaserver->secret[i], timeout, retries); if (request_type == PW_ACCOUNTING_REQUEST) { dtime = rc_getctime() - start_time; rc_avpair_assign(adt_vp, &dtime, 0); } result = rc_send_server (rh, &data, msg, type); if (result != TIMEOUT_RC) aaaserver->deadtime_ends[i] = -1; } exit: if (request_type != PW_ACCOUNTING_REQUEST) { *received = data.receive_pairs; } else { rc_avpair_free(data.receive_pairs); } return result; }
//int rc_aaa(rc_handle *rh, char *host, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received, char *msg, int add_nas_port, int request_type) int rc_aaa(rc_handle *rh, const string & host, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received, char *msg, int add_nas_port, int request_type) { fprintf(stdout, "rc_aaa::Start\n"); SEND_DATA data; VALUE_PAIR *adt_vp; int result; int i, skip_count; SERVER aaaserver; int timeout = rc_conf_int(rh, "radius_timeout"); int retries = rc_conf_int(rh, "radius_retries"); int radius_deadtime = rc_conf_int(rh, "radius_deadtime"); double start_time; time_t dtime; if (request_type != PW_ACCOUNTING_REQUEST) { // aaaserver = rc_conf_srv(rh, "authserver"); // fprintf(stdout, "rc_aaa::authserver\n"); // rc_conf_srv(rh, "authserver", &aaaserver); // aaaserver.name = host; } else { // aaaserver = rc_conf_srv(rh, "acctserver"); // fprintf(stdout, "rc_aaa::acctserver\n"); } // char srvName[15] = "192.168.10.102"; // strcpy(srvName ,aaaserver.name); // fprintf(stdout, "srvName: %s\n", srvName); // fprintf(stdout, "aaaserver.name: %s\n", aaaserver.name); /* if (aaaserver == NULL) { return ERROR_RC; } */ if( !host.empty() ) { aaaserver.name = host; } data.send_pairs = send; data.receive_pairs = NULL; if (add_nas_port != 0) { /* * Fill in NAS-Port */ if (rc_avpair_add(rh, &(data.send_pairs), PW_NAS_PORT, &client_port, 0, 0) == NULL) return ERROR_RC; } if (request_type == PW_ACCOUNTING_REQUEST) { /* * Fill in Acct-Delay-Time */ dtime = 0; if ((adt_vp = rc_avpair_add(rh, &(data.send_pairs), PW_ACCT_DELAY_TIME, &dtime, 0, 0)) == NULL) return ERROR_RC; } start_time = rc_getctime(); skip_count = 0; result = ERROR_RC; // fprintf(stdout, "rc_aaa::aaaserver.max %d\n", aaaserver.max); aaaserver.max = 1; for (i=0; (i < aaaserver.max) && (result != OK_RC) && (result != BADRESP_RC); i++) { if (aaaserver.deadtime_ends != -1 && aaaserver.deadtime_ends > start_time) { skip_count++; continue; } if (data.receive_pairs != NULL) { rc_avpair_free(data.receive_pairs); data.receive_pairs = NULL; } rc_buildreq(rh, &data, request_type, aaaserver.name.c_str(), aaaserver.port, aaaserver.secret.c_str(), timeout, retries); fprintf(stdout, "rc_buildreq: data.server: %s\n", data.server.c_str()); fprintf(stdout, "rc_buildreq: data.secret: %s\n", data.secret.c_str()); fprintf(stdout, "rc_buildreq: data.svc_port: %i\n", data.svc_port); // fprintf(stdout, "aaaserver.name %s, port: %s, secert %s\n", aaaserver.name[i], aaaserver.port[i], aaaserver.secret[i]); if (request_type == PW_ACCOUNTING_REQUEST) { dtime = rc_getctime() - start_time; rc_avpair_assign(adt_vp, &dtime, 0); } result = rc_send_server (rh, &data, msg); if (result == TIMEOUT_RC && radius_deadtime > 0) aaaserver.deadtime_ends = start_time + (double)radius_deadtime; } if (result == OK_RC || result == BADRESP_RC || skip_count == 0) goto exit; result = ERROR_RC; for (i=0; (i < aaaserver.max) && (result != OK_RC) && (result != BADRESP_RC) ; i++) { if (aaaserver.deadtime_ends == -1 || aaaserver.deadtime_ends <= start_time) { continue; } if (data.receive_pairs != NULL) { rc_avpair_free(data.receive_pairs); data.receive_pairs = NULL; } rc_buildreq(rh, &data, request_type, aaaserver.name.c_str(), aaaserver.port, aaaserver.secret.c_str(), timeout, retries); if (request_type == PW_ACCOUNTING_REQUEST) { dtime = rc_getctime() - start_time; rc_avpair_assign(adt_vp, &dtime, 0); } fprintf(stdout, "rc_aaa::rc_send_server Start\n"); result = rc_send_server (rh, &data, msg); fprintf(stdout, "rc_aaa::rc_send_server End\n"); if (result != TIMEOUT_RC) aaaserver.deadtime_ends = -1; } exit: if (request_type != PW_ACCOUNTING_REQUEST) { *received = data.receive_pairs; } else { rc_avpair_free(data.receive_pairs); } printf("rc_aaa return: %d\n", result); return result; }
/** Builds an authentication/accounting request for port id client_port with the value_pairs send and submits it to a specified server. * This function keeps its state in ctx after a successful operation. It can be deallocated using * rc_aaa_ctx_free(). * * @param rh a handle to parsed configuration. * @param ctx if non-NULL it will contain the context of the request; Its initial value should be NULL and it must be released using rc_aaa_ctx_free(). * @param aaaserver a non-NULL SERVER to send the message to. * @param client_port the client port number to use (may be zero to use any available). * @param send a VALUE_PAIR array of values (e.g., PW_USER_NAME). * @param received an allocated array of received values. * @param msg must be an array of PW_MAX_MSG_SIZE or NULL; will contain the concatenation of any * PW_REPLY_MESSAGE received. * @param add_nas_port if non-zero it will include PW_NAS_PORT in sent pairs. * @param request_type one of standard RADIUS codes (e.g., PW_ACCESS_REQUEST). * @return received value_pairs in received, messages from the server in msg and OK_RC (0) on success, negative * on failure as return value. */ int rc_aaa_ctx_server(rc_handle *rh, RC_AAA_CTX **ctx, SERVER *aaaserver, rc_type type, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received, char *msg, int add_nas_port, rc_standard_codes request_type) { SEND_DATA data; VALUE_PAIR *adt_vp = NULL; int result; int timeout = rc_conf_int(rh, "radius_timeout"); int retries = rc_conf_int(rh, "radius_retries"); double start_time = 0; double now = 0; time_t dtime; int servernum; data.send_pairs = send; data.receive_pairs = NULL; /* * if there is more than zero servers, then divide waiting time * among all the servers. */ if(aaaserver->max > 0) { if(timeout > 0) { timeout = (timeout+1) / aaaserver->max; } if(retries > 0) { retries = (retries+1) / aaaserver->max; } } if (add_nas_port != 0 && rc_avpair_get(data.send_pairs, PW_NAS_PORT, 0) == NULL) { /* * Fill in NAS-Port */ if (rc_avpair_add(rh, &(data.send_pairs), PW_NAS_PORT, &client_port, 0, 0) == NULL) return ERROR_RC; } if (request_type == PW_ACCOUNTING_REQUEST) { /* * Fill in Acct-Delay-Time */ dtime = 0; now = rc_getctime(); adt_vp = rc_avpair_get(data.send_pairs, PW_ACCT_DELAY_TIME, 0); if (adt_vp == NULL) { adt_vp = rc_avpair_add(rh, &(data.send_pairs), PW_ACCT_DELAY_TIME, &dtime, 0, 0); if (adt_vp == NULL) return ERROR_RC; start_time = now; } else { start_time = now - adt_vp->lvalue; } } if (data.receive_pairs != NULL) { rc_avpair_free(data.receive_pairs); data.receive_pairs = NULL; } servernum=0; do { rc_buildreq(rh, &data, request_type, aaaserver->name[servernum], aaaserver->port[servernum], aaaserver->secret[servernum], timeout, retries); if (request_type == PW_ACCOUNTING_REQUEST) { dtime = rc_getctime() - start_time; rc_avpair_assign(adt_vp, &dtime, 0); } result = rc_send_server_ctx (rh, ctx, &data, msg, type); if (request_type != PW_ACCOUNTING_REQUEST) { *received = data.receive_pairs; } else { rc_avpair_free(data.receive_pairs); } if(result == OK_RC) { DEBUG(LOG_INFO, "servernum %u returned success", servernum); return result; } //rc_log(LOG_ERR, // "servernum %u returned error: %d", servernum, result); servernum++; } while(servernum < aaaserver->max && result == TIMEOUT_RC); return result; }