auth-server-connection.c revision 7a87427770874f38d1d299635b37d699f9772860
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen/* Copyright (C) 2003 Timo Sirainen */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen/* Maximum size for an auth reply. 50kB should be more than enough. */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen (sizeof(struct auth_client_request_continue) + \
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenstatic void update_available_auth_mechs(struct auth_client *client)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen for (conn = client->connections; conn != NULL; conn = conn->next)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen client->available_auth_mechs |= conn->available_auth_mechs;
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenstatic void auth_handle_handshake(struct auth_server_connection *conn,
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen struct auth_client_handshake_reply *handshake)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen conn->available_auth_mechs = handshake->auth_mechanisms;
7a87427770874f38d1d299635b37d699f9772860Timo Sirainen if (conn->client->connect_notify_callback != NULL &&
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen conn->client->connect_notify_callback(conn->client, TRUE,
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen struct auth_server_connection *conn = context;
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen const unsigned char *data;
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen /* disconnected */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen /* buffer full - can't happen unless auth is buggy */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen i_error("BUG: Auth server sent us more than %d bytes of data",
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen i_stream_skip(conn->input, sizeof(handshake));
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen i_error("BUG: Auth server sent us too large handshake "
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen memcpy(&conn->reply, data, sizeof(conn->reply));
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen i_stream_skip(conn->input, sizeof(conn->reply));
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen /* we've got a full reply */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen auth_server_request_handle_reply(conn, &conn->reply, data);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen i_stream_skip(conn->input, conn->reply.data_size);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenauth_server_connection_new(struct auth_client *client, const char *path)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen struct auth_client_handshake_request handshake;
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen i_error("Can't connect to auth server at %s: %m", path);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen /* use blocking connection since we depend on auth server -
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen if it's slow, just wait */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen pool = pool_alloconly_create("Auth connection", 1024);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen conn = p_new(pool, struct auth_server_connection, 1);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen conn->io = io_add(fd, IO_READ, auth_client_input, conn);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen conn->input = i_stream_create_file(fd, default_pool, MAX_INBUF_SIZE,
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen conn->output = o_stream_create_file(fd, default_pool, MAX_OUTBUF_SIZE,
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen conn->requests = hash_create(default_pool, pool, 100, NULL, NULL);
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen /* send our handshake */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen if (o_stream_send(conn->output, &handshake, sizeof(handshake)) < 0) {
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen i_warning("Error sending handshake to auth server: %m");
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenvoid auth_server_connection_destroy(struct auth_server_connection *conn,
7a87427770874f38d1d299635b37d699f9772860Timo Sirainen else if (client->connect_notify_callback != NULL) {
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenauth_server_connection_find_path(struct auth_client *client, const char *path)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen for (conn = client->connections; conn != NULL; conn = conn->next) {
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenauth_server_connection_find_mech(struct auth_client *client,
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen for (conn = client->connections; conn != NULL; conn = conn->next) {
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen if ((client->available_auth_mechs & mech) == 0)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen *error_r = "Unsupported authentication mechanism";
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen *error_r = "Authentication server isn't connected, "
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen "try again later..";