/* * Blowfish-ECB block encryption/decryption */ int mbedtls_blowfish_crypt_ecb(mbedtls_blowfish_context *ctx, int mode, const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE], unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE]) { uint32_t X0, X1; GET_UINT32_BE(X0, input, 0); GET_UINT32_BE(X1, input, 4); if (mode == MBEDTLS_BLOWFISH_DECRYPT) { blowfish_dec(ctx, &X0, &X1); } else { /* MBEDTLS_BLOWFISH_ENCRYPT */ blowfish_enc(ctx, &X0, &X1); } PUT_UINT32_BE(X0, output, 0); PUT_UINT32_BE(X1, output, 4); return (0); }
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); }