8
8
#include "strescape.h"
9
9
#include "settings-parser.h"
10
#include "iostream-ssl.h"
10
11
#include "master-service.h"
12
#include "master-service-ssl.h"
11
13
#include "master-service-settings.h"
12
14
#include "mail-storage-service.h"
13
15
#include "doveadm-util.h"
20
22
#include <unistd.h>
22
#define MAX_INBUF_SIZE 1024
24
#define MAX_INBUF_SIZE (1024*1024)
24
26
static void client_connection_input(struct client_connection *conn);
26
struct client_connection {
31
struct istream *input;
32
struct ostream *output;
33
struct ip_addr local_ip, remote_ip;
34
const struct doveadm_settings *set;
36
unsigned int handshaked:1;
37
unsigned int authenticated:1;
40
28
static struct doveadm_mail_cmd_context *
41
29
doveadm_mail_cmd_server_parse(const char *cmd_name,
42
30
const struct doveadm_settings *set,
132
124
i_error("%s: %s", ctx->cmd->name, error);
133
o_stream_send(conn->output, "\n-\n", 3);
125
o_stream_nsend(conn->output, "\n-\n", 3);
134
126
} else if (ret == 0) {
135
o_stream_send_str(conn->output, "\n-NOUSER\n");
127
o_stream_nsend_str(conn->output, "\n-NOUSER\n");
136
128
} else if (ctx->exit_code != 0) {
137
129
/* maybe not an error, but not a full success either */
138
o_stream_send(conn->output, "\n-\n", 3);
130
o_stream_nsend_str(conn->output,
131
t_strdup_printf("\n-%u\n", ctx->exit_code));
140
o_stream_send(conn->output, "\n+\n", 3);
133
o_stream_nsend(conn->output, "\n+\n", 3);
142
135
pool_unref(&ctx->pool);
177
170
memset(&input, 0, sizeof(input));
178
171
input.service = "doveadm";
172
input.local_ip = conn->local_ip;
173
input.remote_ip = conn->remote_ip;
174
input.local_port = conn->local_port;
175
input.remote_port = conn->remote_port;
180
177
for (argc = 0; args[argc] != NULL; argc++)
181
178
args[argc] = str_tabunescape(args[argc]);
222
219
o_stream_cork(conn->output);
223
220
ctx = doveadm_mail_cmd_server_parse(cmd_name, conn->set, &input, argc, args);
225
o_stream_send(conn->output, "\n-\n", 3);
222
o_stream_nsend(conn->output, "\n-\n", 3);
227
224
doveadm_mail_cmd_server_run(conn, ctx, &input);
228
225
o_stream_uncork(conn->output);
309
306
if (!conn->authenticated) {
310
307
if ((ret = client_connection_authenticate(conn)) <= 0) {
312
o_stream_send(conn->output, "-\n", 2);
309
o_stream_nsend(conn->output, "-\n", 2);
313
310
client_connection_destroy(&conn);
317
o_stream_send(conn->output, "+\n", 2);
314
o_stream_nsend(conn->output, "+\n", 2);
318
315
conn->authenticated = TRUE;
321
while (ok && (line = i_stream_read_next_line(conn->input)) != NULL) {
318
while (ok && !conn->input->closed &&
319
(line = i_stream_read_next_line(conn->input)) != NULL) {
360
struct client_connection *client_connection_create(int fd, int listen_fd)
358
static int client_connection_init_ssl(struct client_connection *conn)
362
if (master_service_ssl_init(master_service,
363
&conn->input, &conn->output,
364
&conn->ssl_iostream, &error) < 0) {
365
i_error("SSL init failed: %s", error);
368
if (ssl_iostream_handshake(conn->ssl_iostream) < 0) {
369
i_error("SSL handshake failed: %s",
370
ssl_iostream_get_last_error(conn->ssl_iostream));
377
client_connection_send_auth_handshake(struct client_connection *
380
const char *listen_path;
383
/* we'll have to do this with stat(), because at least in Linux
384
fstat() always returns mode as 0777 */
385
if (net_getunixname(listen_fd, &listen_path) == 0 &&
386
stat(listen_path, &st) == 0 && S_ISSOCK(st.st_mode) &&
387
(st.st_mode & 0777) == 0600) {
388
/* no need for client to authenticate */
389
conn->authenticated = TRUE;
390
o_stream_nsend(conn->output, "+\n", 2);
392
o_stream_nsend(conn->output, "-\n", 2);
396
struct client_connection *
397
client_connection_create(int fd, int listen_fd, bool ssl)
362
399
struct client_connection *conn;
364
const char *listen_path;
368
402
pool = pool_alloconly_create("doveadm client", 1024*16);
372
406
conn->io = io_add(fd, IO_READ, client_connection_input, conn);
373
407
conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE);
374
408
conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE);
376
(void)net_getsockname(fd, &conn->local_ip, &port);
377
(void)net_getpeername(fd, &conn->remote_ip, &port);
379
/* we'll have to do this with stat(), because at least in Linux
380
fstat() always returns mode as 0777 */
381
if (net_getunixname(listen_fd, &listen_path) == 0 &&
382
stat(listen_path, &st) == 0 && S_ISSOCK(st.st_mode) &&
383
(st.st_mode & 0777) == 0600) {
384
/* no need for client to authenticate */
385
conn->authenticated = TRUE;
386
o_stream_send(conn->output, "+\n", 2);
388
o_stream_send(conn->output, "-\n", 2);
390
if (client_connection_read_settings(conn) < 0)
409
o_stream_set_no_error_handling(conn->output, TRUE);
411
(void)net_getsockname(fd, &conn->local_ip, &conn->local_port);
412
(void)net_getpeername(fd, &conn->remote_ip, &conn->remote_port);
414
if (client_connection_read_settings(conn) < 0) {
391
415
client_connection_destroy(&conn);
419
if (client_connection_init_ssl(conn) < 0) {
420
client_connection_destroy(&conn);
424
client_connection_send_auth_handshake(conn, listen_fd);