~ubuntu-branches/ubuntu/utopic/dovecot/utopic-proposed

« back to all changes in this revision

Viewing changes to src/auth/auth-client-connection.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-01-08 09:35:49 UTC
  • mfrom: (4.1.35 sid)
  • Revision ID: package-import@ubuntu.com-20140108093549-i72o93pux8p0dlaf
Tags: 1:2.2.9-1ubuntu1
* Merge from Debian unstable, remaining changes:
  + Add mail-stack-delivery package:
    - Update d/rules
    - d/control: convert existing dovecot-postfix package to a dummy
      package and add new mail-stack-delivery package.
    - Update maintainer scripts.
    - Rename d/dovecot-postfix.* to debian/mail-stack-delivery.*
    - d/mail-stack-delivery.preinst: Move previously installed backups and
      config files to a new package namespace.
    - d/mail-stack-delivery.prerm: Added to handle downgrades.
  + Use Snakeoil SSL certificates by default:
    - d/control: Depend on ssl-cert.
    - d/dovecot-core.postinst: Relax grep for SSL_* a bit.
  + Add autopkgtest to debian/tests/*.
  + Add ufw integration:
    - d/dovecot-core.ufw.profile: new ufw profile.
    - d/rules: install profile in dovecot-core.
    - d/control: dovecot-core - suggest ufw.
  + d/dovecot-core.dirs: Added usr/share/doc/dovecot-core
  + Add apport hook:
    - d/rules, d/source_dovecot.py
  + Add upstart job:
    - d/rules, d/dovecot-core.dovecot.upstart, d/control,
      d/dovecot-core.dirs, dovecot-imapd.{postrm, postinst, prerm},
      d/dovecot-pop3d.{postinst, postrm, prerm}.
      d/mail-stack-deliver.postinst: Convert init script to upstart.
  + Use the autotools-dev dh addon to update config.guess/config.sub for
    arm64.
* Dropped changes, included in Debian:
  - Update Dovecot name to reflect distribution in login greeting.
  - Update Drac plugin for >= 2.0.0 support.
* d/control: Drop dovecot-postfix package as its no longer required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2002-2012 Dovecot authors, see the included COPYING file */
 
1
/* Copyright (c) 2002-2013 Dovecot authors, see the included COPYING file */
2
2
 
3
3
#include "auth-common.h"
4
4
#include "ioloop.h"
5
5
#include "istream.h"
6
6
#include "ostream.h"
7
 
#include "network.h"
 
7
#include "net.h"
8
8
#include "hex-binary.h"
9
9
#include "hostpid.h"
10
10
#include "llist.h"
14
14
#include "safe-memset.h"
15
15
#include "master-service.h"
16
16
#include "mech.h"
17
 
#include "auth-stream.h"
 
17
#include "auth-fields.h"
18
18
#include "auth-request-handler.h"
19
19
#include "auth-client-interface.h"
20
20
#include "auth-client-connection.h"
24
24
 
25
25
#define OUTBUF_THROTTLE_SIZE (1024*50)
26
26
 
 
27
#define AUTH_DEBUG_SENSITIVE_SUFFIX \
 
28
        " (previous base64 data may contain sensitive data)"
 
29
 
27
30
static void auth_client_disconnected(struct auth_client_connection **_conn);
28
31
static void auth_client_connection_unref(struct auth_client_connection **_conn);
29
32
static void auth_client_input(struct auth_client_connection *conn);
54
57
        iov[0].iov_len = strlen(cmd);
55
58
        iov[1].iov_base = "\n";
56
59
        iov[1].iov_len = 1;
57
 
        (void)o_stream_sendv(conn->output, iov, 2);
 
60
        o_stream_nsendv(conn->output, iov, 2);
58
61
 
59
62
        if (o_stream_get_buffer_used_size(conn->output) >=
60
63
            OUTBUF_THROTTLE_SIZE) {
65
68
        }
66
69
 
67
70
        if (conn->auth->set->debug) {
68
 
                i_debug("client out: %s", conn->auth->set->debug_passwords ?
 
71
                i_debug("client passdb out: %s",
 
72
                        conn->auth->set->debug_passwords ?
69
73
                        cmd : reply_line_hide_pass(cmd));
70
74
        }
71
75
}
72
76
 
73
 
