/src/dovecot/src/lib-sasl/sasl-server-mech-plain.c
Line | Count | Source |
1 | | /* Copyright (c) Dovecot authors, see top-level COPYING file */ |
2 | | |
3 | | #include "lib.h" |
4 | | #include "safe-memset.h" |
5 | | |
6 | | #include "sasl-server-protected.h" |
7 | | |
8 | | static void |
9 | | mech_plain_auth_continue(struct sasl_server_mech_request *request, |
10 | | const unsigned char *data, size_t data_size) |
11 | 622 | { |
12 | 622 | const char *authid, *authenid; |
13 | 622 | char *pass; |
14 | 622 | size_t i, len; |
15 | 622 | int count; |
16 | | |
17 | | /* authorization ID \0 authentication ID \0 pass. */ |
18 | 622 | authid = (const char *) data; |
19 | 622 | authenid = NULL; pass = NULL; |
20 | | |
21 | 622 | count = 0; |
22 | 216k | for (i = 0; i < data_size; i++) { |
23 | 215k | if (data[i] == '\0') { |
24 | 1.23k | if (++count == 1) |
25 | 616 | authenid = (const char *) data + i+1; |
26 | 619 | else if (count == 2) { |
27 | 615 | i++; |
28 | 615 | len = data_size - i; |
29 | 615 | pass = p_strndup(unsafe_data_stack_pool, |
30 | 615 | data+i, len); |
31 | 615 | } |
32 | 4 | else |
33 | 4 | break; |
34 | 1.23k | } |
35 | 215k | } |
36 | | |
37 | 622 | if (count == 2 && authenid != NULL && strcmp(authid, authenid) == 0) { |
38 | | /* the login username isn't different */ |
39 | 1 | authid = ""; |
40 | 1 | } |
41 | | |
42 | 622 | if (count != 2) { |
43 | | /* invalid input */ |
44 | 11 | e_info(request->event, "invalid input"); |
45 | 11 | sasl_server_request_failure(request); |
46 | 611 | } else if (!sasl_server_request_set_authid( |
47 | 611 | request, SASL_SERVER_AUTHID_TYPE_USERNAME, authenid)) { |
48 | | /* invalid username */ |
49 | 2 | sasl_server_request_failure(request); |
50 | 609 | } else if (*authid != '\0' && |
51 | 369 | !sasl_server_request_set_authzid(request, authid)) { |
52 | | /* invalid login username */ |
53 | 10 | sasl_server_request_failure(request); |
54 | 599 | } else { |
55 | 599 | sasl_server_request_verify_plain( |
56 | 599 | request, pass, sasl_server_mech_plain_verify_callback); |
57 | 599 | } |
58 | | |
59 | | /* make sure it's cleared */ |
60 | 622 | if (pass != NULL) |
61 | 615 | safe_memset(pass, 0, strlen(pass)); |
62 | 622 | } |
63 | | |
64 | | static const struct sasl_server_mech_funcs mech_plain_funcs = { |
65 | | .auth_initial = sasl_server_mech_generic_auth_initial, |
66 | | .auth_continue = mech_plain_auth_continue, |
67 | | }; |
68 | | |
69 | | static const struct sasl_server_mech_def mech_plain = { |
70 | | .name = SASL_MECH_NAME_PLAIN, |
71 | | |
72 | | .flags = SASL_MECH_SEC_PLAINTEXT | SASL_MECH_SEC_ALLOW_NULS, |
73 | | .passdb_need = SASL_MECH_PASSDB_NEED_VERIFY_PLAIN, |
74 | | |
75 | | .funcs = &mech_plain_funcs, |
76 | | }; |
77 | | |
78 | | void sasl_server_mech_register_plain(struct sasl_server_instance *sinst) |
79 | 8.27k | { |
80 | 8.27k | sasl_server_mech_register(sinst, &mech_plain, NULL); |
81 | 8.27k | } |