20
21
i_free_and_null(client->proxy_password);
23
static void get_plain_auth(struct client *client, string_t *dest)
28
str_append(str, client->proxy_user);
29
str_append_c(str, '\0');
30
str_append(str, client->proxy_master_user);
31
str_append_c(str, '\0');
32
str_append(str, client->proxy_password);
33
base64_encode(str_data(str), str_len(str), dest);
36
static void proxy_send_login(struct pop3_client *client, struct ostream *output)
24
static int proxy_send_login(struct pop3_client *client, struct ostream *output)
26
struct dsasl_client_settings sasl_set;
27
const unsigned char *sasl_output;
29
const char *mech_name, *error;
32
i_assert(client->common.proxy_ttl > 1);
40
33
if (client->proxy_xclient) {
41
34
/* remote supports XCLIENT, send it */
42
(void)o_stream_send_str(output, t_strdup_printf(
43
"XCLIENT ADDR=%s PORT=%u SESSION=%s\r\n",
35
o_stream_nsend_str(output, t_strdup_printf(
36
"XCLIENT ADDR=%s PORT=%u SESSION=%s TTL=%u\r\n",
44
37
net_ip2addr(&client->common.ip),
45
38
client->common.remote_port,
46
client_get_session_id(&client->common)));
39
client_get_session_id(&client->common),
40
client->common.proxy_ttl - 1));
47
41
client->common.proxy_state = POP3_PROXY_XCLIENT;
49
43
client->common.proxy_state = POP3_PROXY_LOGIN1;
52
46
str = t_str_new(128);
53
if (client->common.proxy_master_user == NULL) {
47
if (client->common.proxy_mech == NULL) {
54
48
/* send USER command */
55
49
str_append(str, "USER ");
56
50
str_append(str, client->common.proxy_user);
57
51
str_append(str, "\r\n");
59
/* master user login - use AUTH PLAIN. */
60
str_append(str, "AUTH PLAIN\r\n");
62
(void)o_stream_send(output, str_data(str), str_len(str));
52
o_stream_nsend(output, str_data(str), str_len(str));
56
i_assert(client->common.proxy_sasl_client == NULL);
57
memset(&sasl_set, 0, sizeof(sasl_set));
58
sasl_set.authid = client->common.proxy_master_user != NULL ?
59
client->common.proxy_master_user : client->common.proxy_user;
60
sasl_set.authzid = client->common.proxy_user;
61
sasl_set.password = client->common.proxy_password;
62
client->common.proxy_sasl_client =
63
dsasl_client_new(client->common.proxy_mech, &sasl_set);
64
mech_name = dsasl_client_mech_get_name(client->common.proxy_mech);
66
str_printfa(str, "AUTH %s ", mech_name);
67
if (dsasl_client_output(client->common.proxy_sasl_client,
68
&sasl_output, &len, &error) < 0) {
69
client_log_err(&client->common, t_strdup_printf(
70
"proxy: SASL mechanism %s init failed: %s",
75
str_append_c(str, '=');
77
base64_encode(sasl_output, len, str);
78
str_append(str, "\r\n");
79
o_stream_nsend(output, str_data(str), str_len(str));
81
proxy_free_password(&client->common);
82
if (client->common.proxy_state != POP3_PROXY_XCLIENT)
83
client->common.proxy_state = POP3_PROXY_LOGIN2;
88
pop3_proxy_continue_sasl_auth(struct client *client, struct ostream *output,
92
const unsigned char *data;
93
unsigned int data_len;
98
if (base64_decode(line, strlen(line), NULL, str) < 0) {
99
client_log_err(client, "proxy: Server sent invalid base64 data in AUTH response");
102
ret = dsasl_client_input(client->proxy_sasl_client,
103
str_data(str), str_len(str), &error);
105
ret = dsasl_client_output(client->proxy_sasl_client,
106
&data, &data_len, &error);
109
client_log_err(client, t_strdup_printf(
110
"proxy: Server sent invalid authentication data: %s",
116
str_truncate(str, 0);
117
base64_encode(data, data_len, str);
118
str_append(str, "\r\n");
120
o_stream_nsend(output, str_data(str), str_len(str));
65
124
int pop3_proxy_parse_line(struct client *client, const char *line)
117
181
client_proxy_failed(client, TRUE);
120
client->proxy_state = POP3_PROXY_LOGIN1;
184
client->proxy_state = client->proxy_sasl_client == NULL ?
185
POP3_PROXY_LOGIN1 : POP3_PROXY_LOGIN2;
122
187
case POP3_PROXY_LOGIN1:
123
str = t_str_new(128);
124
if (client->proxy_master_user == NULL) {
125
if (strncmp(line, "+OK", 3) != 0)
188
i_assert(client->proxy_sasl_client == NULL);
189
if (strncmp(line, "+OK", 3) != 0)
128
/* USER successful, send PASS */
129
str_append(str, "PASS ");
130
str_append(str, client->proxy_password);
131
str_append(str, "\r\n");
135
/* AUTH successful, send the authentication data */
136
get_plain_auth(client, str);
137
str_append(str, "\r\n");
139
(void)o_stream_send(output, str_data(str), str_len(str));
192
/* USER successful, send PASS */
193
o_stream_nsend_str(output, t_strdup_printf(
194
"PASS %s\r\n", client->proxy_password));
140
195
proxy_free_password(client);
141
196
client->proxy_state = POP3_PROXY_LOGIN2;
143
198
case POP3_PROXY_LOGIN2:
199
if (strncmp(line, "+ ", 2) == 0 &&
200
client->proxy_sasl_client != NULL) {
201
/* continue SASL authentication */
202
if (pop3_proxy_continue_sasl_auth(client, output,
204
client_proxy_failed(client, TRUE);
144
209
if (strncmp(line, "+OK", 3) != 0)
147
212
/* Login successful. Send this line to client. */
148
213
line = t_strconcat(line, "\r\n", NULL);
149
(void)o_stream_send_str(client->output, line);
214
o_stream_nsend_str(client->output, line);
151
216
client_proxy_finish_destroy_client(client);