/src/dovecot/src/lib-sasl/sasl-server-mech-plain.c
Line | Count | Source |
1 | | /* Copyright (c) 2002-2018 Dovecot authors, see the included 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 | 607 | { |
12 | 607 | const char *authid, *authenid; |
13 | 607 | char *pass; |
14 | 607 | size_t i, len; |
15 | 607 | int count; |
16 | | |
17 | | /* authorization ID \0 authentication ID \0 pass. */ |
18 | 607 | authid = (const char *) data; |
19 | 607 | authenid = NULL; pass = NULL; |
20 | | |
21 | 607 | count = 0; |
22 | 45.0k | for (i = 0; i < data_size; i++) { |
23 | 44.4k | if (data[i] == '\0') { |
24 | 1.20k | if (++count == 1) |
25 | 601 | authenid = (const char *) data + i+1; |
26 | 604 | else if (count == 2) { |
27 | 599 | i++; |
28 | 599 | len = data_size - i; |
29 | 599 | pass = p_strndup(unsafe_data_stack_pool, |
30 | 599 | data+i, len); |
31 | 599 | } |
32 | 5 | else |
33 | 5 | break; |
34 | 1.20k | } |
35 | 44.4k | } |
36 | | |
37 | 607 | if (count == 2 && authenid != NULL && strcmp(authid, authenid) == 0) { |
38 | | /* the login username isn't different */ |
39 | 1 | authid = ""; |
40 | 1 | } |
41 | | |
42 | 607 | if (count != 2) { |
43 | | /* invalid input */ |
44 | 13 | e_info(request->event, "invalid input"); |
45 | 13 | sasl_server_request_failure(request); |
46 | 594 | } else if (!sasl_server_request_set_authid( |
47 | 594 | request, SASL_SERVER_AUTHID_TYPE_USERNAME, authenid)) { |
48 | | /* invalid username */ |
49 | 2 | sasl_server_request_failure(request); |
50 | 592 | } else if (*authid != '\0' && |
51 | 364 | !sasl_server_request_set_authzid(request, authid)) { |
52 | | /* invalid login username */ |
53 | 2 | sasl_server_request_failure(request); |
54 | 590 | } else { |
55 | 590 | sasl_server_request_verify_plain( |
56 | 590 | request, pass, sasl_server_mech_plain_verify_callback); |
57 | 590 | } |
58 | | |
59 | | /* make sure it's cleared */ |
60 | 607 | if (pass != NULL) |
61 | 599 | safe_memset(pass, 0, strlen(pass)); |
62 | 607 | } |
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.34k | { |
80 | 8.34k | sasl_server_mech_register(sinst, &mech_plain, NULL); |
81 | 8.34k | } |