xref: /3.0.2-MP2/memcached/cbsasl/plain/plain.c (revision ca4ab0ea)
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
21cbsasl_error_t plain_server_init()
22{
23    return SASL_OK;
24}
25
26cbsasl_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
33cbsasl_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
91cbsasl_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