auth-worker-client.c revision 82f53ea81671bcc7b9bf24a34b04a4ba2752efd3
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen/* Copyright (C) 2005 Timo Sirainen */
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen/* If no requests have come within this time, kill ourself */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenauth_worker_client_check_throttle(struct auth_worker_client *client)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (o_stream_get_buffer_used_size(client->output) >=
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* stop reading new requests until client has read the pending
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenworker_auth_request_new(struct auth_worker_client *client, unsigned int id,
9398c0935613ba038cf2275ff66c43b25092cfd0Timo Sirainen auth_request = auth_request_new_dummy(client->auth);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen for (tmp = t_strsplit(args, "\t"); *tmp != NULL; tmp++) {
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen (void)auth_request_import(auth_request, key, value);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstatic void verify_plain_callback(enum passdb_result result,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct auth_worker_client *client = request->context;
72bb770023dd5c2eb4e0b56a79203233548b2aefTimo Sirainen /* we're proxying - send back the password that was
72bb770023dd5c2eb4e0b56a79203233548b2aefTimo Sirainen sent by user (not the password in passdb). */
72bb770023dd5c2eb4e0b56a79203233548b2aefTimo Sirainen str_printfa(str, "pass=%s\t", request->mech_password);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen o_stream_send(client->output, str_data(str), str_len(str));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenauth_worker_handle_passv(struct auth_worker_client *client,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* verify plaintext password */
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen unsigned int num;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen i_error("BUG: Auth worker server sent us invalid PASSV");
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen auth_request = worker_auth_request_new(client, id, args);
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen if (auth_request->user == NULL || auth_request->service == NULL) {
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen auth_request->passdb = auth_request->passdb->next;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen auth_request->passdb->passdb->verify_plain(auth_request, password,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenlookup_credentials_callback(enum passdb_result result, const char *credentials,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct auth_worker_client *client = request->context;
3d370bb6763ac4af4a0d143ad7c93300d5ddff89Timo Sirainen str_printfa(str, "OK\t%s\t{%s}%s\t", request->user,
0af3274706d337b2930bd34f0377f2cc2dbcd18aTimo Sirainen passdb_credentials_to_str(request->credentials),
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen o_stream_send(client->output, str_data(str), str_len(str));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenauth_worker_handle_passl(struct auth_worker_client *client,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* lookup credentials */
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen unsigned int num;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen i_error("BUG: Auth worker server sent us invalid PASSL");
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen auth_request = worker_auth_request_new(client, id, args);
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen if (auth_request->user == NULL || auth_request->service == NULL) {
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen auth_request->passdb = auth_request->passdb->next;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenlookup_user_callback(const char *result, struct auth_request *auth_request)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct auth_worker_client *client = auth_request->context;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen o_stream_send(client->output, str_data(str), str_len(str));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenauth_worker_handle_user(struct auth_worker_client *client,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* lookup user */
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen unsigned int num;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen auth_request = worker_auth_request_new(client, id, args);
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen if (auth_request->user == NULL || auth_request->service == NULL) {
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen auth_request->userdb = auth_request->userdb->next;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenauth_worker_handle_line(struct auth_worker_client *client, const char *line)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen const char *p;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen unsigned int id;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen id = (unsigned int)strtoul(t_strdup_until(line, p), NULL, 10);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen auth_worker_handle_passv(client, id, line + 6);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen auth_worker_handle_passl(client, id, line + 6);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen auth_worker_handle_user(client, id, line + 5);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* disconnected */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* buffer full */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen i_error("BUG: Auth worker server sent us more than %d bytes",
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen while ((line = i_stream_next_line(client->input)) != NULL) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (o_stream_get_buffer_used_size(client->output) <=
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen OUTBUF_THROTTLE_SIZE/3 && client->io == NULL) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* allow input again */
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainenstatic void auth_worker_client_timeout(void *context)
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen if (client->last_request + AUTH_WORKER_MAX_IDLE <= ioloop_time)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenauth_worker_client_create(struct auth *auth, int fd)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen o_stream_create_file(fd, default_pool, (size_t)-1, FALSE);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen o_stream_set_flush_callback(client->output, auth_worker_output, client);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen client->io = io_add(fd, IO_READ, auth_worker_input, client);
c1ebcdad1b4d950eb22219704dd9d64a89d0568fTimo Sirainen client->to = timeout_add(1000*60, auth_worker_client_timeout, client);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenvoid auth_worker_client_destroy(struct auth_worker_client *client)