Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/auth/mech-apop.c @ 9266:cd29b745c8dd HEAD
configure: clock_gettime()'s -lrt adding dropped everything else from $LIBS.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 27 Jul 2009 06:32:42 -0400 |
parents | c1fea9e157c8 |
children |
rev | line source |
---|---|
2270 | 1 /* |
2 * APOP (RFC-1460) authentication mechanism. | |
3 * | |
4 * Copyright (c) 2004 Andrey Panin <pazke@donpac.ru> | |
5 * | |
4382
f8d37e26a2b3
Relicensed dovecot-auth to MIT.
Timo Sirainen <tss@iki.fi>
parents:
3863
diff
changeset
|
6 * This software is released under the MIT license. |
2270 | 7 */ |
8 | |
9 #include "common.h" | |
10 #include "mech.h" | |
11 #include "passdb.h" | |
12 #include "md5.h" | |
13 #include "buffer.h" | |
14 #include "auth-client-connection.h" | |
15 #include "auth-master-connection.h" | |
16 | |
3073
7e0caae73c59
Require a valid timestamp in APOP challenge.
Timo Sirainen <tss@iki.fi>
parents:
3072
diff
changeset
|
17 #include <stdio.h> |
7e0caae73c59
Require a valid timestamp in APOP challenge.
Timo Sirainen <tss@iki.fi>
parents:
3072
diff
changeset
|
18 #include <unistd.h> |
2270 | 19 |
20 struct apop_auth_request { | |
21 struct auth_request auth_request; | |
22 | |
23 pool_t pool; | |
24 | |
25 /* requested: */ | |
26 char *challenge; | |
27 | |
28 /* received: */ | |
8604
67f923c9988a
APOP auth: Minor code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
5598
diff
changeset
|
29 unsigned char response_digest[16]; |
2270 | 30 }; |
31 | |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3766
diff
changeset
|
32 static bool verify_credentials(struct apop_auth_request *request, |
5598
971050640e3b
All password schemes can now be encoded with base64 or hex. The encoding is
Timo Sirainen <tss@iki.fi>
parents:
5593
diff
changeset
|
33 const unsigned char *credentials, size_t size) |
3058
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
34 { |
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
35 unsigned char digest[16]; |
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
36 struct md5_context ctx; |
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
37 |
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
38 md5_init(&ctx); |
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
39 md5_update(&ctx, request->challenge, strlen(request->challenge)); |
5598
971050640e3b
All password schemes can now be encoded with base64 or hex. The encoding is
Timo Sirainen <tss@iki.fi>
parents:
5593
diff
changeset
|
40 md5_update(&ctx, credentials, size); |
3058
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
41 md5_final(&ctx, digest); |
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
42 |
8604
67f923c9988a
APOP auth: Minor code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
5598
diff
changeset
|
43 return memcmp(digest, request->response_digest, 16) == 0; |
3058
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
44 } |
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
45 |
5475
769aaaee6821
Reverted accidental commit. This code isn't ready yet.
Timo Sirainen <tss@iki.fi>
parents:
5462
diff
changeset
|
46 static void |
3058
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
47 apop_credentials_callback(enum passdb_result result, |
5598
971050640e3b
All password schemes can now be encoded with base64 or hex. The encoding is
Timo Sirainen <tss@iki.fi>
parents:
5593
diff
changeset
|
48 const unsigned char *credentials, size_t size, |
2270 | 49 struct auth_request *auth_request) |
50 { | |
2736
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
51 struct apop_auth_request *request = |
2270 | 52 (struct apop_auth_request *)auth_request; |
53 | |
3058
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
54 switch (result) { |
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
55 case PASSDB_RESULT_OK: |
5598
971050640e3b
All password schemes can now be encoded with base64 or hex. The encoding is
Timo Sirainen <tss@iki.fi>
parents:
5593
diff
changeset
|
56 if (verify_credentials(request, credentials, size)) |
5475
769aaaee6821
Reverted accidental commit. This code isn't ready yet.
Timo Sirainen <tss@iki.fi>
parents:
5462
diff
changeset
|
57 auth_request_success(auth_request, NULL, 0); |
769aaaee6821
Reverted accidental commit. This code isn't ready yet.
Timo Sirainen <tss@iki.fi>
parents:
5462
diff
changeset
|
58 else |
769aaaee6821
Reverted accidental commit. This code isn't ready yet.
Timo Sirainen <tss@iki.fi>
parents:
5462
diff
changeset
|
59 auth_request_fail(auth_request); |
3058
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
60 break; |
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
61 case PASSDB_RESULT_INTERNAL_FAILURE: |
3064
2d33734b16d5
Split auth_request* functions from mech.c to auth-request.c
Timo Sirainen <tss@iki.fi>
parents:
3058
diff
changeset
|
62 auth_request_internal_failure(auth_request); |
3058
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
63 break; |
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
64 default: |
3064
2d33734b16d5
Split auth_request* functions from mech.c to auth-request.c
Timo Sirainen <tss@iki.fi>
parents:
3058
diff
changeset
|
65 auth_request_fail(auth_request); |
3058
052f3a5743af
Make FAIL reply contain "temp" parameter if the authentication failed
Timo Sirainen <tss@iki.fi>
parents:
2736
diff
changeset
|
66 break; |
2289 | 67 } |
2270 | 68 } |
69 | |
2736
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
70 static void |
2270 | 71 mech_apop_auth_initial(struct auth_request *auth_request, |
3071 | 72 const unsigned char *data, size_t data_size) |
2270 | 73 { |
2736
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
74 struct apop_auth_request *request = |
2270 | 75 (struct apop_auth_request *)auth_request; |
76 const unsigned char *tmp, *end, *username = NULL; | |
3073
7e0caae73c59
Require a valid timestamp in APOP challenge.
Timo Sirainen <tss@iki.fi>
parents:
3072
diff
changeset
|
77 unsigned long pid, connect_uid, timestamp; |
7e0caae73c59
Require a valid timestamp in APOP challenge.
Timo Sirainen <tss@iki.fi>
parents:
3072
diff
changeset
|
78 const char *error; |
2270 | 79 |
8604
67f923c9988a
APOP auth: Minor code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
5598
diff
changeset
|
80 /* pop3-login handles sending the challenge and getting the response. |
67f923c9988a
APOP auth: Minor code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
5598
diff
changeset
|
81 Our input here is: <challenge> \0 <username> \0 <response> */ |
67f923c9988a
APOP auth: Minor code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
5598
diff
changeset
|
82 |
2736
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
83 if (data_size == 0) { |
2270 | 84 /* Should never happen */ |
3069 | 85 auth_request_log_info(auth_request, "apop", |
86 "no initial respone"); | |
3064
2d33734b16d5
Split auth_request* functions from mech.c to auth-request.c
Timo Sirainen <tss@iki.fi>
parents:
3058
diff
changeset
|
87 auth_request_fail(auth_request); |
2736
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
88 return; |
2270 | 89 } |
90 | |
2736
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
91 tmp = data; |
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
92 end = data + data_size; |
2270 | 93 |
8604
67f923c9988a
APOP auth: Minor code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
5598
diff
changeset
|
94 /* get the challenge */ |
2270 | 95 while (tmp != end && *tmp != '\0') |
96 tmp++; | |
8604
67f923c9988a
APOP auth: Minor code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
5598
diff
changeset
|
97 request->challenge = p_strdup_until(request->pool, data, tmp); |
2270 | 98 |
5088
caa07c0dbb56
Verify the APOP input before passing it to sscanf() to make sure it's
Timo Sirainen <tss@iki.fi>
parents:
4782
diff
changeset
|
99 if (tmp != end) { |
caa07c0dbb56
Verify the APOP input before passing it to sscanf() to make sure it's
Timo Sirainen <tss@iki.fi>
parents:
4782
diff
changeset
|
100 /* get the username */ |
caa07c0dbb56
Verify the APOP input before passing it to sscanf() to make sure it's
Timo Sirainen <tss@iki.fi>
parents:
4782
diff
changeset
|
101 username = ++tmp; |
caa07c0dbb56
Verify the APOP input before passing it to sscanf() to make sure it's
Timo Sirainen <tss@iki.fi>
parents:
4782
diff
changeset
|
102 while (tmp != end && *tmp != '\0') |
caa07c0dbb56
Verify the APOP input before passing it to sscanf() to make sure it's
Timo Sirainen <tss@iki.fi>
parents:
4782
diff
changeset
|
103 tmp++; |
caa07c0dbb56
Verify the APOP input before passing it to sscanf() to make sure it's
Timo Sirainen <tss@iki.fi>
parents:
4782
diff
changeset
|
104 } |
caa07c0dbb56
Verify the APOP input before passing it to sscanf() to make sure it's
Timo Sirainen <tss@iki.fi>
parents:
4782
diff
changeset
|
105 |
caa07c0dbb56
Verify the APOP input before passing it to sscanf() to make sure it's
Timo Sirainen <tss@iki.fi>
parents:
4782
diff
changeset
|
106 if (tmp + 1 + 16 != end) { |
caa07c0dbb56
Verify the APOP input before passing it to sscanf() to make sure it's
Timo Sirainen <tss@iki.fi>
parents:
4782
diff
changeset
|
107 /* Should never happen */ |
caa07c0dbb56
Verify the APOP input before passing it to sscanf() to make sure it's
Timo Sirainen <tss@iki.fi>
parents:
4782
diff
changeset
|
108 auth_request_log_info(auth_request, "apop", "malformed data"); |
caa07c0dbb56
Verify the APOP input before passing it to sscanf() to make sure it's
Timo Sirainen <tss@iki.fi>
parents:
4782
diff
changeset
|
109 auth_request_fail(auth_request); |
caa07c0dbb56
Verify the APOP input before passing it to sscanf() to make sure it's
Timo Sirainen <tss@iki.fi>
parents:
4782
diff
changeset
|
110 return; |
caa07c0dbb56
Verify the APOP input before passing it to sscanf() to make sure it's
Timo Sirainen <tss@iki.fi>
parents:
4782
diff
changeset
|
111 } |
8606
c1fea9e157c8
apop: Compile fix for previous commit.
Timo Sirainen <tss@iki.fi>
parents:
8605
diff
changeset
|
112 memcpy(request->response_digest, tmp + 1, |
c1fea9e157c8
apop: Compile fix for previous commit.
Timo Sirainen <tss@iki.fi>
parents:
8605
diff
changeset
|
113 sizeof(request->response_digest)); |
5088
caa07c0dbb56
Verify the APOP input before passing it to sscanf() to make sure it's
Timo Sirainen <tss@iki.fi>
parents:
4782
diff
changeset
|
114 |
2270 | 115 /* the challenge must begin with trusted unique ID. we trust only |
116 ourself, so make sure it matches our connection specific UID | |
3073
7e0caae73c59
Require a valid timestamp in APOP challenge.
Timo Sirainen <tss@iki.fi>
parents:
3072
diff
changeset
|
117 which we told to client in handshake. Also require a timestamp |
7e0caae73c59
Require a valid timestamp in APOP challenge.
Timo Sirainen <tss@iki.fi>
parents:
3072
diff
changeset
|
118 which is later than this process's start time. */ |
7e0caae73c59
Require a valid timestamp in APOP challenge.
Timo Sirainen <tss@iki.fi>
parents:
3072
diff
changeset
|
119 |
8604
67f923c9988a
APOP auth: Minor code cleanups.
Timo Sirainen <tss@iki.fi>
parents:
5598
diff
changeset
|
120 if (sscanf(request->challenge, "<%lx.%lx.%lx.", |
3073
7e0caae73c59
Require a valid timestamp in APOP challenge.
Timo Sirainen <tss@iki.fi>
parents:
3072
diff
changeset
|
121 &pid, &connect_uid, ×tamp) != 3 || |
3074 | 122 connect_uid != auth_request->connect_uid || |
3073
7e0caae73c59
Require a valid timestamp in APOP challenge.
Timo Sirainen <tss@iki.fi>
parents:
3072
diff
changeset
|
123 pid != (unsigned long)getpid() || |
7e0caae73c59
Require a valid timestamp in APOP challenge.
Timo Sirainen <tss@iki.fi>
parents:
3072
diff
changeset
|
124 (time_t)timestamp < process_start_time) { |
3069 | 125 auth_request_log_info(auth_request, "apop", |
126 "invalid challenge"); | |
3064
2d33734b16d5
Split auth_request* functions from mech.c to auth-request.c
Timo Sirainen <tss@iki.fi>
parents:
3058
diff
changeset
|
127 auth_request_fail(auth_request); |
2736
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
128 return; |
2270 | 129 } |
130 | |
3065
29d83a8bb50d
Reorganized the code to have less global/static variables.
Timo Sirainen <tss@iki.fi>
parents:
3064
diff
changeset
|
131 if (!auth_request_set_username(auth_request, (const char *)username, |
29d83a8bb50d
Reorganized the code to have less global/static variables.
Timo Sirainen <tss@iki.fi>
parents:
3064
diff
changeset
|
132 &error)) { |
3069 | 133 auth_request_log_info(auth_request, "apop", "%s", error); |
3064
2d33734b16d5
Split auth_request* functions from mech.c to auth-request.c
Timo Sirainen <tss@iki.fi>
parents:
3058
diff
changeset
|
134 auth_request_fail(auth_request); |
2736
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
135 return; |
2270 | 136 } |
137 | |
5593
f8dc0bdb06a7
Removed enum passdb_credentials. Use scheme strings directly instead. This
Timo Sirainen <tss@iki.fi>
parents:
5475
diff
changeset
|
138 auth_request_lookup_credentials(auth_request, "PLAIN", |
3068 | 139 apop_credentials_callback); |
2270 | 140 } |
141 | |
3072 | 142 static struct auth_request *mech_apop_auth_new(void) |
2270 | 143 { |
2736
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
144 struct apop_auth_request *request; |
2270 | 145 pool_t pool; |
146 | |
3695
4f8598b0ca62
Use a bit larger initial pool sizes
Timo Sirainen <tss@iki.fi>
parents:
3683
diff
changeset
|
147 pool = pool_alloconly_create("apop_auth_request", 1024); |
2736
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
148 request = p_new(pool, struct apop_auth_request, 1); |
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
149 request->pool = pool; |
2270 | 150 |
2736
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
151 request->auth_request.pool = pool; |
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
152 return &request->auth_request; |
2270 | 153 } |
154 | |
155 const struct mech_module mech_apop = { | |
156 "APOP", | |
157 | |
2736
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
158 MEMBER(flags) MECH_SEC_PRIVATE | MECH_SEC_DICTIONARY | MECH_SEC_ACTIVE, |
8605
84eea1977632
auth: Code cleanup for specifying what passdb features auth mechanisms need.
Timo Sirainen <tss@iki.fi>
parents:
8604
diff
changeset
|
159 MEMBER(passdb_need) MECH_PASSDB_NEED_VERIFY_RESPONSE, |
2270 | 160 |
161 mech_apop_auth_new, | |
2736
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
162 mech_apop_auth_initial, |
0f31778d3c34
Changed dovecot-auth protocol to ASCII based. Should be easier now to write
Timo Sirainen <tss@iki.fi>
parents:
2629
diff
changeset
|
163 NULL, |
4414
9017db478693
Added mech_generic_auth_internal() and mech_generic_auth_free() functions
Timo Sirainen <tss@iki.fi>
parents:
4382
diff
changeset
|
164 mech_generic_auth_free |
2270 | 165 }; |