Beispiel #1
0
static void verify_plain_callback(enum passdb_result result,
				  struct auth_request *request)
{
	struct auth_worker_client *client = request->context;
	string_t *str;

	if (request->failed && result == PASSDB_RESULT_OK)
		result = PASSDB_RESULT_PASSWORD_MISMATCH;

	str = t_str_new(128);
	str_printfa(str, "%u\t", request->id);

	if (result == PASSDB_RESULT_OK)
		str_append(str, "OK");
	else
		str_printfa(str, "FAIL\t%d", result);
	if (result != PASSDB_RESULT_INTERNAL_FAILURE) {
		str_append_c(str, '\t');
		str_append_tabescaped(str, request->user);
		str_append_c(str, '\t');
		if (request->passdb_password != NULL)
			str_append_tabescaped(str, request->passdb_password);
		reply_append_extra_fields(str, request);
	}
	str_append_c(str, '\n');
	auth_worker_send_reply(client, request, str);

	auth_request_unref(&request);
	auth_worker_client_check_throttle(client);
	auth_worker_client_unref(&client);
}
Beispiel #2
0
static void
lookup_user_callback(enum userdb_result result,
		     struct auth_request *auth_request)
{
	struct auth_worker_client *client = auth_request->context;
	string_t *str;

	str = t_str_new(128);
	str_printfa(str, "%u\t", auth_request->id);
	switch (result) {
	case USERDB_RESULT_INTERNAL_FAILURE:
		str_append(str, "FAIL\t");
		break;
	case USERDB_RESULT_USER_UNKNOWN:
		str_append(str, "NOTFOUND\t");
		break;
	case USERDB_RESULT_OK:
		str_append(str, "OK\t");
		str_append_tabescaped(str, auth_request->user);
		str_append_c(str, '\t');
		auth_fields_append(auth_request->userdb_reply, str, 0, 0);
		if (auth_request->userdb_lookup_tempfailed)
			str_append(str, "\ttempfail");
		break;
	}
	str_append_c(str, '\n');

	auth_worker_send_reply(client, auth_request, str);

	auth_request_unref(&auth_request);
	auth_worker_client_check_throttle(client);
	auth_worker_client_unref(&client);
}
Beispiel #3
0
static void
lookup_credentials_callback(enum passdb_result result,
			    const unsigned char *credentials, size_t size,
			    struct auth_request *request)
{
	struct auth_worker_client *client = request->context;
	string_t *str;

	if (request->failed && result == PASSDB_RESULT_OK)
		result = PASSDB_RESULT_PASSWORD_MISMATCH;

	str = t_str_new(128);
	str_printfa(str, "%u\t", request->id);

	if (result != PASSDB_RESULT_OK)
		str_printfa(str, "FAIL\t%d", result);
	else {
		str_append(str, "OK\t");
		str_append_tabescaped(str, request->user);
		str_append_c(str, '\t');
		if (request->credentials_scheme[0] != '\0') {
			str_printfa(str, "{%s.b64}", request->credentials_scheme);
			base64_encode(credentials, size, str);
		} else {
			i_assert(size == 0);
		}
		reply_append_extra_fields(str, request);
	}
	str_append_c(str, '\n');
	auth_worker_send_reply(client, request, str);

	auth_request_unref(&request);
	auth_worker_client_check_throttle(client);
	auth_worker_client_unref(&client);
}
Beispiel #4
0
static void
set_credentials_callback(bool success, struct auth_request *request)
{
	struct auth_worker_client *client = request->context;

	string_t *str;

	str = t_str_new(64);
	str_printfa(str, "%u\t%s\n", request->id, success ? "OK" : "FAIL");
	auth_worker_send_reply(client, request, str);

	auth_request_unref(&request);
	auth_worker_client_check_throttle(client);
	auth_worker_client_unref(&client);
}
Beispiel #5
0
static void
lookup_credentials_callback(enum passdb_result result,
			    const unsigned char *credentials, size_t size,
			    struct auth_request *request)
{
	struct auth_worker_client *client = request->context;
	struct auth_stream_reply *reply;
	string_t *str;

	if (request->passdb_failure && result == PASSDB_RESULT_OK)
		result = PASSDB_RESULT_PASSWORD_MISMATCH;

	reply = auth_stream_reply_init(pool_datastack_create());
	auth_stream_reply_add(reply, NULL, dec2str(request->id));

	if (result != PASSDB_RESULT_OK) {
		auth_stream_reply_add(reply, "FAIL", NULL);
		auth_stream_reply_add(reply, NULL,
				      t_strdup_printf("%d", result));
	} else {
		auth_stream_reply_add(reply, "OK", NULL);
		auth_stream_reply_add(reply, NULL, request->user);

		str = t_str_new(64);
		str_printfa(str, "{%s.b64}", request->credentials_scheme);
		base64_encode(credentials, size, str);
		auth_stream_reply_add(reply, NULL, str_c(str));

		if (request->extra_fields != NULL) {
			const char *fields =
				auth_stream_reply_export(request->extra_fields);
			auth_stream_reply_import(reply, fields);
		}
		if (request->extra_cache_fields != NULL) {
			const char *fields =
				auth_stream_reply_export(request->extra_cache_fields);
			auth_stream_reply_import(reply, fields);
		}
	}
	str = auth_stream_reply_get_str(reply);
	str_append_c(str, '\n');
	auth_worker_send_reply(client, str);

