static rb_node_t *tac_script_lookup_exec_context(tac_session * session, char *username, char *portname) { struct shellctx sc; if (!session->ctx->shellctxcache) return NULL; sc.username = username; sc.portname = portname; memcpy(&sc.nas_address, &session->ctx->nas_address, sizeof(struct in6_addr)); return RB_search(session->ctx->shellctxcache, &sc); }
static void mavis_io(struct context *ctx) { av_ctx *avc = NULL; struct query *q; rb_node_t *r; char *serial; Debug((DEBUG_PROC, "mavis_io %p\n", ctx)); switch (mavis_recv(mcx, &avc, ctx)) { case MAVIS_FINAL: break; case MAVIS_TIMEOUT: counter_expired++, counter_p_expired++; default: return; } if (!(serial = av_get(avc, AV_A_SERIAL))) return; q = alloca(sizeof(struct query)); q->serial = serial; q->serial_crc = crc32_update(INITCRC32, (u_char *) serial, strlen(serial)); if (!(r = RB_search(deferred_by_serial, q))) return; q = RB_payload(r, struct query *); /* XXX -- move the unset functionality to a separate module? */ if (!transmit_password) { av_unset(avc, AV_A_PASSWORD); av_unset(avc, AV_A_DBPASSWORD); } ctx = io_get_ctx(io, q->fd); /* Send answer to client */ av_send(avc, q->fd, &q->sa, ctx->blowfish); /* Remove query from deferred queue */ RB_delete(deferred_by_serial, r); backlog--; setproctitle("%s: backlog: %d", common_data.progname, backlog); counter_answered++, counter_p_answered++; return; } /* if */
void client_io(struct context *ctx, int cur) { /* We have incoming data. */ char *serial; int res; ssize_t buflen; sockaddr_union sa; socklen_t sinlen = (socklen_t) sizeof(sockaddr_union); char *avt; char buf[BUFSIZE_MAVIS]; av_ctx *avc; static struct query *q = NULL; if (!q) q = Xcalloc(1, sizeof(struct query)); Debug((DEBUG_PROC, "client_io\n")); /* Receive request from client */ buflen = recvfrom(cur, buf, sizeof(buf) - 1, 0, &sa.sa, &sinlen); if (buflen <= 0) return; buf[buflen] = 0; /* Decode data, if neccessary */ if (ctx->blowfish) blowfish_dec(ctx->blowfish, (a_char *) buf, buflen); /* Check client IP address */ res = acl_check(&sa); if (!res) { char ibuf[INET6_ADDRSTRLEN]; logmsg("Ignoring query from %s", su_ntop(&sa, ibuf, (socklen_t) sizeof(ibuf))); return; } counter_query++, counter_p_query++; avc = av_new(NULL, NULL); av_char_to_array(avc, buf, NULL); serial = av_get(avc, AV_A_SERIAL); if (!serial) { char ibuf[INET6_ADDRSTRLEN]; logmsg("query from %s lacks serial", su_ntop(&sa, ibuf, (socklen_t) sizeof(ibuf))); counter_err++, counter_p_err++; av_free(avc); return; } q->serial = serial; q->serial_crc = crc32_update(INITCRC32, (u_char *) serial, strlen(serial)); if (RB_search(deferred_by_serial, q)) { char ibuf[INET6_ADDRSTRLEN]; Debug((DEBUG_PROC, "Duplicate detected\n")); logmsg("Ignoring duplicate query from %s (backlog: %d)", su_ntop(&sa, ibuf, (socklen_t) sizeof(ibuf)), backlog); counter_retry++, counter_p_retry++; av_free(avc); return; } if (av_get(avc, AV_A_RESULT)) { char ibuf[INET6_ADDRSTRLEN]; Debug((DEBUG_PROC, "AV_A_RESULT already set. Spoofing?\n")); logmsg("Ignoring query with pre-set result code " "from %s (backlog: %d)", su_ntop(&sa, ibuf, (socklen_t) sizeof(ibuf)), backlog); counter_err++, counter_p_err++; av_free(avc); return; } avt = av_get(avc, AV_A_TYPE); if (!avt || !strncmp(avt, AV_V_TYPE_PRIVATE_PREFIX, AV_V_TYPE_PRIVATE_PREFIX_LEN)) { counter_err++, counter_p_err++; av_free(avc); return; } av_setcb(avc, (void *) mavis_io, (void *) q); switch (mavis_send(mcx, &avc)) { case MAVIS_DEFERRED: Debug((DEBUG_PROC, "mavis_send yields DEFERRED\n")); q->sa = sa; q->fd = cur; q->serial = Xstrdup(serial); RB_insert(deferred_by_serial, q); q = NULL; backlog++; if (backlog > backlog_max) backlog_max = backlog; if (backlog > backlog_max_p) backlog_max_p = backlog; setproctitle("%s: backlog: %d", common_data.progname, backlog); return; case MAVIS_TIMEOUT: counter_expired++, counter_p_expired++; break; case MAVIS_FINAL: if (!transmit_password) { av_unset(avc, AV_A_PASSWORD); av_unset(avc, AV_A_DBPASSWORD); } av_send(avc, cur, &sa, ctx->blowfish); counter_answered++, counter_p_answered++; } av_free(avc); }