container_of(client, struct submission_client, common);
struct smtp_server_cmd_ctx *cmd = subm_client->auth_cmd;
+ i_assert(!subm_client->auth_cmd_implicit);
i_assert(cmd != NULL);
smtp_server_cmd_auth_send_challenge(cmd, data);
client->master_data_prefix = buffer_free_without_data(&buf);
}
+void cmd_auth_begin(struct submission_client *subm_client)
+{
+ subm_client->auth_cmd_deferred = FALSE;
+
+ if (subm_client->auth_cmd == NULL)
+ return;
+
+ struct client *client = &subm_client->common;
+
+ if (subm_client->auth_cmd_implicit) {
+ (void)client_auth_begin_implicit(client,
+ SASL_MECH_NAME_EXTERNAL, "=");
+ } else {
+ struct smtp_server_cmd_auth *data = subm_client->auth_cmd_data;
+
+ i_assert(data != NULL);
+ (void)client_auth_begin(client, data->sasl_mech,
+ data->initial_response);
+ }
+}
+
int cmd_auth(void *conn_ctx, struct smtp_server_cmd_ctx *cmd,
struct smtp_server_cmd_auth *data)
{
struct submission_client *subm_client = conn_ctx;
struct client *client = &subm_client->common;
+ i_assert(!client->authenticating);
+
cmd_auth_set_master_data_prefix(subm_client, NULL);
+ subm_client->auth_cmd_deferred = FALSE;
i_assert(subm_client->auth_cmd == NULL);
subm_client->auth_cmd = cmd;
+ subm_client->auth_cmd_data = data; /* allocated on cmd pool */
+ subm_client->auth_cmd_implicit = FALSE;
+
+ if (!auth_client_is_connected(auth_client)) {
+ subm_client->auth_cmd_deferred = TRUE;
+ return 0;
+ }
- (void)client_auth_begin(client, data->sasl_mech, data->initial_response);
+ cmd_auth_begin(subm_client);
return 0;
}
return;
}
+ i_assert(!client->authenticating);
+
e_debug(cmd->event,
"Performing implicit EXTERNAL authentication");
smtp_server_command_input_lock(cmd);
cmd_auth_set_master_data_prefix(subm_client, params);
+ subm_client->auth_cmd_deferred = FALSE;
i_assert(subm_client->auth_cmd == NULL);
subm_client->auth_cmd = cmd;
+ subm_client->auth_cmd_implicit = TRUE;
+
+ if (!auth_client_is_connected(auth_client)) {
+ subm_client->auth_cmd_deferred = TRUE;
+ return;
+ }
- (void)client_auth_begin_implicit(client, SASL_MECH_NAME_EXTERNAL, "=");
+ cmd_auth_begin(subm_client);
}
smtp_server_connection_start(subm_client->conn);
}
+static void submission_client_notify_auth_connected(struct client *client)
+{
+ struct submission_client *subm_client =
+ container_of(client, struct submission_client, common);
+
+ if (subm_client->auth_cmd_deferred)
+ cmd_auth_begin(subm_client);
+}
+
static void
submission_client_notify_disconnect(struct client *_client,
enum client_disconnect_reason reason,
struct submission_client *client = context;
client->auth_cmd = NULL;
+ client->auth_cmd_data = NULL;
client_disconnect(&client->common, reason);
}
.destroy = submission_client_destroy,
.reload_config = submission_client_reload_config,
.notify_auth_ready = submission_client_notify_auth_ready,
+ .notify_auth_connected = submission_client_notify_auth_connected,
.notify_disconnect = submission_client_notify_disconnect,
.auth_send_challenge = submission_client_auth_send_challenge,
.auth_result = submission_client_auth_result,
enum smtp_capability backend_capabilities;
struct smtp_server_connection *conn;
+
struct smtp_server_cmd_ctx *auth_cmd;
+ struct smtp_server_cmd_auth *auth_cmd_data;
enum submission_proxy_state proxy_state;
enum smtp_capability proxy_capability;
struct smtp_server_reply *proxy_reply;
const char **proxy_xclient;
unsigned int proxy_xclient_replies_expected;
+
+ bool auth_cmd_implicit:1;
+ bool auth_cmd_deferred:1;
};
#endif