	auth_request_unref(&request);
	auth_worker_client_check_throttle(client);
	auth_worker_client_unref(&client);
}
Beispiel #6
0
static void verify_plain_callback(enum passdb_result result,
				  struct auth_request *request)
{
	struct auth_worker_client *client = request->context;
	struct auth_stream_reply *reply;
	string_t *str;

	if (request->passdb_failure && result == PASSDB_RESULT_OK)
		result = PASSDB_RESULT_PASSWORD_MISMATCH;

	reply = auth_stream_reply_init(pool_datastack_create());
	auth_stream_reply_add(reply, NULL, dec2str(request->id));

	if (result == PASSDB_RESULT_OK)
		auth_stream_reply_add(reply, "OK", NULL);
	else {
		auth_stream_reply_add(reply, "FAIL", NULL);
		auth_stream_reply_add(reply, NULL,
				      t_strdup_printf("%d", result));
	}
	if (result != PASSDB_RESULT_INTERNAL_FAILURE) {
		auth_stream_reply_add(reply, NULL, request->user);
		auth_stream_reply_add(reply, NULL,
				      request->passdb_password == NULL ? "" :
				      request->passdb_password);
		if (request->extra_fields != NULL) {
			const char *fields =
				auth_stream_reply_export(request->extra_fields);
			auth_stream_reply_import(reply, fields);
		}
		if (request->extra_cache_fields != NULL) {
			const char *fields =
				auth_stream_reply_export(request->extra_cache_fields);
			auth_stream_reply_import(reply, fields);
		}
	}
	str = auth_stream_reply_get_str(reply);
	str_append_c(str, '\n');
	auth_worker_send_reply(client, str);

	auth_request_unref(&request);
	auth_worker_client_check_throttle(client);
	auth_worker_client_unref(&client);
}
Beispiel #7
0
static void list_iter_deinit(struct auth_worker_list_context *ctx)
{
	struct auth_worker_client *client = ctx->client;
	string_t *str;

	i_assert(client->io == NULL);

	str = t_str_new(32);
	if (ctx->userdb->iface->iterate_deinit(ctx->iter) < 0)
		str_printfa(str, "%u\tFAIL\n", ctx->id);
	else
		str_printfa(str, "%u\tOK\n", ctx->id);
	auth_worker_send_reply(client, str);

	client->io = io_add(client->fd, IO_READ, auth_worker_input, client);
	o_stream_set_flush_callback(client->output, auth_worker_output, client);
	auth_worker_client_unref(&client);
	i_free(ctx);
}
Beispiel #8
0
void auth_worker_client_destroy(struct auth_worker_client **_client)
{
	struct auth_worker_client *client = *_client;

	*_client = NULL;
	if (client->fd == -1)
		return;

	i_stream_close(client->input);
	o_stream_close(client->output);

	if (client->io != NULL)
		io_remove(&client->io);

	net_disconnect(client->fd);
	client->fd = -1;
	auth_worker_client_unref(&client);

	auth_worker_client = NULL;
	master_service_client_connection_destroyed(master_service);
}
Beispiel #9
0
static void auth_worker_input(struct auth_worker_client *client)
{
	char *line;
	bool ret;

	switch (i_stream_read(client->input)) {
	case 0:
		return;
	case -1:
		/* disconnected */
		auth_worker_client_destroy(&client);
		return;
	case -2:
		/* buffer full */
		i_error("BUG: Auth worker server sent us more than %d bytes",
			(int)AUTH_WORKER_MAX_LINE_LENGTH);
		auth_worker_client_destroy(&client);
		return;
	}

	if (!client->version_received) {
		line = i_stream_next_line(client->input);
		if (line == NULL)
			return;

		if (!version_string_verify(line, "auth-worker",
				     AUTH_WORKER_PROTOCOL_MAJOR_VERSION)) {
			i_error("Auth worker not compatible with this server "
				"(mixed old and new binaries?)");
			auth_worker_client_destroy(&client);
			return;
		}
		client->version_received = TRUE;
	}
	if (!client->dbhash_received) {
		line = i_stream_next_line(client->input);
		if (line == NULL)
			return;

		if (!auth_worker_verify_db_hash(line)) {
			i_error("Auth worker sees different passdbs/userdbs "
				"than auth server. Maybe config just changed "
				"and this goes away automatically?");
			auth_worker_client_destroy(&client);
			return;
		}
		client->dbhash_received = TRUE;
	}

        client->refcount++;
	while ((line = i_stream_next_line(client->input)) != NULL) {
		T_BEGIN {
			ret = auth_worker_handle_line(client, line);
		} T_END;

		if (!ret) {
			struct auth_worker_client *client2 = client;
			auth_worker_client_destroy(&client2);
			break;
		}
	}
	auth_worker_client_unref(&client);
}