static void auth_callback(struct auth_stream_reply *reply,
 
77
static void auth_callback(const char *reply,
74
78
                          struct auth_client_connection *conn)
75
79
{
76
80
        if (reply == NULL) {
77
81
                /* handler destroyed */
78
82
                auth_client_connection_unref(&conn);
79
 
                return;
 
83
        } else {
 
84
                auth_client_send(conn, reply);
80
85
        }
81
 
 
82
 
        auth_client_send(conn, auth_stream_reply_export(reply));
83
86
}
84
87
 
85
88
static bool
124
127
        /* handshake complete, we can now actually start serving requests */
125
128
        conn->refcount++;
126
129
        conn->request_handler =
127
 
                auth_request_handler_create(auth_callback, conn,
 
130
                auth_request_handler_create(conn->token_auth, auth_callback, conn,
128
131
                                            !conn->login_requests ? NULL :
129
132
                                            auth_master_request_callback);
130
133
        auth_request_handler_set(conn->request_handler, conn->connect_uid, pid);
150
153
        return 1;
151
154
}
152
155
 
153
 
static const char *auth_line_hide_pass(const char *line)
 
156
static const char *
 
157
auth_line_hide_pass(struct auth_client_connection *conn, const char *line)
154
158
{
155
159
        const char *p, *p2;
156
160
 
159
163
                return line;
160
164
        p += 6;
161
165
 
 
166
        if (conn->auth->set->debug_passwords)
 
167
                return t_strconcat(line, AUTH_DEBUG_SENSITIVE_SUFFIX, NULL);
 
168
 
162
169
        p2 = strchr(p, '\t');
163
170
        return t_strconcat(t_strdup_until(line, p), PASSWORD_HIDDEN_STR,
164
171
                           p2, NULL);
165
172
}
166
173
 
167
 
static const char *cont_line_hide_pass(const char *line)
 
174
static const char *
 
175
cont_line_hide_pass(struct auth_client_connection *conn, const char *line)
168
176
{
169
177
        const char *p;
170
178
 
 
179
        if (conn->auth->set->debug_passwords)
 
180
                return t_strconcat(line, AUTH_DEBUG_SENSITIVE_SUFFIX, NULL);
 
181
 
171
182
        p = strchr(line, '\t');
172
183
        if (p == NULL)
173
184
                return line;
195
206
        if (strncmp(line, "AUTH\t", 5) == 0) {
196
207
                if (conn->auth->set->debug) {
197
208
                        i_debug("client in: %s",
198
 
                                conn->auth->set->debug_passwords ? line :
199
 
                                auth_line_hide_pass(line));
 
209
                                auth_line_hide_pass(conn, line));
200
210
                }
201
211
                return auth_request_handler_auth_begin(conn->request_handler,
202
212
                                                       line + 5);
204
214
        if (strncmp(line, "CONT\t", 5) == 0) {
205
215
                if (conn->auth->set->debug) {
206
216
                        i_debug("client in: %s",
207
 
                                conn->auth->set->debug_passwords ? line :
208
 
                                cont_line_hide_pass(line));
 
217
                                cont_line_hide_pass(conn, line));
209
218
                }
210
219
                return auth_request_handler_auth_continue(conn->request_handler,
211
220
                                                          line + 5);
292
301
        auth_client_connection_unref(&conn);
293
302
}
294
303
 
295
 
struct auth_client_connection *
296
 
auth_client_connection_create(struct auth *auth, int fd, bool login_requests)
 
304
void auth_client_connection_create(struct auth *auth, int fd,
 
305
                                   bool login_requests, bool token_auth)
297
306
{
298
307
        static unsigned int connect_uid_counter = 0;
299
308
        struct auth_client_connection *conn;
 
309
        const char *mechanisms;
300
310
        string_t *str;
301
311
 
302
312
        conn = i_new(struct auth_client_connection, 1);
304
314
        conn->refcount = 1;
305
315
        conn->connect_uid = ++connect_uid_counter;
306
316
        conn->login_requests = login_requests;
 
317
        conn->token_auth = token_auth;
307
318
        random_fill(conn->cookie, sizeof(conn->cookie));
308
319
 
309
320
        conn->fd = fd;
310
321
        conn->input = i_stream_create_fd(fd, AUTH_CLIENT_MAX_LINE_LENGTH,
311
322
                                         FALSE);
312
323
        conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE);
 
324
        o_stream_set_no_error_handling(conn->output, TRUE);
313
325
        o_stream_set_flush_callback(conn->output, auth_client_output, conn);
314
326
        conn->io = io_add(fd, IO_READ, auth_client_input, conn);
315
327
 
316
328
        DLLIST_PREPEND(&auth_client_connections, conn);
317
329
 
 
330
        if (token_auth) {
 
331
                mechanisms = t_strconcat("MECH\t",
 
332
                        mech_dovecot_token.mech_name, "\n", NULL);
 
333
        } else {
 
334
                mechanisms = str_c(auth->reg->handshake);
 
335
        }
 
336
 
318
337
        str = t_str_new(128);
319
338
        str_printfa(str, "VERSION\t%u\t%u\n%sSPID\t%s\nCUID\t%u\nCOOKIE\t",
320
339
                    AUTH_CLIENT_PROTOCOL_MAJOR_VERSION,
321
340
                    AUTH_CLIENT_PROTOCOL_MINOR_VERSION,
322
 
                    str_c(auth->reg->handshake), my_pid, conn->connect_uid);
 
341
                    mechanisms, my_pid, conn->connect_uid);
323
342
        binary_to_hex_append(str, conn->cookie, sizeof(conn->cookie));
324
343
        str_append(str, "\nDONE\n");
325
344
 
326
345
        if (o_stream_send(conn->output, str_data(str), str_len(str)) < 0)
327
346
                auth_client_disconnected(&conn);
328
 
 
329
 
        return conn;
330
347
}
331
348
 
332
349
void auth_client_connection_destroy(struct auth_client_connection **_conn)