auth-client-request.c revision e59faf65ce864fe95dc00f5d52b8323cdbd0608a
565N/A/* Copyright (c) 2003-2010 Dovecot authors, see the included COPYING file */
565N/A
565N/A#include "lib.h"
565N/A#include "str.h"
565N/A#include "strescape.h"
565N/A#include "ostream.h"
565N/A#include "auth-client-private.h"
565N/A#include "auth-server-connection.h"
565N/A#include "auth-client-request.h"
565N/A
565N/A#include <stdlib.h>
565N/A
565N/Astruct auth_client_request {
565N/A pool_t pool;
565N/A
565N/A struct auth_server_connection *conn;
565N/A unsigned int id;
565N/A
565N/A struct auth_request_info request_info;
565N/A
565N/A auth_request_callback_t *callback;
926N/A void *context;
926N/A};
835N/A
565N/Astatic void auth_server_send_new_request(struct auth_server_connection *conn,
926N/A struct auth_client_request *request)
565N/A{
1051N/A struct auth_request_info *info = &request->request_info;
1050N/A string_t *str;
941N/A
941N/A str = t_str_new(512);
926N/A str_printfa(str, "AUTH\t%u\t", request->id);
926N/A str_tabescape_write(str, info->mech);
926N/A str_append(str, "\tservice=");
926N/A str_tabescape_write(str, info->service);
926N/A
838N/A if ((info->flags & AUTH_REQUEST_FLAG_SECURED) != 0)
565N/A str_append(str, "\tsecured");
565N/A if ((info->flags & AUTH_REQUEST_FLAG_VALID_CLIENT_CERT) != 0)
565N/A str_append(str, "\tvalid-client-cert");
565N/A
565N/A if (info->cert_username != NULL) {
565N/A str_append(str, "\tcert_username=");
565N/A str_tabescape_write(str, info->cert_username);
565N/A }
565N/A if (info->local_ip.family != 0)
565N/A str_printfa(str, "\tlip=%s", net_ip2addr(&info->local_ip));
565N/A if (info->remote_ip.family != 0)
565N/A str_printfa(str, "\trip=%s", net_ip2addr(&info->remote_ip));
565N/A if (info->local_port != 0)
565N/A str_printfa(str, "\tlport=%u", info->local_port);
565N/A if (info->remote_port != 0)
565N/A str_printfa(str, "\trport=%u", info->remote_port);
565N/A if (info->initial_resp_base64 != NULL) {
565N/A str_append(str, "\tresp=");
565N/A str_tabescape_write(str, info->initial_resp_base64);
565N/A }
565N/A str_append_c(str, '\n');
565N/A
565N/A if (o_stream_send(conn->output, str_data(str), str_len(str)) < 0)
565N/A i_error("Error sending request to auth server: %m");
565N/A}
565N/A
565N/Astruct auth_client_request *
565N/Aauth_client_request_new(struct auth_client *client,
565N/A const struct auth_request_info *request_info,
565N/A auth_request_callback_t *callback, void *context)
1019N/A{
1019N/A struct auth_client_request *request;
1019N/A pool_t pool;
1019N/A
1019N/A pool = pool_alloconly_create("auth client request", 512);
1019N/A request = p_new(pool, struct auth_client_request, 1);
1019N/A request->pool = pool;
1019N/A request->conn = client->conn;
565N/A
565N/A request->request_info = *request_info;
565N/A request->request_info.mech = p_strdup(pool, request_info->mech);
565N/A request->request_info.service = p_strdup(pool, request_info->service);
565N/A request->request_info.cert_username =
565N/A p_strdup(pool, request_info->cert_username);
565N/A request->request_info.initial_resp_base64 =
565N/A p_strdup(pool, request_info->initial_resp_base64);
565N/A
565N/A request->callback = callback;
565N/A request->context = context;
565N/A
565N/A request->id =
565N/A auth_server_connection_add_request(request->conn, request);
565N/A T_BEGIN {
565N/A auth_server_send_new_request(request->conn, request);
565N/A } T_END;
565N/A return request;
565N/A}
565N/A
565N/Avoid auth_client_request_continue(struct auth_client_request *request,
565N/A const char *data_base64)
565N/A{
565N/A struct const_iovec iov[3];
565N/A const char *prefix;
565N/A
565N/A prefix = t_strdup_printf("CONT\t%u\t", request->id);
565N/A
565N/A iov[0].iov_base = prefix;
685N/A iov[0].iov_len = strlen(prefix);
685N/A iov[1].iov_base = data_base64;
685N/A iov[1].iov_len = strlen(data_base64);
685N/A iov[2].iov_base = "\n";
685N/A iov[2].iov_len = 1;
685N/A
685N/A if (o_stream_sendv(request->conn->output, iov, 3) < 0)
926N/A i_error("Error sending continue request to auth server: %m");
926N/A}
926N/A
926N/Avoid auth_client_request_abort(struct auth_client_request **_request)
685N/A{
685N/A struct auth_client_request *request = *_request;
685N/A
926N/A *_request = NULL;
685N/A
685N/A request->callback(request, AUTH_REQUEST_STATUS_FAIL, NULL, NULL,
879N/A request->context);
879N/A request->callback = NULL;
879N/A}
879N/A
879N/Aunsigned int auth_client_request_get_id(struct auth_client_request *request)
879N/A{
879N/A return request->id;
879N/A}
879N/A
879N/Aunsigned int
565N/Aauth_client_request_get_server_pid(struct auth_client_request *request)
838N/A{
926N/A return request->conn->server_pid;
926N/A}
565N/A
838N/Aconst char *auth_client_request_get_cookie(struct auth_client_request *request)
838N/A{
838N/A return request->conn->cookie;
838N/A}
838N/A
838N/Abool auth_client_request_is_aborted(struct auth_client_request *request)
838N/A{
565N/A return request->callback == NULL;
616N/A}
616N/A
616N/Avoid auth_client_request_server_input(struct auth_client_request *request,
988N/A enum auth_request_status status,
988N/A const char *const *args)
926N/A{
926N/A const char *const *tmp, *base64_data = NULL;
565N/A
565N/A if (request->callback == NULL) {
988N/A /* aborted already */
565N/A return;
922N/A }
922N/A
633N/A switch (status) {
616N/A case AUTH_REQUEST_STATUS_OK:
988N/A for (tmp = args; *tmp != NULL; tmp++) {
616N/A if (strncmp(*tmp, "resp=", 5) == 0) {
616N/A base64_data = *tmp + 5;
988N/A break;
616N/A }
616N/A }
655N/A break;
988N/A case AUTH_REQUEST_STATUS_CONTINUE:
1027N/A base64_data = args[0];
926N/A args = NULL;
655N/A break;
838N/A case AUTH_REQUEST_STATUS_FAIL:
838N/A break;
838N/A }
1027N/A
838N/A request->callback(request, status, base64_data, args, request->context);
838N/A if (status != AUTH_REQUEST_STATUS_CONTINUE)
838N/A pool_unref(&request->pool);
565N/A}
565N/A