151
158
i_stream_skip(conn->input, size);
161
static void server_connection_authenticated(struct server_connection *conn)
163
conn->authenticated = TRUE;
164
if (conn->delayed_cmd != NULL) {
165
o_stream_send_str(conn->output, conn->delayed_cmd);
166
conn->delayed_cmd = NULL;
155
171
server_connection_authenticate(struct server_connection *conn)
157
173
string_t *plain = t_str_new(128);
158
174
string_t *cmd = t_str_new(128);
160
if (*doveadm_settings->doveadm_password == '\0') {
161
i_error("doveadm_password not set, can't authenticate");
176
if (*conn->set->doveadm_password == '\0') {
177
i_error("doveadm_password not set, "
178
"can't authenticate to remote server");
165
182
str_append_c(plain, '\0');
166
183
str_append(plain, "doveadm");
167
184
str_append_c(plain, '\0');
168
str_append(plain, doveadm_settings->doveadm_password);
185
str_append(plain, conn->set->doveadm_password);
170
187
str_append(cmd, "PLAIN\t");
171
188
base64_encode(plain->data, plain->used, cmd);
191
209
conn->handshaked = TRUE;
192
210
if (strcmp(line, "+") == 0)
193
conn->authenticated = TRUE;
211
server_connection_authenticated(conn);
194
212
else if (strcmp(line, "-") == 0) {
195
213
if (server_connection_authenticate(conn) < 0) {
196
214
server_connection_destroy(&conn);
200
219
i_error("doveadm server sent invalid handshake: %s",
209
228
server_connection_destroy(&conn);
212
data = i_stream_get_data(conn->input, &size);
216
232
if (!conn->authenticated) {
217
233
if ((line = i_stream_next_line(conn->input)) == NULL)
219
235
if (strcmp(line, "+") == 0)
220
conn->authenticated = TRUE;
236
server_connection_authenticated(conn);
222
238
i_error("doveadm authentication failed (%s)", line+1);
223
239
server_connection_destroy(&conn);
235
255
if (conn->state != SERVER_REPLY_STATE_RET)
237
257
/* fall through */
238
data = i_stream_get_data(conn->input, &size);
239
258
case SERVER_REPLY_STATE_RET:
259
line = i_stream_next_line(conn->input);
242
if (data[0] == '+' && data[1] == '\n')
243
263
server_connection_callback(conn, SERVER_CMD_REPLY_OK);
244
else if (data[0] == '-' && data[1] == '\n')
245
server_connection_callback(conn, SERVER_CMD_REPLY_FAIL);
264
else if (line[0] == '-') {
265
reply = strcmp(line+1, "NOUSER") == 0 ?
266
SERVER_CMD_REPLY_UNKNOWN_USER :
267
SERVER_CMD_REPLY_FAIL;
268
server_connection_callback(conn, reply);
247
270
i_error("doveadm server sent broken input");
248
server_connection_destroy(&conn);
271
/* we're finished, close the connection */
272
server_connection_destroy(&conn);
277
static int server_connection_read_settings(struct server_connection *conn)
279
const struct setting_parser_info *set_roots[] = {
280
&doveadm_setting_parser_info,
283
struct master_service_settings_input input;
284
struct master_service_settings_output output;
289
memset(&input, 0, sizeof(input));
290
input.roots = set_roots;
291
input.service = "doveadm";
293
(void)net_getsockname(conn->fd, &input.local_ip, &port);
294
(void)net_getpeername(conn->fd, &input.remote_ip, &port);
296
if (master_service_settings_read(master_service, &input,
297
&output, &error) < 0) {
298
i_error("Error reading configuration: %s", error);
301
set = master_service_settings_get_others(master_service)[0];
302
conn->set = settings_dup(&doveadm_setting_parser_info, set, conn->pool);
255
306
struct server_connection *
256
307
server_connection_create(struct doveadm_server *server)
258
309
#define DOVEADM_SERVER_HANDSHAKE "VERSION\tdoveadm-server\t1\t0\n"
259
310
struct server_connection *conn;
261
conn = i_new(struct server_connection, 1);
313
pool = pool_alloconly_create("doveadm server connection", 1024*16);
314
conn = p_new(pool, struct server_connection, 1);
262
316
conn->server = server;
263
317
conn->fd = doveadm_connect(server->name);
264
318
net_set_nonblock(conn->fd, TRUE);
313
368
void server_connection_cmd(struct server_connection *conn, const char *line,
314
369
server_cmd_callback_t *callback, void *context)
371
i_assert(conn->delayed_cmd == NULL);
316
373
conn->state = SERVER_REPLY_STATE_PRINT;
317
o_stream_send_str(conn->output, line);
374
if (conn->authenticated)
375
o_stream_send_str(conn->output, line);
377
conn->delayed_cmd = p_strdup(conn->pool, line);
318
378
conn->callback = callback;
319
379
conn->context = context;