static BOOL __stdcall CryptSetHashParam_done(BOOL retval, HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD dwFlags) { DWORD err = GetLastError(); int ret_addr = *((DWORD *) ((DWORD) &retval - 4)); if (retval && !called_internally(ret_addr)) { HashMap::iterator iter; LOCK(); iter = hash_map.find(hHash); if (iter != hash_map.end()) { HashContext *ctx = iter->second; const TCHAR *param_str; HMAC_INFO *hmi; ByteBuffer *buf = NULL; const char *data = NULL; int data_len = 0; switch (dwParam) { case HP_HMAC_INFO: param_str = _T("HMAC_INFO"); hmi = (HMAC_INFO *) pbData; buf = byte_buffer_sized_new(4 + 4 + hmi->cbInnerString + 4 + hmi->cbOuterString); byte_buffer_append(buf, &hmi->HashAlgid, sizeof(ALG_ID)); byte_buffer_append(buf, &hmi->cbInnerString, sizeof(DWORD)); byte_buffer_append(buf, hmi->pbInnerString, hmi->cbInnerString); byte_buffer_append(buf, &hmi->cbOuterString, sizeof(DWORD)); byte_buffer_append(buf, hmi->pbOuterString, hmi->cbOuterString); data = (const char *) buf->buf; data_len = (int) buf->offset; break; case HP_HASHVAL: param_str = _T("HASHVAL"); break; default: param_str = _T("UNKNOWN"); break; } message_logger_log(_T("CryptSetHashParam"), (char *) &retval - 4, ctx->get_id(), MESSAGE_TYPE_PACKET, MESSAGE_CTX_INFO, PACKET_DIRECTION_INVALID, NULL, NULL, data, data_len, _T("hHash=0x%p, Algid=%s, dwParam=%s"), hHash, ctx->get_alg_id_as_string(), param_str); if (buf != NULL) byte_buffer_free(buf); } UNLOCK(); } SetLastError(err); return retval; }
static void do_client_state_machine(const apr_pollfd_t *s, apr_pollset_t *pollset) { struct per_client *c = s->client_data; apr_socket_t *client = s->desc.s; per_client_state old_state = c->state, new_state; apr_int16_t old_reqevents = s->reqevents, new_reqevents; apr_int16_t send_reqevents = APR_POLLOUT | APR_POLLHUP | APR_POLLERR; apr_int16_t recv_reqevents = APR_POLLIN | APR_POLLHUP | APR_POLLERR; byte_buffer *q = &c->query; switch (old_state) { case LM_S_INIT_CLIENT: { DEBUG("LM_S_INIT_CLIENT\n"); new_state = LM_S_SEND_HI; new_reqevents = send_reqevents; c->bytes_sent = 0; byte_buffer_init(&c->query); byte_buffer_init(&c->reply); break; } case LM_S_SEND_HI: { DEBUG("LM_S_SEND_HI\n"); apr_size_t send_sz = (sizeof LM_SERVER_HI) - c->bytes_sent; apr_status_t send_err; send_err = apr_socket_send(client, LM_SERVER_HI, &send_sz); if (send_err && !(APR_STATUS_IS_EAGAIN(send_err))) { APR_FAIL(send_err); new_state = LM_S_CLOSING; break; } c->bytes_sent += send_sz; if (c->bytes_sent == (sizeof LM_SERVER_HI)) { new_state = LM_S_GET_QUERY; new_reqevents = recv_reqevents; } else { new_state = LM_S_SEND_HI; new_reqevents = send_reqevents; } break; } case LM_S_GET_QUERY: { DEBUG("LM_S_GET_QUERY\n"); apr_status_t recv_err; size_t bigger = q->used + 64; if (q->size < bigger) { if (byte_buffer_grow_to(&c->query, bigger)) { FAIL("can't grow receive buffer\n"); new_state = LM_S_CLOSING; break; } } char *put_bytes_here = q->buf + q->used; apr_size_t bytes_read = q->size - q->used; DEBUG("put_bytes_here = %p\n", put_bytes_here); recv_err = apr_socket_recv(client, put_bytes_here, &bytes_read); DEBUG("recv %zu bytes, %d.\n", bytes_read, recv_err); if ((bytes_read == 0) || (APR_STATUS_IS_EOF(recv_err))) { if (q->used == 0) { DEBUG("clean disconnect :)\n"); } else { DEBUG("dirty disconnect :| (%zd)\n", q->used); } new_state = LM_S_CLOSING; break; } if (recv_err) { APR_FAIL(recv_err); new_state = LM_S_CLOSING; break; } q->used += bytes_read; char *null_here; do_you_want_to_try_a_query: null_here = memchr(q->buf, '\x00', q->used); if (null_here) { new_state = LM_S_SEND_REPLY; new_reqevents = send_reqevents; bytes query_bytes; query_bytes.start = c->query.buf; query_bytes.end = null_here; if (do_client_query(c->lmdb, query_bytes, &c->reply)) { new_state = LM_S_CLOSING; break; } /* How many bytes of the buffered input did that */ /* query occupy? Copy any leftovers back up to */ /* the beginning of the 'query' buffer. */ size_t q_consumed = 1 + null_here - c->query.buf; q->used -= q_consumed; if (q->used) { memcpy(q->buf, 1 + null_here, q->used); } c->bytes_sent = 0; if (c->reply.used == 0) { goto do_you_want_to_try_a_query; } } else { new_state = LM_S_GET_QUERY; new_reqevents = recv_reqevents; } break; } case LM_S_SEND_REPLY: { DEBUG("LM_S_SEND_REPLY\n"); apr_size_t nbytes = c->reply.used - c->bytes_sent; char *bytes = c->reply.buf + c->bytes_sent; apr_status_t send_err = apr_socket_send(client, bytes, &nbytes); if (send_err && !(APR_STATUS_IS_EAGAIN(send_err))) { APR_FAIL(send_err); new_state = LM_S_CLOSING; break; } c->bytes_sent += nbytes; if (c->bytes_sent == c->reply.used) { goto do_you_want_to_try_a_query; } else { new_state = LM_S_SEND_REPLY; new_reqevents = send_reqevents; } break; } default: { FAIL("Invalid client state.\n"); abort(); break; } } if (new_state == LM_S_CLOSING) { apr_pollset_remove(pollset, s); apr_socket_close(s->desc.s); byte_buffer_free(&c->query); byte_buffer_free(&c->reply); } else if (old_reqevents != new_reqevents) { apr_pollfd_t s1; memset(&s1, 0, sizeof s1); s1.p = s->p; s1.client_data = s->client_data; s1.desc_type = s->desc_type; s1.desc.s = s->desc.s; s1.reqevents = new_reqevents; apr_pollset_remove(pollset, s); apr_pollset_add(pollset, &s1); } c->state = new_state; }