Client * client_new(Window win) { Client *c; long supplied; Atom win_type; XGetWindowAttributes(display, win, &attr); if (attr.override_redirect) return NULL; if (c = client_find(win)) return NULL; c = malloc(sizeof *c); c->next = head; head = c; c->win = win; c->name = ewmh_get_text(c, WM_NAME); c->geom.x = attr.x; c->geom.y = 16; c->geom.w = attr.width; c->geom.h = attr.height; XGetWMNormalHints(display, c->win, &c->size, &supplied); XGetTransientForHint(display, c->win, &c->trans); return c; }
/* * Xlat for %{getclient:<ipaddr>.foo} */ static ssize_t xlat_getclient(UNUSED void *instance, REQUEST *request, char const *fmt, char *out, size_t outlen) { char const *value = NULL; char buffer[INET6_ADDRSTRLEN], *q; char const *p = fmt; fr_ipaddr_t ip; CONF_PAIR *cp; RADCLIENT *client = NULL; if (!fmt || !out || (outlen < 1)) return 0; q = strrchr(p, '.'); if (!q || (q == p) || (((size_t)(q - p)) > sizeof(buffer))) { REDEBUG("Invalid client string"); goto error; } strlcpy(buffer, p, (q + 1) - p); memset(&ip, 0, sizeof(ip)); if (ip_ptonx(buffer, &ip) <= 0) { REDEBUG("\"%s\" is not a valid IPv4 or IPv6 address", buffer); goto error; } fmt = q + 1; client = client_find(NULL, &ip, IPPROTO_IP); if (!client) { RDEBUG("No client found with IP \"%s\"", buffer); *out = '\0'; return 0; } cp = cf_pair_find(client->cs, fmt); if (!cp || !(value = cf_pair_value(cp))) { if (strcmp(fmt, "shortname") == 0) { strlcpy(out, request->client->shortname, outlen); return strlen(out); } RDEBUG("Client does not contain config item \"%s\"", fmt); *out = '\0'; return 0; } strlcpy(out, value, outlen); return strlen(out); error: *out = '\0'; return -1; }
static const char *getsecret(uint32_t server) { RADCLIENT *cl; cl = client_find(server); if (cl == NULL) { char buf[32]; radlog(L_ERR|L_CONS, "No clients entry for %s", ip_ntoa(buf,server)); exit(1); } return (const char *)cl->secret; }
static void db_discovery_evt_handler(ble_db_discovery_evt_t * p_evt) { // Find the client using the connection handle. client_t * p_client; uint32_t index; bool is_valid_srv_found = false; index = client_find(p_evt->conn_handle); p_client = &m_client[index]; if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE) { uint8_t i; for (i = 0; i < p_evt->params.discovered_db.char_count; i++) { ble_db_discovery_char_t * p_characteristic; p_characteristic = &(p_evt->params.discovered_db.charateristics[i]); //See if this is the Ms. Pacman service if ((p_characteristic->characteristic.uuid.uuid == BLE_MS_PACMAN_CHARACTERISTIC_UUID) && (p_characteristic->characteristic.uuid.type == m_base_uuid_type_ms_pacman)) { // Characteristic found. Store the information needed and break. p_client->char_index = i; break; } //See if this is the Nunchuck service else if ((p_characteristic->characteristic.uuid.uuid == BLE_NUNCHUCK_CHARACTERISTIC_UUID) && (p_characteristic->characteristic.uuid.type == m_base_uuid_type_nunchuck)) { // Characteristic found. Store the information needed and break. p_client->char_index = i; is_valid_srv_found = true; break; } } } //Only enable notifications if it is the Nunchuck characteristic if (is_valid_srv_found) { // Enable notification. Maybe don't do this?? notif_enable(p_client); } }
/* * Xlat for %{client:[<ipaddr>.]foo} */ static ssize_t xlat_client(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen, UNUSED void const *mod_inst, UNUSED void const *xlat_inst, REQUEST *request, char const *fmt) { char const *value = NULL; char buffer[INET6_ADDRSTRLEN], *q; char const *p = fmt; fr_ipaddr_t ip; CONF_PAIR *cp; RADCLIENT *client = NULL; *out = NULL; q = strrchr(p, '.'); if (q) { strlcpy(buffer, p, (q + 1) - p); if (fr_inet_pton(&ip, buffer, -1, AF_UNSPEC, false, true) < 0) goto request_client; p = q + 1; client = client_find(NULL, &ip, IPPROTO_IP); if (!client) { RDEBUG("No client found with IP \"%s\"", buffer); return 0; } } else { request_client: client = request->client; if (!client) { RERROR("No client associated with this request"); return -1; } } cp = cf_pair_find(client->cs, p); if (!cp || !(value = cf_pair_value(cp))) { if (strcmp(fmt, "shortname") == 0 && request->client->shortname) { value = request->client->shortname; } else if (strcmp(fmt, "nas_type") == 0 && request->client->nas_type) { value = request->client->nas_type; } if (!value) return 0; } *out = talloc_typed_strdup(ctx, value); return talloc_array_length(*out) - 1; }
Code_t client_register(ZNotice_t *notice, struct in_addr *host, Client **client_p, int wantdefaults) { Client *client; /* chain the client's host onto this server's host list */ zdbug((LOG_DEBUG, "client_register: adding %s at %s/%d", notice->z_sender, inet_ntoa(*host), ntohs(notice->z_port))); if (!notice->z_port) return ZSRV_BADSUBPORT; *client_p = client = client_find(host, notice->z_port); if (!client) { *client_p = client = (Client *) malloc(sizeof(Client)); if (!client) return ENOMEM; memset(&client->addr, 0, sizeof(struct sockaddr_in)); #ifdef HAVE_KRB5 client->session_keyblock = NULL; #else #ifdef HAVE_KRB4 memset(&client->session_key, 0, sizeof(client->session_key)); #endif #endif client->last_send = 0; client->last_ack = NOW; client->addr.sin_family = AF_INET; client->addr.sin_addr.s_addr = host->s_addr; client->addr.sin_port = notice->z_port; client->subs = NULL; client->realm = NULL; client->principal = make_string(notice->z_sender, 0); Client_insert(&client_bucket[INET_HASH(&client->addr.sin_addr, notice->z_port)], client); } /* Add default subscriptions only if this is not resulting from a brain * dump, AND this request wants defaults. */ if (!bdumping && wantdefaults) return subscr_def_subs(client); else return ZERR_NONE; }
int duplicate(struct params *p, struct ieee80211_frame *wh, int rc) { struct client *c; int s; if (!frame_type(wh, IEEE80211_FC0_TYPE_DATA, IEEE80211_FC0_SUBTYPE_DATA)) return 0; s = seqno(wh); c = client_find(p, wh->i_addr2); if (!c) { c = malloc(sizeof(*c)); if (!c) err(1, "malloc()"); memset(c, 0, sizeof(*c)); memcpy(c->mac, wh->i_addr2, 6); c->seq = s-1; client_insert(p, c); } if (wh->i_fc[1] & IEEE80211_FC1_RETRY) { if ( (s <= c->seq) && ((c->seq - s ) < 5)) { #if 0 printf("Dup seq %d prev %d\n", s, c->seq); #endif return 1; } } #if 0 do { char mac[3*6]; mac2str(mac, c->mac); printf("%s seq %d prev %d\n", mac, s, c->seq); } while (0); #endif c->seq = s; return 0; }
static void db_discovery_evt_handler(ble_db_discovery_evt_t * p_evt) { // Find the client using the connection handle. client_t * p_client; uint32_t index; bool is_valid_srv_found = false; index = client_find(p_evt->conn_handle); p_client = &m_client[index]; if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE) { uint8_t i; for (i = 0; i < p_evt->params.discovered_db.char_count; i++) { ble_gatt_db_char_t * p_characteristic; p_characteristic = &(p_evt->params.discovered_db.charateristics[i]); if ((p_characteristic->characteristic.uuid.uuid == MULTILINK_PERIPHERAL_CHAR_UUID) && (p_characteristic->characteristic.uuid.type == m_base_uuid_type)) { // Characteristic found. Store the information needed and break. p_client->char_index = i; is_valid_srv_found = true; break; } } } if (is_valid_srv_found) { // Enable notification. notif_enable(p_client); } else { p_client->state = STATE_ERROR; } }
void workspace_client_moveto_bindable(XEvent *xevent, arglist *args) { unsigned int ws; client_t *client; client = client_find(event_window(xevent)); if (args != NULL && args->arglist_arg->type_type == INTEGER) { ws = args->arglist_arg->type_value.intval; } else { fprintf(stderr, "AHWM: type error\n"); /* can't happen */ return; } if (client == NULL) { fprintf(stderr, "AHWM: can't move client to workspace %d, can't find client\n", ws); return; } workspace_client_moveto(client, ws); }
void client_handling_ble_evt_handler(ble_evt_t * p_ble_evt) { client_t * p_client = NULL; uint32_t index = client_find(p_ble_evt->evt.gattc_evt.conn_handle); if (index != MAX_CLIENTS) { p_client = &m_client[index]; } switch (p_ble_evt->header.evt_id) { case BLE_GATTC_EVT_WRITE_RSP: if ((p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION) || (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION)) { uint32_t err_code = dm_security_setup_req(&p_client->handle); APP_ERROR_CHECK(err_code); } on_evt_write_rsp(p_ble_evt, p_client); break; case BLE_GATTC_EVT_HVX: on_evt_hvx(p_ble_evt, p_client, index); break; case BLE_GATTC_EVT_TIMEOUT: on_evt_timeout(p_ble_evt, p_client); break; default: break; } if (p_client != NULL) { ble_db_discovery_on_ble_evt(&(p_client->srv_db), p_ble_evt); } }
void screen_updatestackingorder(struct screen_ctx *sc) { Window *wins, w0, w1; struct client_ctx *cc; unsigned int nwins, i, s; if (!XQueryTree(X_Dpy, sc->rootwin, &w0, &w1, &wins, &nwins)) return; for (s = 0, i = 0; i < nwins; i++) { /* Skip hidden windows */ if ((cc = client_find(wins[i])) == NULL || cc->flags & CLIENT_HIDDEN) continue; cc->stackingorder = s++; } XFree(wins); }
/** Add a client to a RADCLIENT_LIST * * @param clients list to add client to, may be NULL if global client list is being used. * @param client to add. * @return true on success, false on failure. */ bool client_add(RADCLIENT_LIST *clients, RADCLIENT *client) { RADCLIENT *old; char buffer[INET6_ADDRSTRLEN + 3]; if (!client) return false; /* * Hack to fixup wildcard clients * * If the IP is all zeros, with a 32 or 128 bit netmask * assume the user meant to configure 0.0.0.0/0 instead * of 0.0.0.0/32 - which would require the src IP of * the client to be all zeros. */ if (fr_inaddr_any(&client->ipaddr) == 1) switch (client->ipaddr.af) { case AF_INET: if (client->ipaddr.prefix == 32) client->ipaddr.prefix = 0; break; case AF_INET6: if (client->ipaddr.prefix == 128) client->ipaddr.prefix = 0; break; default: rad_assert(0); } fr_ntop(buffer, sizeof(buffer), &client->ipaddr); DEBUG3("Adding client %s (%s) to prefix tree %i", buffer, client->longname, client->ipaddr.prefix); /* * If the client also defines a server, do that now. */ if (client->defines_coa_server) if (!realm_home_server_add(client->coa_server)) return false; /* * If "clients" is NULL, it means add to the global list, * unless we're trying to add it to a virtual server... */ if (!clients) { if (client->server != NULL) { CONF_SECTION *cs; cs = cf_section_sub_find_name2(main_config.config, "server", client->server); if (!cs) { ERROR("Failed to find virtual server %s", client->server); return false; } /* * If the client list already exists, use that. * Otherwise, create a new client list. */ clients = cf_data_find(cs, "clients"); if (!clients) { clients = client_list_init(cs); if (!clients) { ERROR("Out of memory"); return false; } if (cf_data_add(cs, "clients", clients, (void (*)(void *)) client_list_free) < 0) { ERROR("Failed to associate clients with virtual server %s", client->server); client_list_free(clients); return false; } } } else { /* * Initialize the global list, if not done already. */ if (!root_clients) { root_clients = client_list_init(NULL); if (!root_clients) return false; } clients = root_clients; } } /* * Create a tree for it. */ if (!clients->trees[client->ipaddr.prefix]) { clients->trees[client->ipaddr.prefix] = rbtree_create(clients, client_ipaddr_cmp, NULL, 0); if (!clients->trees[client->ipaddr.prefix]) { return false; } } #define namecmp(a) ((!old->a && !client->a) || (old->a && client->a && (strcmp(old->a, client->a) == 0))) /* * Cannot insert the same client twice. */ old = rbtree_finddata(clients->trees[client->ipaddr.prefix], client); if (old) { /* * If it's a complete duplicate, then free the new * one, and return "OK". */ if ((fr_ipaddr_cmp(&old->ipaddr, &client->ipaddr) == 0) && (old->ipaddr.prefix == client->ipaddr.prefix) && namecmp(longname) && namecmp(secret) && namecmp(shortname) && namecmp(nas_type) && namecmp(login) && namecmp(password) && namecmp(server) && #ifdef WITH_DYNAMIC_CLIENTS (old->lifetime == client->lifetime) && namecmp(client_server) && #endif #ifdef WITH_COA namecmp(coa_name) && (old->coa_server == client->coa_server) && (old->coa_pool == client->coa_pool) && #endif (old->message_authenticator == client->message_authenticator)) { WARN("Ignoring duplicate client %s", client->longname); client_free(client); return true; } ERROR("Failed to add duplicate client %s", client->shortname); return false; } #undef namecmp /* * Other error adding client: likely is fatal. */ if (!rbtree_insert(clients->trees[client->ipaddr.prefix], client)) { return false; } #ifdef WITH_STATS if (!tree_num) { tree_num = rbtree_create(clients, client_num_cmp, NULL, 0); } #ifdef WITH_DYNAMIC_CLIENTS /* * More catching of clients added by rlm_sql. * * The sql modules sets the dynamic flag BEFORE calling * us. The client_afrom_request() function sets it AFTER * calling us. */ if (client->dynamic && (client->lifetime == 0)) { RADCLIENT *network; /* * If there IS an enclosing network, * inherit the lifetime from it. */ network = client_find(clients, &client->ipaddr, client->proto); if (network) { client->lifetime = network->lifetime; } } #endif client->number = tree_num_max; tree_num_max++; if (tree_num) rbtree_insert(tree_num, client); #endif if (client->ipaddr.prefix < clients->min_prefix) { clients->min_prefix = client->ipaddr.prefix; } (void) talloc_steal(clients, client); /* reparent it */ return true; }
/* * Add a client to the tree. */ int client_add(RADCLIENT_LIST *clients, RADCLIENT *client) { RADCLIENT *old; char buffer[INET6_ADDRSTRLEN + 3]; if (!client) { return 0; } /* * Hack to fixup wildcard clients */ if (is_wildcard(&client->ipaddr)) client->ipaddr.prefix = 0; fr_ntop(buffer, sizeof(buffer), &client->ipaddr); DEBUG3("Adding client %s (%s) to prefix tree %i", buffer, client->longname, client->ipaddr.prefix); /* * If "clients" is NULL, it means add to the global list. */ if (!clients) { /* * Initialize it, if not done already. */ if (!root_clients) { root_clients = clients_init(NULL); if (!root_clients) return 0; } clients = root_clients; } /* * Create a tree for it. */ if (!clients->trees[client->ipaddr.prefix]) { clients->trees[client->ipaddr.prefix] = rbtree_create(client_ipaddr_cmp, NULL, 0); if (!clients->trees[client->ipaddr.prefix]) { return 0; } } #define namecmp(a) ((!old->a && !client->a) || (old->a && client->a && (strcmp(old->a, client->a) == 0))) /* * Cannot insert the same client twice. */ old = rbtree_finddata(clients->trees[client->ipaddr.prefix], client); if (old) { /* * If it's a complete duplicate, then free the new * one, and return "OK". */ if ((fr_ipaddr_cmp(&old->ipaddr, &client->ipaddr) == 0) && (old->ipaddr.prefix == client->ipaddr.prefix) && namecmp(longname) && namecmp(secret) && namecmp(shortname) && namecmp(nas_type) && namecmp(login) && namecmp(password) && namecmp(server) && #ifdef WITH_DYNAMIC_CLIENTS (old->lifetime == client->lifetime) && namecmp(client_server) && #endif #ifdef WITH_COA namecmp(coa_name) && (old->coa_server == client->coa_server) && (old->coa_pool == client->coa_pool) && #endif (old->message_authenticator == client->message_authenticator)) { WARN("Ignoring duplicate client %s", client->longname); client_free(client); return 1; } ERROR("Failed to add duplicate client %s", client->shortname); return 0; } #undef namecmp /* * Other error adding client: likely is fatal. */ if (!rbtree_insert(clients->trees[client->ipaddr.prefix], client)) { return 0; } #ifdef WITH_STATS if (!tree_num) { tree_num = rbtree_create(client_num_cmp, NULL, 0); } #ifdef WITH_DYNAMIC_CLIENTS /* * More catching of clients added by rlm_sql. * * The sql modules sets the dynamic flag BEFORE calling * us. The client_from_request() function sets it AFTER * calling us. */ if (client->dynamic && (client->lifetime == 0)) { RADCLIENT *network; /* * If there IS an enclosing network, * inherit the lifetime from it. */ network = client_find(clients, &client->ipaddr, client->proto); if (network) { client->lifetime = network->lifetime; } } #endif client->number = tree_num_max; tree_num_max++; if (tree_num) rbtree_insert(tree_num, client); #endif if (client->ipaddr.prefix < clients->min_prefix) { clients->min_prefix = client->ipaddr.prefix; } (void) talloc_steal(clients, client); /* reparent it */ return 1; }
static void request_stats_reply(REQUEST *request) { VALUE_PAIR *flag, *vp; /* * Statistics are available ONLY on a "status" port. */ rad_assert(request->packet->code == PW_STATUS_SERVER); rad_assert(request->listener->type == RAD_LISTEN_NONE); flag = pairfind(request->packet->vps, FR2ATTR(127)); if (!flag || (flag->vp_integer == 0)) return; /* * Authentication. */ if (((flag->vp_integer & 0x01) != 0) && ((flag->vp_integer & 0xc0) == 0)) { request_stats_addvp(request, authvp, &radius_auth_stats); } #ifdef WITH_ACCOUNTING /* * Accounting */ if (((flag->vp_integer & 0x02) != 0) && ((flag->vp_integer & 0xc0) == 0)) { request_stats_addvp(request, acctvp, &radius_acct_stats); } #endif #ifdef WITH_PROXY /* * Proxied authentication requests. */ if (((flag->vp_integer & 0x04) != 0) && ((flag->vp_integer & 0x20) == 0)) { request_stats_addvp(request, proxy_authvp, &proxy_auth_stats); } #ifdef WITH_ACCOUNTING /* * Proxied accounting requests. */ if (((flag->vp_integer & 0x08) != 0) && ((flag->vp_integer & 0x20) == 0)) { request_stats_addvp(request, proxy_acctvp, &proxy_acct_stats); } #endif #endif /* * Internal server statistics */ if ((flag->vp_integer & 0x10) != 0) { vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(176), PW_TYPE_DATE); if (vp) vp->vp_date = radius_start_time.tv_sec; vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(177), PW_TYPE_DATE); if (vp) vp->vp_date = radius_hup_time.tv_sec; #ifdef HAVE_PTHREAD_H int i, array[RAD_LISTEN_MAX]; thread_pool_queue_stats(array); for (i = 0; i <= RAD_LISTEN_DETAIL; i++) { vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(162 + i), PW_TYPE_INTEGER); if (!vp) continue; vp->vp_integer = array[i]; } #endif } /* * For a particular client. */ if ((flag->vp_integer & 0x20) != 0) { fr_ipaddr_t ipaddr; VALUE_PAIR *server_ip, *server_port = NULL; RADCLIENT *client = NULL; RADCLIENT_LIST *cl = NULL; /* * See if we need to look up the client by server * socket. */ server_ip = pairfind(request->packet->vps, FR2ATTR(170)); if (server_ip) { server_port = pairfind(request->packet->vps, FR2ATTR(171)); if (server_port) { ipaddr.af = AF_INET; ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr; cl = listener_find_client_list(&ipaddr, server_port->vp_integer); /* * Not found: don't do anything */ if (!cl) return; } } vp = pairfind(request->packet->vps, FR2ATTR(167)); if (vp) { ipaddr.af = AF_INET; ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; client = client_find(cl, &ipaddr); /* * Else look it up by number. */ } else if ((vp = pairfind(request->packet->vps, FR2ATTR(168))) != NULL) { client = client_findbynumber(cl, vp->vp_integer); } if (client) { /* * If found, echo it back, along with * the requested statistics. */ pairadd(&request->reply->vps, paircopyvp(vp)); /* * When retrieving client by number, also * echo back it's IP address. */ if ((vp->type == PW_TYPE_INTEGER) && (client->ipaddr.af == AF_INET)) { vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(167), PW_TYPE_IPADDR); if (vp) { vp->vp_ipaddr = client->ipaddr.ipaddr.ip4addr.s_addr; } if (client->prefix != 32) { vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(169), PW_TYPE_INTEGER); if (vp) { vp->vp_integer = client->prefix; } } } if (server_ip) { pairadd(&request->reply->vps, paircopyvp(server_ip)); pairadd(&request->reply->vps, paircopyvp(server_port)); } if (client->auth && ((flag->vp_integer & 0x01) != 0)) { request_stats_addvp(request, client_authvp, client->auth); } #ifdef WITH_ACCOUNTING if (client->acct && ((flag->vp_integer & 0x01) != 0)) { request_stats_addvp(request, client_acctvp, client->acct); } #endif } /* else client wasn't found, don't echo it back */ } /* * For a particular "listen" socket. */ if (((flag->vp_integer & 0x40) != 0) && ((flag->vp_integer & 0x03) != 0)) { rad_listen_t *this; VALUE_PAIR *server_ip, *server_port; fr_ipaddr_t ipaddr; /* * See if we need to look up the server by socket * socket. */ server_ip = pairfind(request->packet->vps, FR2ATTR(170)); if (!server_ip) return; server_port = pairfind(request->packet->vps, FR2ATTR(171)); if (!server_port) return; ipaddr.af = AF_INET; ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr; this = listener_find_byipaddr(&ipaddr, server_port->vp_integer); /* * Not found: don't do anything */ if (!this) return; pairadd(&request->reply->vps, paircopyvp(server_ip)); pairadd(&request->reply->vps, paircopyvp(server_port)); if (((flag->vp_integer & 0x01) != 0) && ((request->listener->type == RAD_LISTEN_AUTH) || (request->listener->type == RAD_LISTEN_NONE))) { request_stats_addvp(request, authvp, &this->stats); } #ifdef WITH_ACCOUNTING if (((flag->vp_integer & 0x02) != 0) && ((request->listener->type == RAD_LISTEN_ACCT) || (request->listener->type == RAD_LISTEN_NONE))) { request_stats_addvp(request, acctvp, &this->stats); } #endif } /* * Home servers. */ if (((flag->vp_integer & 0x80) != 0) && ((flag->vp_integer & 0x03) != 0)) { home_server *home; VALUE_PAIR *server_ip, *server_port; fr_ipaddr_t ipaddr; /* * See if we need to look up the server by socket * socket. */ server_ip = pairfind(request->packet->vps, FR2ATTR(170)); if (!server_ip) return; server_port = pairfind(request->packet->vps, FR2ATTR(171)); if (!server_port) return; ipaddr.af = AF_INET; ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr; home = home_server_find(&ipaddr, server_port->vp_integer); /* * Not found: don't do anything */ if (!home) return; pairadd(&request->reply->vps, paircopyvp(server_ip)); pairadd(&request->reply->vps, paircopyvp(server_port)); vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(172), PW_TYPE_INTEGER); if (vp) vp->vp_integer = home->currently_outstanding; vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(173), PW_TYPE_INTEGER); if (vp) vp->vp_integer = home->state; if ((home->state == HOME_STATE_ALIVE) && (home->revive_time.tv_sec != 0)) { vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(175), PW_TYPE_DATE); if (vp) vp->vp_date = home->revive_time.tv_sec; } if ((home->state == HOME_STATE_ALIVE) && (home->ema.window > 0)) { vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(178), PW_TYPE_INTEGER); if (vp) vp->vp_integer = home->ema.window; vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(179), PW_TYPE_INTEGER); if (vp) vp->vp_integer = home->ema.ema1 / EMA_SCALE; vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(180), PW_TYPE_INTEGER); if (vp) vp->vp_integer = home->ema.ema10 / EMA_SCALE; } if (home->state == HOME_STATE_IS_DEAD) { vp = radius_paircreate(request, &request->reply->vps, FR2ATTR(174), PW_TYPE_DATE); if (vp) vp->vp_date = home->zombie_period_start.tv_sec + home->zombie_period; } if (((flag->vp_integer & 0x01) != 0) && (home->type == HOME_TYPE_AUTH)) { request_stats_addvp(request, proxy_authvp, &home->stats); } #ifdef WITH_ACCOUNTING if (((flag->vp_integer & 0x02) != 0) && (home->type == HOME_TYPE_ACCT)) { request_stats_addvp(request, proxy_acctvp, &home->stats); } #endif } }
void request_stats_reply(REQUEST *request) { VALUE_PAIR *flag, *vp; /* * Statistics are available ONLY on a "status" port. */ rad_assert(request->packet->code == PW_CODE_STATUS_SERVER); rad_assert(request->listener->type == RAD_LISTEN_NONE); flag = pairfind(request->packet->vps, 127, VENDORPEC_FREERADIUS, TAG_ANY); if (!flag || (flag->vp_integer == 0)) return; /* * Authentication. */ if (((flag->vp_integer & 0x01) != 0) && ((flag->vp_integer & 0xc0) == 0)) { request_stats_addvp(request, authvp, &radius_auth_stats); } #ifdef WITH_ACCOUNTING /* * Accounting */ if (((flag->vp_integer & 0x02) != 0) && ((flag->vp_integer & 0xc0) == 0)) { request_stats_addvp(request, acctvp, &radius_acct_stats); } #endif #ifdef WITH_PROXY /* * Proxied authentication requests. */ if (((flag->vp_integer & 0x04) != 0) && ((flag->vp_integer & 0x20) == 0)) { request_stats_addvp(request, proxy_authvp, &proxy_auth_stats); } #ifdef WITH_ACCOUNTING /* * Proxied accounting requests. */ if (((flag->vp_integer & 0x08) != 0) && ((flag->vp_integer & 0x20) == 0)) { request_stats_addvp(request, proxy_acctvp, &proxy_acct_stats); } #endif #endif /* * Internal server statistics */ if ((flag->vp_integer & 0x10) != 0) { vp = radius_paircreate(request->reply, &request->reply->vps, 176, VENDORPEC_FREERADIUS); if (vp) vp->vp_date = start_time.tv_sec; vp = radius_paircreate(request->reply, &request->reply->vps, 177, VENDORPEC_FREERADIUS); if (vp) vp->vp_date = hup_time.tv_sec; #ifdef HAVE_PTHREAD_H int i, array[RAD_LISTEN_MAX], pps[2]; thread_pool_queue_stats(array, pps); for (i = 0; i <= 4; i++) { vp = radius_paircreate(request->reply, &request->reply->vps, 162 + i, VENDORPEC_FREERADIUS); if (!vp) continue; vp->vp_integer = array[i]; } for (i = 0; i < 2; i++) { vp = radius_paircreate(request->reply, &request->reply->vps, 181 + i, VENDORPEC_FREERADIUS); if (!vp) continue; vp->vp_integer = pps[i]; } #endif } /* * For a particular client. */ if ((flag->vp_integer & 0x20) != 0) { fr_ipaddr_t ipaddr; VALUE_PAIR *server_ip, *server_port = NULL; RADCLIENT *client = NULL; RADCLIENT_LIST *cl = NULL; /* * See if we need to look up the client by server * socket. */ server_ip = pairfind(request->packet->vps, 170, VENDORPEC_FREERADIUS, TAG_ANY); if (server_ip) { server_port = pairfind(request->packet->vps, 171, VENDORPEC_FREERADIUS, TAG_ANY); if (server_port) { ipaddr.af = AF_INET; ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr; cl = listener_find_client_list(&ipaddr, server_port->vp_integer, IPPROTO_UDP); /* * Not found: don't do anything */ if (!cl) return; } } vp = pairfind(request->packet->vps, 167, VENDORPEC_FREERADIUS, TAG_ANY); if (vp) { memset(&ipaddr, 0, sizeof(ipaddr)); ipaddr.af = AF_INET; ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; client = client_find(cl, &ipaddr, IPPROTO_UDP); #ifdef WITH_TCP if (!client) { client = client_find(cl, &ipaddr, IPPROTO_TCP); } #endif /* * Else look it up by number. */ } else if ((vp = pairfind(request->packet->vps, 168, VENDORPEC_FREERADIUS, TAG_ANY)) != NULL) { client = client_findbynumber(cl, vp->vp_integer); } if (client) { /* * If found, echo it back, along with * the requested statistics. */ pairadd(&request->reply->vps, paircopyvp(request->reply, vp)); /* * When retrieving client by number, also * echo back it's IP address. */ if ((vp->da->type == PW_TYPE_INTEGER) && (client->ipaddr.af == AF_INET)) { vp = radius_paircreate(request->reply, &request->reply->vps, 167, VENDORPEC_FREERADIUS); if (vp) { vp->vp_ipaddr = client->ipaddr.ipaddr.ip4addr.s_addr; } if (client->ipaddr.prefix != 32) { vp = radius_paircreate(request->reply, &request->reply->vps, 169, VENDORPEC_FREERADIUS); if (vp) { vp->vp_integer = client->ipaddr.prefix; } } } if (server_ip) { pairadd(&request->reply->vps, paircopyvp(request->reply, server_ip)); } if (server_port) { pairadd(&request->reply->vps, paircopyvp(request->reply, server_port)); } if ((flag->vp_integer & 0x01) != 0) { request_stats_addvp(request, client_authvp, &client->auth); } #ifdef WITH_ACCOUNTING if ((flag->vp_integer & 0x01) != 0) { request_stats_addvp(request, client_acctvp, &client->acct); } #endif } /* else client wasn't found, don't echo it back */ } /* * For a particular "listen" socket. */ if (((flag->vp_integer & 0x40) != 0) && ((flag->vp_integer & 0x03) != 0)) { rad_listen_t *this; VALUE_PAIR *server_ip, *server_port; fr_ipaddr_t ipaddr; /* * See if we need to look up the server by socket * socket. */ server_ip = pairfind(request->packet->vps, 170, VENDORPEC_FREERADIUS, TAG_ANY); if (!server_ip) return; server_port = pairfind(request->packet->vps, 171, VENDORPEC_FREERADIUS, TAG_ANY); if (!server_port) return; ipaddr.af = AF_INET; ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr; this = listener_find_byipaddr(&ipaddr, server_port->vp_integer, IPPROTO_UDP); /* * Not found: don't do anything */ if (!this) return; pairadd(&request->reply->vps, paircopyvp(request->reply, server_ip)); pairadd(&request->reply->vps, paircopyvp(request->reply, server_port)); if (((flag->vp_integer & 0x01) != 0) && ((request->listener->type == RAD_LISTEN_AUTH) || (request->listener->type == RAD_LISTEN_NONE))) { request_stats_addvp(request, authvp, &this->stats); } #ifdef WITH_ACCOUNTING if (((flag->vp_integer & 0x02) != 0) && ((request->listener->type == RAD_LISTEN_ACCT) || (request->listener->type == RAD_LISTEN_NONE))) { request_stats_addvp(request, acctvp, &this->stats); } #endif } #ifdef WITH_PROXY /* * Home servers. */ if (((flag->vp_integer & 0x80) != 0) && ((flag->vp_integer & 0x03) != 0)) { home_server_t *home; VALUE_PAIR *server_ip, *server_port; fr_ipaddr_t ipaddr; /* * See if we need to look up the server by socket * socket. */ server_ip = pairfind(request->packet->vps, 170, VENDORPEC_FREERADIUS, TAG_ANY); if (!server_ip) return; server_port = pairfind(request->packet->vps, 171, VENDORPEC_FREERADIUS, TAG_ANY); if (!server_port) return; #ifndef NDEBUG memset(&ipaddr, 0, sizeof(ipaddr)); #endif ipaddr.af = AF_INET; ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr; home = home_server_find(&ipaddr, server_port->vp_integer, IPPROTO_UDP); /* * Not found: don't do anything */ if (!home) return; pairadd(&request->reply->vps, paircopyvp(request->reply, server_ip)); pairadd(&request->reply->vps, paircopyvp(request->reply, server_port)); vp = radius_paircreate(request->reply, &request->reply->vps, 172, VENDORPEC_FREERADIUS); if (vp) vp->vp_integer = home->currently_outstanding; vp = radius_paircreate(request->reply, &request->reply->vps, 173, VENDORPEC_FREERADIUS); if (vp) vp->vp_integer = home->state; if ((home->state == HOME_STATE_ALIVE) && (home->revive_time.tv_sec != 0)) { vp = radius_paircreate(request->reply, &request->reply->vps, 175, VENDORPEC_FREERADIUS); if (vp) vp->vp_date = home->revive_time.tv_sec; } if ((home->state == HOME_STATE_ALIVE) && (home->ema.window > 0)) { vp = radius_paircreate(request->reply, &request->reply->vps, 178, VENDORPEC_FREERADIUS); if (vp) vp->vp_integer = home->ema.window; vp = radius_paircreate(request->reply, &request->reply->vps, 179, VENDORPEC_FREERADIUS); if (vp) vp->vp_integer = home->ema.ema1 / EMA_SCALE; vp = radius_paircreate(request->reply, &request->reply->vps, 180, VENDORPEC_FREERADIUS); if (vp) vp->vp_integer = home->ema.ema10 / EMA_SCALE; } if (home->state == HOME_STATE_IS_DEAD) { vp = radius_paircreate(request->reply, &request->reply->vps, 174, VENDORPEC_FREERADIUS); if (vp) vp->vp_date = home->zombie_period_start.tv_sec + home->zombie_period; } /* * Show more information... * * FIXME: do this for clients, too! */ vp = radius_paircreate(request->reply, &request->reply->vps, 184, VENDORPEC_FREERADIUS); if (vp) vp->vp_date = home->last_packet_recv; vp = radius_paircreate(request->reply, &request->reply->vps, 185, VENDORPEC_FREERADIUS); if (vp) vp->vp_date = home->last_packet_sent; if (((flag->vp_integer & 0x01) != 0) && (home->type == HOME_TYPE_AUTH)) { request_stats_addvp(request, proxy_authvp, &home->stats); } #ifdef WITH_ACCOUNTING if (((flag->vp_integer & 0x02) != 0) && (home->type == HOME_TYPE_ACCT)) { request_stats_addvp(request, proxy_acctvp, &home->stats); } #endif } #endif /* WITH_PROXY */ }
/* * Find a per-socket client. */ RADCLIENT *client_listener_find(const rad_listen_t *listener, const fr_ipaddr_t *ipaddr, int src_port) { #ifdef WITH_DYNAMIC_CLIENTS int rcode; REQUEST *request; RADCLIENT *created; #endif time_t now; RADCLIENT *client; RADCLIENT_LIST *clients; listen_socket_t *sock; rad_assert(listener != NULL); rad_assert(ipaddr != NULL); sock = listener->data; clients = sock->clients; /* * This HAS to have been initialized previously. */ rad_assert(clients != NULL); client = client_find(clients, ipaddr,sock->proto); if (!client) { char name[256], buffer[128]; #ifdef WITH_DYNAMIC_CLIENTS unknown: /* used only for dynamic clients */ #endif /* * DoS attack quenching, but only in daemon mode. * If they're running in debug mode, show them * every packet. */ if (debug_flag == 0) { static time_t last_printed = 0; now = time(NULL); if (last_printed == now) return NULL; last_printed = now; } listener->print(listener, name, sizeof(name)); radlog(L_ERR, "Ignoring request to %s from unknown client %s port %d" #ifdef WITH_TCP " proto %s" #endif , name, inet_ntop(ipaddr->af, &ipaddr->ipaddr, buffer, sizeof(buffer)), src_port #ifdef WITH_TCP , (sock->proto == IPPROTO_UDP) ? "udp" : "tcp" #endif ); return NULL; } #ifndef WITH_DYNAMIC_CLIENTS return client; /* return the found client. */ #else /* * No server defined, and it's not dynamic. Return it. */ if (!client->client_server && !client->dynamic) return client; now = time(NULL); /* * It's a dynamically generated client, check it. */ if (client->dynamic && (src_port != 0)) { /* * Lives forever. Return it. */ if (client->lifetime == 0) return client; /* * Rate-limit the deletion of known clients. * This makes them last a little longer, but * prevents the server from melting down if (say) * 10k clients all expire at once. */ if (now == client->last_new_client) return client; /* * It's not dead yet. Return it. */ if ((client->created + client->lifetime) > now) return client; /* * This really puts them onto a queue for later * deletion. */ client_delete(clients, client); /* * Go find the enclosing network again. */ client = client_find(clients, ipaddr, sock->proto); /* * WTF? */ if (!client) goto unknown; if (!client->client_server) goto unknown; /* * At this point, 'client' is the enclosing * network that configures where dynamic clients * can be defined. */ rad_assert(client->dynamic == 0); } else { /* * The IP is unknown, so we've found an enclosing * network. Enable DoS protection. We only * allow one new client per second. Known * clients aren't subject to this restriction. */ if (now == client->last_new_client) goto unknown; } client->last_new_client = now; request = request_alloc(); if (!request) goto unknown; request->listener = listener; request->client = client; request->packet = rad_recv(listener->fd, 0x02); /* MSG_PEEK */ if (!request->packet) { /* badly formed, etc */ request_free(&request); goto unknown; } request->reply = rad_alloc_reply(request->packet); if (!request->reply) { request_free(&request); goto unknown; } request->packet->timestamp = request->timestamp; request->number = 0; request->priority = listener->type; request->server = client->client_server; request->root = &mainconfig; /* * Run a fake request through the given virtual server. * Look for FreeRADIUS-Client-IP-Address * FreeRADIUS-Client-Secret * ... * * and create the RADCLIENT structure from that. */ DEBUG("server %s {", request->server); rcode = module_authorize(0, request); DEBUG("} # server %s", request->server); if (rcode != RLM_MODULE_OK) { request_free(&request); goto unknown; } /* * If the client was updated by rlm_dynamic_clients, * don't create the client from attribute-value pairs. */ if (request->client == client) { created = client_create(clients, request); } else { created = request->client; /* * This frees the client if it isn't valid. */ if (!client_validate(clients, client, created)) goto unknown; } request_free(&request); if (!created) goto unknown; return created; #endif }
/** Map multiple attributes from a client into the request * * @param[in] mod_inst NULL. * @param[in] proc_inst NULL. * @param[in] request The current request. * @param[in] client_override If NULL, use the current client, else use the client matching * the ip given. * @param[in] maps Head of the map list. * @return * - #RLM_MODULE_NOOP no rows were returned. * - #RLM_MODULE_UPDATED if one or more #VALUE_PAIR were added to the #REQUEST. * - #RLM_MODULE_FAIL if an error occurred. */ static rlm_rcode_t map_proc_client(UNUSED void *mod_inst, UNUSED void *proc_inst, REQUEST *request, fr_value_box_t **client_override, vp_map_t const *maps) { rlm_rcode_t rcode = RLM_MODULE_OK; vp_map_t const *map; RADCLIENT *client; client_get_vp_ctx_t uctx; if (*client_override) { fr_ipaddr_t ip; char const *client_str; /* * Concat don't asprint, as this becomes a noop * in the vast majority of cases. */ if (fr_value_box_list_concat(request, *client_override, client_override, FR_TYPE_STRING, true) < 0) { REDEBUG("Failed concatenating input data"); return RLM_MODULE_FAIL; } client_str = (*client_override)->vb_strvalue; if (fr_inet_pton(&ip, client_str, -1, AF_UNSPEC, false, true) < 0) { REDEBUG("\"%s\" is not a valid IPv4 or IPv6 address", client_str); rcode = RLM_MODULE_FAIL; goto finish; } client = client_find(NULL, &ip, IPPROTO_IP); if (!client) { RDEBUG("No client found with IP \"%s\"", client_str); rcode = RLM_MODULE_NOTFOUND; goto finish; } if (client->cs) { char const *filename; int line; filename = cf_filename(client->cs); line = cf_lineno(client->cs); if (filename) { RDEBUG2("Found client matching \"%s\". Defined in \"%s\" line %i", client_str, filename, line); } else { RDEBUG2("Found client matching \"%s\"", client_str); } } } else { client = request->client; } uctx.cs = client->cs; RINDENT(); for (map = maps; map != NULL; map = map->next) { char *field = NULL; if (tmpl_aexpand(request, &field, request, map->rhs, NULL, NULL) < 0) { REDEBUG("Failed expanding RHS at %s", map->lhs->name); rcode = RLM_MODULE_FAIL; talloc_free(field); break; } uctx.cp = cf_pair_find(client->cs, field); if (!uctx.cp) { RDEBUG3("No matching client property \"%s\", skipping...", field); goto next; /* No matching CONF_PAIR found */ } uctx.field = field; /* * Pass the raw data to the callback, which will * create the VP and add it to the map. */ if (map_to_request(request, map, _map_proc_client_get_vp, &uctx) < 0) { rcode = RLM_MODULE_FAIL; talloc_free(field); break; } rcode = RLM_MODULE_UPDATED; next: talloc_free(field); } REXDENT(); finish: return rcode; }
/* * Old wrapper for client_find */ RADCLIENT *client_find_old(fr_ipaddr_t const *ipaddr) { return client_find(root_clients, ipaddr, IPPROTO_UDP); }