1 /*
2  *     Copyright 2013 Couchbase, Inc.
3  *
4  *   Licensed under the Apache License, Version 2.0 (the "License");
5  *   you may not use this file except in compliance with the License.
6  *   You may obtain a copy of the License at
7  *
8  *       http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *   Unless required by applicable law or agreed to in writing, software
11  *   distributed under the License is distributed on an "AS IS" BASIS,
12  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *   See the License for the specific language governing permissions and
14  *   limitations under the License.
15  */
16 #include "plain.h"
17 #include "cbsasl/pwfile.h"
18 #include "cbsasl/util.h"
19 #include <string.h>
20 
plain_server_initnull21 cbsasl_error_t plain_server_init()
22 {
23     return SASL_OK;
24 }
25 
plain_server_start(cbsasl_conn_t *conn)26 cbsasl_error_t plain_server_start(cbsasl_conn_t *conn)
27 {
28     conn->c.server.sasl_data = NULL;
29     conn->c.server.sasl_data_len = 0;
30     return SASL_CONTINUE;
31 }
32 
plain_server_step(cbsasl_conn_t *conn, const char *input, unsigned inputlen, const char **output, unsigned *outputlen)33 cbsasl_error_t plain_server_step(cbsasl_conn_t *conn,
34                                  const char *input,
35                                  unsigned inputlen,
36                                  const char **output,
37                                  unsigned *outputlen)
38 {
39 
40     size_t inputpos = 0;
41     while (inputpos < inputlen && input[inputpos] != '\0') {
42         inputpos++;
43     }
44     inputpos++;
45 
46     if (inputpos >= inputlen) {
47         return SASL_BADPARAM;
48     }
49 
50     {
51         char *cfg = NULL;
52         size_t pwlen = 0;
53         const char *username = input + inputpos;
54         const char *password = NULL;
55         char *stored_password;
56         size_t stored_pwlen;
57         while (inputpos < inputlen && input[inputpos] != '\0') {
58             inputpos++;
59         }
60         inputpos++;
61 
62         if (inputpos > inputlen) {
63             return SASL_BADPARAM;
64         } else if (inputpos != inputlen) {
65             password = input + inputpos;
66             while (inputpos < inputlen && input[inputpos] != '\0') {
67                 inputpos++;
68                 pwlen++;
69             }
70         }
71 
72         conn->c.server.username = strdup(username);
73         if ((stored_password = find_pw(username, &cfg)) == NULL) {
74             return SASL_NOUSER;
75         }
76 
77         stored_pwlen = strlen(stored_password);
78         if (cbsasl_secure_compare(password, pwlen,
79                                   stored_password, stored_pwlen) != 0) {
80             return SASL_PWERR;
81         }
82 
83         conn->c.server.config = strdup(cfg);
84     }
85 
86     *output = NULL;
87     *outputlen = 0;
88     return SASL_OK;
89 }
90 
get_plain_mechs(void)91 cbsasl_mechs_t get_plain_mechs(void)
92 {
93     static cbsasl_mechs_t mechs = {
94         MECH_NAME_PLAIN,
95         plain_server_init,
96         plain_server_start,
97         plain_server_step
98     };
99     return mechs;
100 }
101