auth-server-connection.c revision 4b8c92b4773677a7b4064816e469eeafc976ba75
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
a272994d43de80a306a8ed1f2983960d1f3102d0Timo Sirainenstatic void auth_server_connection_unref(struct auth_server_connection *conn);
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainenstatic void update_available_auth_mechs(struct auth_server_connection *conn)
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen unsigned int i;
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen for (i = 0; i < conn->available_auth_mechs_count; i++) {
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen if (auth_client_find_mech(client, mech[i].name) == NULL) {
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainenauth_client_input_mech(struct auth_server_connection *conn, const char *args)
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen const char *const *list;
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen i_error("BUG: Authentication server already sent handshake");
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen i_error("BUG: Authentication server sent broken MECH line");
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen mech_desc.name = p_strdup(conn->pool, list[0]);
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen else if (strcmp(*list, "forward-secrecy") == 0)
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen buffer_append(conn->auth_mechs_buf, &mech_desc, sizeof(mech_desc));
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainenauth_client_input_spid(struct auth_server_connection *conn, const char *args)
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen i_error("BUG: Authentication server already sent handshake");
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen conn->server_pid = (unsigned int)strtoul(args, NULL, 10);
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainenauth_client_input_cuid(struct auth_server_connection *conn, const char *args)
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen i_error("BUG: Authentication server already sent handshake");
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen conn->connect_uid = (unsigned int)strtoul(args, NULL, 10);
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainenstatic int auth_client_input_done(struct auth_server_connection *conn)
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen conn->available_auth_mechs = conn->auth_mechs_buf->data;
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen conn->auth_mechs_buf->used / sizeof(struct auth_mech_desc);
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 /* 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",
b0df0e9a8ed8889ad4bf032043ab245ce8851fdeTimo Sirainen /* make sure the major version matches */
b0df0e9a8ed8889ad4bf032043ab245ce8851fdeTimo Sirainen i_error("Authentication server not compatible with "
b0df0e9a8ed8889ad4bf032043ab245ce8851fdeTimo Sirainen "this client (mixed old and new binaries?)");
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen while ((line = i_stream_next_line(conn->input)) != NULL) {
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen /* ignore unknown command */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainenauth_server_connection_new(struct auth_client *client, const char *path)
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);
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen conn->io = io_add(fd, IO_READ, auth_client_input, conn);
acf3b7bf3a8891b118a71c45e6c48d17bc90b259Timo Sirainen client->ext_input_add(fd, auth_client_input, conn);
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen conn->input = i_stream_create_file(fd, default_pool,
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen conn->output = o_stream_create_file(fd, default_pool, (size_t)-1,
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen conn->requests = hash_create(default_pool, pool, 100, NULL, NULL);
73bfdbe28c2ce6d143eadf0bab8ccfbe4cab0faeTimo Sirainen conn->auth_mechs_buf = buffer_create_dynamic(default_pool, 256);
4b8c92b4773677a7b4064816e469eeafc976ba75Timo Sirainen handshake = t_strdup_printf("VERSION\t%u\t%u\nCPID\t%u\n",
b0df0e9a8ed8889ad4bf032043ab245ce8851fdeTimo Sirainen if (o_stream_send_str(conn->output, 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) {
a272994d43de80a306a8ed1f2983960d1f3102d0Timo Sirainenstatic void auth_server_connection_unref(struct auth_server_connection *conn)
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,
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen unsigned int i;
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen for (conn = client->connections; conn != NULL; conn = conn->next) {
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen for (i = 0; i < conn->available_auth_mechs_count; i++) {
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen if (auth_client_find_mech(client, name) == NULL)
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen *error_r = "Unsupported authentication mechanism";
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen *error_r = "Authentication server isn't connected, "
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen "try again later..";