.auth_result = imap_client_auth_result,
.proxy_reset = imap_proxy_reset,
.proxy_parse_line = imap_proxy_parse_line,
- .proxy_error = imap_proxy_error,
+ .proxy_failed = imap_proxy_failed,
.proxy_get_state = imap_proxy_get_state,
.send_raw_data = client_common_send_raw_data,
.input_next_cmd = imap_client_input_next_cmd,
imap_client->proxy_rcvd_state = IMAP_PROXY_RCVD_STATE_NONE;
}
-void imap_proxy_error(struct client *client, const char *text)
+static void
+imap_proxy_send_failure_reply(struct imap_client *imap_client,
+ enum login_proxy_failure_type type,
+ const char *reason ATTR_UNUSED)
+{
+ switch (type) {
+ case LOGIN_PROXY_FAILURE_TYPE_CONNECT:
+ case LOGIN_PROXY_FAILURE_TYPE_INTERNAL:
+ case LOGIN_PROXY_FAILURE_TYPE_REMOTE:
+ case LOGIN_PROXY_FAILURE_TYPE_PROTOCOL:
+ client_send_reply_code(&imap_client->common, IMAP_CMD_REPLY_NO,
+ IMAP_RESP_CODE_UNAVAILABLE,
+ LOGIN_PROXY_FAILURE_MSG);
+ break;
+ case LOGIN_PROXY_FAILURE_TYPE_REMOTE_CONFIG:
+ case LOGIN_PROXY_FAILURE_TYPE_INTERNAL_CONFIG:
+ client_send_reply_code(&imap_client->common, IMAP_CMD_REPLY_NO,
+ IMAP_RESP_CODE_SERVERBUG,
+ LOGIN_PROXY_FAILURE_MSG);
+ break;
+ case LOGIN_PROXY_FAILURE_TYPE_AUTH:
+ /* reply was already sent */
+ break;
+ }
+}
+
+void imap_proxy_failed(struct client *client,
+ enum login_proxy_failure_type type,
+ const char *reason, bool reconnecting)
{
- client_send_reply_code(client, IMAP_CMD_REPLY_NO,
- IMAP_RESP_CODE_UNAVAILABLE, text);
+ struct imap_client *imap_client =
+ container_of(client, struct imap_client, common);
+
+ if (!reconnecting)
+ imap_proxy_send_failure_reply(imap_client, type, reason);
+ client_common_proxy_failed(client, type, reason, reconnecting);
}
const char *imap_proxy_get_state(struct client *client)
void imap_proxy_reset(struct client *client);
int imap_proxy_parse_line(struct client *client, const char *line);
-void imap_proxy_error(struct client *client, const char *text);
+void imap_proxy_failed(struct client *client,
+ enum login_proxy_failure_type type,
+ const char *reason, bool reconnecting);
const char *imap_proxy_get_state(struct client *client);
#endif
#include "master-service-ssl-settings.h"
#include "client-common.h"
-#define PROXY_FAILURE_MSG "Account is temporarily unavailable."
-
/* If we've been waiting auth server to respond for over this many milliseconds,
send a "waiting" message. */
#define AUTH_WAITING_TIMEOUT_MSECS (30*1000)
client_destroy_success(client, NULL);
}
-static void client_proxy_error(struct client *client, const char *text)
-{
- client->v.proxy_error(client, text);
-}
-
const char *client_proxy_get_state(struct client *client)
{
return client->v.proxy_get_state(client);
o_stream_unref(&output);
}
-static void proxy_failed(struct client *client,
- enum login_proxy_failure_type type,
- const char *reason ATTR_UNUSED,
- bool reconnecting)
+void client_common_proxy_failed(struct client *client,
+ enum login_proxy_failure_type type,
+ const char *reason ATTR_UNUSED,
+ bool reconnecting)
{
if (client->proxy_sasl_client != NULL)
dsasl_client_free(&client->proxy_sasl_client);
case LOGIN_PROXY_FAILURE_TYPE_REMOTE:
case LOGIN_PROXY_FAILURE_TYPE_REMOTE_CONFIG:
case LOGIN_PROXY_FAILURE_TYPE_PROTOCOL:
- client_proxy_error(client, PROXY_FAILURE_MSG);
break;
case LOGIN_PROXY_FAILURE_TYPE_AUTH:
client->proxy_auth_failed = TRUE;
"proxy(%s): ", client->virtual_user));
if (!proxy_check_start(client, event, reply, &sasl_mech, &ip)) {
- client_proxy_error(client, PROXY_FAILURE_MSG);
+ client->v.proxy_failed(client,
+ LOGIN_PROXY_FAILURE_TYPE_INTERNAL,
+ LOGIN_PROXY_FAILURE_MSG, FALSE);
event_unref(&event);
return -1;
}
net_ip2addr(&proxy_set.ip), proxy_set.port));
if (login_proxy_new(client, event, &proxy_set, proxy_input,
- proxy_failed) < 0) {
+ client->v.proxy_failed) < 0) {
event_unref(&event);
return -1;
}
const char *text);
void (*proxy_reset)(struct client *client);
int (*proxy_parse_line)(struct client *client, const char *line);
- void (*proxy_error)(struct client *client, const char *text);
+ void (*proxy_failed)(struct client *client,
+ enum login_proxy_failure_type type,
+ const char *reason, bool reconnecting);
const char *(*proxy_get_state)(struct client *client);
void (*send_raw_data)(struct client *client,
const void *data, size_t size);
void client_common_send_raw_data(struct client *client,
const void *data, size_t size);
void client_common_default_free(struct client *client);
+void client_common_proxy_failed(struct client *client,
+ enum login_proxy_failure_type type,
+ const char *reason, bool reconnecting);
void client_set_auth_waiting(struct client *client);
void client_auth_send_challenge(struct client *client, const char *data);
TTL extension feature. */
#define LOGIN_PROXY_TTL 5
+#define LOGIN_PROXY_FAILURE_MSG "Account is temporarily unavailable."
+
struct client;
struct login_proxy;
.auth_result = pop3_client_auth_result,
.proxy_reset = pop3_proxy_reset,
.proxy_parse_line = pop3_proxy_parse_line,
- .proxy_error = pop3_proxy_error,
+ .proxy_failed = pop3_proxy_failed,
.proxy_get_state = pop3_proxy_get_state,
.send_raw_data = client_common_send_raw_data,
.input_next_cmd = pop3_client_input_next_cmd,
pop3_client->proxy_state = POP3_PROXY_BANNER;
}
-void pop3_proxy_error(struct client *client, const char *text)
+static void
+pop3_proxy_send_failure_reply(struct client *client,
+ enum login_proxy_failure_type type,
+ const char *reason ATTR_UNUSED)
{
- client_send_reply(client, POP3_CMD_REPLY_ERROR, text);
+ switch (type) {
+ case LOGIN_PROXY_FAILURE_TYPE_CONNECT:
+ case LOGIN_PROXY_FAILURE_TYPE_INTERNAL:
+ case LOGIN_PROXY_FAILURE_TYPE_INTERNAL_CONFIG:
+ case LOGIN_PROXY_FAILURE_TYPE_REMOTE:
+ case LOGIN_PROXY_FAILURE_TYPE_REMOTE_CONFIG:
+ case LOGIN_PROXY_FAILURE_TYPE_PROTOCOL:
+ client_send_reply(client, POP3_CMD_REPLY_ERROR,
+ LOGIN_PROXY_FAILURE_MSG);
+ break;
+ case LOGIN_PROXY_FAILURE_TYPE_AUTH:
+ /* reply was already sent */
+ break;
+ }
+}
+
+void pop3_proxy_failed(struct client *client,
+ enum login_proxy_failure_type type,
+ const char *reason, bool reconnecting)
+{
+ if (!reconnecting)
+ pop3_proxy_send_failure_reply(client, type, reason);
+ client_common_proxy_failed(client, type, reason, reconnecting);
}
const char *pop3_proxy_get_state(struct client *client)
void pop3_proxy_reset(struct client *client);
int pop3_proxy_parse_line(struct client *client, const char *line);
-void pop3_proxy_error(struct client *client, const char *text);
+void pop3_proxy_failed(struct client *client,
+ enum login_proxy_failure_type type,
+ const char *reason, bool reconnecting);
const char *pop3_proxy_get_state(struct client *client);
#endif
.auth_result = submission_client_auth_result,
.proxy_reset = submission_proxy_reset,
.proxy_parse_line = submission_proxy_parse_line,
- .proxy_error = submission_proxy_error,
+ .proxy_failed = submission_proxy_failed,
.proxy_get_state = submission_proxy_get_state,
};
subm_client->proxy_reply = NULL;
}
-void submission_proxy_error(struct client *client, const char *text)
+static void
+submission_proxy_send_failure_reply(struct submission_client *subm_client,
+ enum login_proxy_failure_type type,
+ const char *reason ATTR_UNUSED)
+{
+ struct smtp_server_cmd_ctx *cmd = subm_client->pending_auth;
+ if (cmd == NULL)
+ return;
+
+ subm_client->pending_auth = NULL;
+ switch (type) {
+ case LOGIN_PROXY_FAILURE_TYPE_CONNECT:
+ case LOGIN_PROXY_FAILURE_TYPE_INTERNAL:
+ case LOGIN_PROXY_FAILURE_TYPE_INTERNAL_CONFIG:
+ case LOGIN_PROXY_FAILURE_TYPE_REMOTE:
+ case LOGIN_PROXY_FAILURE_TYPE_REMOTE_CONFIG:
+ case LOGIN_PROXY_FAILURE_TYPE_PROTOCOL:
+ smtp_server_reply(cmd, 535, "5.7.8", LOGIN_PROXY_FAILURE_MSG);
+ break;
+ case LOGIN_PROXY_FAILURE_TYPE_AUTH:
+ /* reply was already sent */
+ break;
+ }
+}
+
+void submission_proxy_failed(struct client *client,
+ enum login_proxy_failure_type type,
+ const char *reason, bool reconnecting)
{
struct submission_client *subm_client =
container_of(client, struct submission_client, common);
- struct smtp_server_cmd_ctx *cmd = subm_client->pending_auth;
- if (cmd != NULL) {
- subm_client->pending_auth = NULL;
- smtp_server_reply(cmd, 535, "5.7.8", "%s", text);
- }
+ if (!reconnecting)
+ submission_proxy_send_failure_reply(subm_client, type, reason);
+ client_common_proxy_failed(client, type, reason, reconnecting);
}
const char *submission_proxy_get_state(struct client *client)
void submission_proxy_reset(struct client *client);
int submission_proxy_parse_line(struct client *client, const char *line);
-void submission_proxy_error(struct client *client, const char *text);
+void submission_proxy_failed(struct client *client,
+ enum login_proxy_failure_type type,
+ const char *reason, bool reconnecting);
const char *submission_proxy_get_state(struct client *client);
#endif