auth-server-connection.c revision b0df0e9a8ed8889ad4bf032043ab245ce8851fde
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina/* Copyright (C) 2003-2004 Timo Sirainen */
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březinastatic void auth_server_connection_unref(struct auth_server_connection *conn);
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březinastatic void update_available_auth_mechs(struct auth_server_connection *conn)
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina unsigned int i;
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina for (i = 0; i < conn->available_auth_mechs_count; i++) {
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina if (auth_client_find_mech(client, mech[i].name) == NULL) {
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březinaauth_client_input_mech(struct auth_server_connection *conn, const char *args)
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina const char *const *list;
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina i_error("BUG: Authentication server already sent handshake");
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina i_error("BUG: Authentication server sent broken MECH line");
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina mech_desc.name = p_strdup(conn->pool, list[0]);
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina else if (strcmp(*list, "forward-secrecy") == 0)
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina buffer_append(conn->auth_mechs_buf, &mech_desc, sizeof(mech_desc));
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březinaauth_client_input_spid(struct auth_server_connection *conn, const char *args)
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina i_error("BUG: Authentication server already sent handshake");
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina conn->server_pid = (unsigned int)strtoul(args, NULL, 10);
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březinaauth_client_input_cuid(struct auth_server_connection *conn, const char *args)
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina i_error("BUG: Authentication server already sent handshake");
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina conn->connect_uid = (unsigned int)strtoul(args, NULL, 10);
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březinastatic int auth_client_input_done(struct auth_server_connection *conn)
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina conn->available_auth_mechs = conn->auth_mechs_buf->data;
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina conn->auth_mechs_buf->used / sizeof(struct auth_mech_desc);
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina if (conn->client->connect_notify_callback != NULL &&
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina conn->client->connect_notify_callback(conn->client, TRUE,
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina struct auth_server_connection *conn = context;
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina /* disconnected */
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina /* buffer full - can't happen unless auth is buggy */
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina i_error("BUG: Auth server sent us more than %d bytes of data",
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina /* make sure the major version matches */
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina i_error("Authentication server not compatible with "
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina "this client (mixed old and new binaries?)");
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina while ((line = i_stream_next_line(conn->input)) != NULL) {
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina /* ignore unknown command */
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březinaauth_server_connection_new(struct auth_client *client, const char *path)
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina i_error("Can't connect to auth server at %s: %m", path);
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina /* use blocking connection since we depend on auth server -
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina if it's slow, just wait */
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina pool = pool_alloconly_create("Auth connection", 1024);
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina conn = p_new(pool, struct auth_server_connection, 1);
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina conn->io = io_add(fd, IO_READ, auth_client_input, conn);
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina client->ext_input_add(fd, auth_client_input, conn);
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina conn->input = i_stream_create_file(fd, default_pool,
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina conn->output = o_stream_create_file(fd, default_pool, (size_t)-1,
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina conn->requests = hash_create(default_pool, pool, 100, NULL, NULL);
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina conn->auth_mechs_buf = buffer_create_dynamic(default_pool, 256);
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina handshake = t_strdup_printf("VERSION\t%u.%u\nCPID\t%u\n",
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina if (o_stream_send_str(conn->output, handshake) < 0) {
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina i_warning("Error sending handshake to auth server: %m");
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březinavoid auth_server_connection_destroy(struct auth_server_connection *conn,
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina else if (client->connect_notify_callback != NULL) {
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březinastatic void auth_server_connection_unref(struct auth_server_connection *conn)
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březinaauth_server_connection_find_path(struct auth_client *client, const char *path)
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina for (conn = client->connections; conn != NULL; conn = conn->next) {
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březinaauth_server_connection_find_mech(struct auth_client *client,
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina unsigned int i;
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina for (conn = client->connections; conn != NULL; conn = conn->next) {
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina for (i = 0; i < conn->available_auth_mechs_count; i++) {
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina if (auth_client_find_mech(client, name) == NULL)
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina *error_r = "Unsupported authentication mechanism";
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina *error_r = "Authentication server isn't connected, "
a641a13889d617aca6bd998025e9087e822ff7f0Pavel Březina "try again later..";