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