libcouchbase 1.2.8 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +4 -4
- data/README.md +16 -8
- data/ext/libcouchbase/CMakeLists.txt +34 -32
- data/ext/libcouchbase/RELEASE_NOTES.markdown +277 -6
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +14 -0
- data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibevent.cmake +2 -0
- data/ext/libcouchbase/cmake/Modules/FindCouchbaseLibuv.cmake +2 -1
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -0
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +8 -1
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +14 -0
- data/ext/libcouchbase/cmake/configure +8 -26
- data/ext/libcouchbase/cmake/defs.mk.in +2 -2
- data/ext/libcouchbase/cmake/libcouchbase.stp.in +829 -0
- data/ext/libcouchbase/cmake/source_files.cmake +11 -2
- data/ext/libcouchbase/contrib/cbsasl/CMakeLists.txt +18 -2
- data/ext/libcouchbase/contrib/cbsasl/include/cbsasl/cbsasl.h +44 -2
- data/ext/libcouchbase/contrib/cbsasl/src/client.c +285 -73
- data/ext/libcouchbase/contrib/cbsasl/src/common.c +4 -0
- data/ext/libcouchbase/contrib/cbsasl/src/scram-sha/scram_utils.c +500 -0
- data/ext/libcouchbase/contrib/cbsasl/src/scram-sha/scram_utils.h +99 -0
- data/ext/libcouchbase/contrib/cliopts/CMakeLists.txt +1 -1
- data/ext/libcouchbase/contrib/cliopts/cliopts.h +14 -1
- data/ext/libcouchbase/contrib/snappy/CMakeLists.txt +2 -3
- data/ext/libcouchbase/contrib/snappy/snappy-sinksource.cc +4 -0
- data/ext/libcouchbase/contrib/snappy/snappy-stubs-public.h +7 -5
- data/ext/libcouchbase/contrib/snappy/snappy.cc +7 -2
- data/ext/libcouchbase/example/crypto/.gitignore +2 -0
- data/ext/libcouchbase/example/crypto/Makefile +13 -0
- data/ext/libcouchbase/example/crypto/common_provider.c +24 -0
- data/ext/libcouchbase/example/crypto/common_provider.h +31 -0
- data/ext/libcouchbase/example/crypto/openssl_symmetric_decrypt.c +139 -0
- data/ext/libcouchbase/example/crypto/openssl_symmetric_encrypt.c +147 -0
- data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.c +281 -0
- data/ext/libcouchbase/example/crypto/openssl_symmetric_provider.h +29 -0
- data/ext/libcouchbase/example/tracing/.gitignore +2 -0
- data/ext/libcouchbase/example/tracing/Makefile +8 -0
- data/ext/libcouchbase/example/tracing/cJSON.c +1 -0
- data/ext/libcouchbase/example/tracing/cJSON.h +1 -0
- data/ext/libcouchbase/example/tracing/tracing.c +439 -0
- data/ext/libcouchbase/example/tracing/views.c +444 -0
- data/ext/libcouchbase/include/libcouchbase/auth.h +56 -4
- data/ext/libcouchbase/include/libcouchbase/cbft.h +8 -0
- data/ext/libcouchbase/include/libcouchbase/cntl-private.h +55 -1
- data/ext/libcouchbase/include/libcouchbase/cntl.h +101 -1
- data/ext/libcouchbase/include/libcouchbase/configuration.h.in +6 -0
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +109 -6
- data/ext/libcouchbase/include/libcouchbase/crypto.h +140 -0
- data/ext/libcouchbase/include/libcouchbase/error.h +38 -2
- data/ext/libcouchbase/include/libcouchbase/kvbuf.h +6 -1
- data/ext/libcouchbase/include/libcouchbase/metrics.h +79 -0
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +9 -0
- data/ext/libcouchbase/include/libcouchbase/tracing.h +319 -0
- data/ext/libcouchbase/include/libcouchbase/vbucket.h +1 -1
- data/ext/libcouchbase/include/libcouchbase/views.h +8 -0
- data/ext/libcouchbase/include/memcached/protocol_binary.h +40 -10
- data/ext/libcouchbase/packaging/rpm/libcouchbase.spec.in +6 -14
- data/ext/libcouchbase/plugins/io/libuv/plugin-internal.h +3 -0
- data/ext/libcouchbase/plugins/io/libuv/plugin-libuv.c +1 -0
- data/ext/libcouchbase/plugins/io/select/plugin-select.c +4 -1
- data/ext/libcouchbase/src/auth-priv.h +36 -4
- data/ext/libcouchbase/src/auth.cc +66 -27
- data/ext/libcouchbase/src/bootstrap.cc +1 -1
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +12 -7
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +26 -17
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +1 -1
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +4 -2
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +6 -3
- data/ext/libcouchbase/src/cbft.cc +48 -0
- data/ext/libcouchbase/src/cntl.cc +138 -2
- data/ext/libcouchbase/src/config_static.h +17 -0
- data/ext/libcouchbase/src/connspec.cc +54 -6
- data/ext/libcouchbase/src/connspec.h +9 -1
- data/ext/libcouchbase/src/crypto.cc +386 -0
- data/ext/libcouchbase/src/ctx-log-inl.h +23 -6
- data/ext/libcouchbase/src/dump.cc +4 -0
- data/ext/libcouchbase/src/getconfig.cc +1 -2
- data/ext/libcouchbase/src/handler.cc +65 -27
- data/ext/libcouchbase/src/hostlist.cc +35 -7
- data/ext/libcouchbase/src/hostlist.h +7 -0
- data/ext/libcouchbase/src/http/http-priv.h +2 -0
- data/ext/libcouchbase/src/http/http.cc +77 -37
- data/ext/libcouchbase/src/http/http_io.cc +19 -2
- data/ext/libcouchbase/src/instance.cc +90 -17
- data/ext/libcouchbase/src/internal.h +5 -0
- data/ext/libcouchbase/src/lcbio/connect.cc +39 -4
- data/ext/libcouchbase/src/lcbio/connect.h +27 -0
- data/ext/libcouchbase/src/lcbio/ctx.c +49 -23
- data/ext/libcouchbase/src/lcbio/ioutils.cc +30 -3
- data/ext/libcouchbase/src/lcbio/ioutils.h +2 -0
- data/ext/libcouchbase/src/lcbio/manager.cc +44 -8
- data/ext/libcouchbase/src/lcbio/manager.h +2 -0
- data/ext/libcouchbase/src/lcbio/rw-inl.h +1 -0
- data/ext/libcouchbase/src/lcbio/ssl.h +3 -5
- data/ext/libcouchbase/src/logging.c +1 -1
- data/ext/libcouchbase/src/logging.h +2 -0
- data/ext/libcouchbase/src/mc/compress.cc +164 -0
- data/ext/libcouchbase/src/mc/compress.h +7 -12
- data/ext/libcouchbase/src/mc/mcreq-flush-inl.h +5 -1
- data/ext/libcouchbase/src/mc/mcreq.c +11 -1
- data/ext/libcouchbase/src/mc/mcreq.h +35 -4
- data/ext/libcouchbase/src/mcserver/mcserver.cc +30 -7
- data/ext/libcouchbase/src/mcserver/mcserver.h +7 -0
- data/ext/libcouchbase/src/mcserver/negotiate.cc +103 -57
- data/ext/libcouchbase/src/mcserver/negotiate.h +2 -2
- data/ext/libcouchbase/src/mctx-helper.h +11 -0
- data/ext/libcouchbase/src/metrics.cc +132 -0
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +2 -1
- data/ext/libcouchbase/src/n1ql/n1ql.cc +66 -0
- data/ext/libcouchbase/src/newconfig.cc +9 -2
- data/ext/libcouchbase/src/operations/counter.cc +2 -1
- data/ext/libcouchbase/src/operations/durability-cas.cc +11 -0
- data/ext/libcouchbase/src/operations/durability-seqno.cc +3 -0
- data/ext/libcouchbase/src/operations/durability.cc +24 -2
- data/ext/libcouchbase/src/operations/durability_internal.h +19 -0
- data/ext/libcouchbase/src/operations/get.cc +4 -2
- data/ext/libcouchbase/src/operations/observe-seqno.cc +1 -0
- data/ext/libcouchbase/src/operations/observe.cc +113 -62
- data/ext/libcouchbase/src/operations/ping.cc +246 -67
- data/ext/libcouchbase/src/operations/remove.cc +2 -1
- data/ext/libcouchbase/src/operations/store.cc +17 -14
- data/ext/libcouchbase/src/operations/touch.cc +3 -0
- data/ext/libcouchbase/src/packetutils.h +68 -4
- data/ext/libcouchbase/src/probes.d +132 -161
- data/ext/libcouchbase/src/rdb/bigalloc.c +1 -1
- data/ext/libcouchbase/src/retryq.cc +6 -2
- data/ext/libcouchbase/src/rnd.cc +68 -0
- data/ext/libcouchbase/src/rnd.h +39 -0
- data/ext/libcouchbase/src/settings.c +27 -0
- data/ext/libcouchbase/src/settings.h +67 -3
- data/ext/libcouchbase/src/ssl/CMakeLists.txt +0 -12
- data/ext/libcouchbase/src/ssl/ssl_common.c +23 -4
- data/ext/libcouchbase/src/strcodecs/base64.c +141 -16
- data/ext/libcouchbase/src/strcodecs/strcodecs.h +16 -1
- data/ext/libcouchbase/src/trace.h +68 -61
- data/ext/libcouchbase/src/tracing/span.cc +289 -0
- data/ext/libcouchbase/src/tracing/threshold_logging_tracer.cc +171 -0
- data/ext/libcouchbase/src/tracing/tracer.cc +53 -0
- data/ext/libcouchbase/src/tracing/tracing-internal.h +213 -0
- data/ext/libcouchbase/src/utilities.c +5 -0
- data/ext/libcouchbase/src/vbucket/CMakeLists.txt +2 -2
- data/ext/libcouchbase/src/vbucket/vbucket.c +50 -18
- data/ext/libcouchbase/src/views/docreq.cc +26 -1
- data/ext/libcouchbase/src/views/docreq.h +17 -0
- data/ext/libcouchbase/src/views/viewreq.cc +64 -1
- data/ext/libcouchbase/src/views/viewreq.h +21 -0
- data/ext/libcouchbase/tests/CMakeLists.txt +6 -6
- data/ext/libcouchbase/tests/basic/t_base64.cc +34 -6
- data/ext/libcouchbase/tests/basic/t_connstr.cc +14 -0
- data/ext/libcouchbase/tests/basic/t_creds.cc +10 -10
- data/ext/libcouchbase/tests/basic/t_host.cc +22 -2
- data/ext/libcouchbase/tests/basic/t_scram.cc +514 -0
- data/ext/libcouchbase/tests/check-all.cc +6 -2
- data/ext/libcouchbase/tests/iotests/mock-environment.cc +64 -0
- data/ext/libcouchbase/tests/iotests/mock-environment.h +27 -1
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +2 -2
- data/ext/libcouchbase/tests/iotests/t_forward.cc +8 -0
- data/ext/libcouchbase/tests/iotests/t_netfail.cc +124 -0
- data/ext/libcouchbase/tests/iotests/t_smoke.cc +1 -1
- data/ext/libcouchbase/tests/iotests/t_snappy.cc +316 -0
- data/ext/libcouchbase/tests/socktests/socktest.cc +2 -2
- data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
- data/ext/libcouchbase/tests/socktests/t_manager.cc +1 -1
- data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
- data/ext/libcouchbase/tools/CMakeLists.txt +1 -1
- data/ext/libcouchbase/tools/cbc-handlers.h +17 -0
- data/ext/libcouchbase/tools/cbc-n1qlback.cc +7 -4
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +408 -100
- data/ext/libcouchbase/tools/cbc-proxy.cc +134 -3
- data/ext/libcouchbase/tools/cbc-subdoc.cc +1 -2
- data/ext/libcouchbase/tools/cbc.cc +113 -8
- data/ext/libcouchbase/tools/common/histogram.cc +1 -0
- data/ext/libcouchbase/tools/common/options.cc +28 -1
- data/ext/libcouchbase/tools/common/options.h +5 -0
- data/ext/libcouchbase/tools/docgen/docgen.h +36 -10
- data/ext/libcouchbase/tools/docgen/loc.h +5 -4
- data/ext/libcouchbase/tools/docgen/seqgen.h +28 -0
- data/lib/libcouchbase/ext/libcouchbase/enums.rb +10 -0
- data/lib/libcouchbase/n1ql.rb +6 -1
- data/lib/libcouchbase/version.rb +1 -1
- data/spec/connection_spec.rb +6 -6
- metadata +38 -5
- data/ext/libcouchbase/cmake/Modules/FindCouchbaseSnappy.cmake +0 -11
- data/ext/libcouchbase/src/mc/compress.c +0 -90
- data/ext/libcouchbase/tools/common/my_inttypes.h +0 -22
|
@@ -21,6 +21,7 @@ FILE(GLOB LCB_OP_SRC src/operations/*.c)
|
|
|
21
21
|
|
|
22
22
|
# memcached packets
|
|
23
23
|
FILE(GLOB LCB_MC_SRC src/mc/*.c)
|
|
24
|
+
FILE(GLOB LCB_MC_CXXSRC src/mc/*.cc)
|
|
24
25
|
|
|
25
26
|
# read buffer management
|
|
26
27
|
FILE(GLOB LCB_RDB_SRC src/rdb/*.c)
|
|
@@ -40,11 +41,14 @@ SET(LCB_CORE_SRC
|
|
|
40
41
|
${LCB_N1QL_SRC}
|
|
41
42
|
src/callbacks.c
|
|
42
43
|
src/legacy.c
|
|
43
|
-
# src/mcserver/negotiate.c
|
|
44
44
|
src/iofactory.c
|
|
45
45
|
src/settings.c
|
|
46
46
|
src/utilities.c)
|
|
47
47
|
|
|
48
|
+
IF (LCB_TRACING)
|
|
49
|
+
FILE(GLOB LCB_TRACING_SRC src/tracing/*.cc)
|
|
50
|
+
ENDIF()
|
|
51
|
+
|
|
48
52
|
SET(LCB_CORE_CXXSRC
|
|
49
53
|
src/instance.cc
|
|
50
54
|
src/auth.cc
|
|
@@ -55,6 +59,7 @@ SET(LCB_CORE_CXXSRC
|
|
|
55
59
|
src/bucketconfig/bc_static.cc
|
|
56
60
|
src/bucketconfig/confmon.cc
|
|
57
61
|
src/connspec.cc
|
|
62
|
+
src/crypto.cc
|
|
58
63
|
src/dns-srv.cc
|
|
59
64
|
src/dump.cc
|
|
60
65
|
src/errmap.cc
|
|
@@ -87,9 +92,13 @@ SET(LCB_CORE_CXXSRC
|
|
|
87
92
|
src/operations/ping.cc
|
|
88
93
|
src/mcserver/mcserver.cc
|
|
89
94
|
src/mcserver/negotiate.cc
|
|
95
|
+
src/metrics.cc
|
|
90
96
|
src/retrychk.cc
|
|
91
97
|
src/retryq.cc
|
|
98
|
+
src/rnd.cc
|
|
92
99
|
src/views/docreq.cc
|
|
93
100
|
src/views/viewreq.cc
|
|
94
101
|
src/cntl.cc
|
|
95
|
-
src/wait.cc
|
|
102
|
+
src/wait.cc
|
|
103
|
+
${LCB_TRACING_SRC}
|
|
104
|
+
)
|
|
@@ -1,9 +1,25 @@
|
|
|
1
|
+
INCLUDE (CheckCSourceCompiles)
|
|
1
2
|
INCLUDE_DIRECTORIES(src)
|
|
2
3
|
FILE(GLOB CBSASL_SRC src/*.c)
|
|
3
4
|
FILE(GLOB CRAM_SRC src/cram-md5/*.c)
|
|
5
|
+
FILE(GLOB SCRAM_SRC src/scram-sha/*.c)
|
|
4
6
|
|
|
5
|
-
ADD_LIBRARY(cbsasl OBJECT ${CBSASL_SRC} ${CRAM_SRC})
|
|
6
|
-
SET_TARGET_PROPERTIES(cbsasl
|
|
7
|
+
ADD_LIBRARY(cbsasl-lcb OBJECT ${CBSASL_SRC} ${CRAM_SRC} ${SCRAM_SRC})
|
|
8
|
+
SET_TARGET_PROPERTIES(cbsasl-lcb
|
|
7
9
|
PROPERTIES
|
|
8
10
|
POSITION_INDEPENDENT_CODE TRUE
|
|
9
11
|
COMPILE_FLAGS "${LCB_CORE_CFLAGS}")
|
|
12
|
+
|
|
13
|
+
IF(OPENSSL_FOUND AND (NOT LCB_NO_SSL))
|
|
14
|
+
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
|
|
15
|
+
ADD_DEFINITIONS(${OPENSSL_DEFINITIONS})
|
|
16
|
+
# Check if the system have a usable version of PKCS5_PBKDF2_HMAC
|
|
17
|
+
CMAKE_PUSH_CHECK_STATE(RESET)
|
|
18
|
+
SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${OPENSSL_LIBRARIES})
|
|
19
|
+
SET(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${OPENSSL_INCLUDE_DIR})
|
|
20
|
+
CHECK_C_SOURCE_COMPILES("
|
|
21
|
+
#include <openssl/evp.h>
|
|
22
|
+
int main() {
|
|
23
|
+
PKCS5_PBKDF2_HMAC(NULL, 0, NULL, 0, 0, NULL, 0, NULL);
|
|
24
|
+
}" HAVE_PKCS5_PBKDF2_HMAC)
|
|
25
|
+
ENDIF()
|
|
@@ -22,6 +22,19 @@
|
|
|
22
22
|
extern "C" {
|
|
23
23
|
#endif
|
|
24
24
|
|
|
25
|
+
#define MECH_PLAIN "PLAIN"
|
|
26
|
+
#define MECH_CRAM_MD5 "CRAM-MD5"
|
|
27
|
+
#define MECH_SCRAM_SHA1 "SCRAM-SHA1"
|
|
28
|
+
#define MECH_SCRAM_SHA256 "SCRAM-SHA256"
|
|
29
|
+
#define MECH_SCRAM_SHA512 "SCRAM-SHA512"
|
|
30
|
+
|
|
31
|
+
// size in bytes - to double if the nonce is displayed in hexadecimal
|
|
32
|
+
#define SCRAM_NONCE_SIZE 8
|
|
33
|
+
|
|
34
|
+
#define CBSASL_SHA1_DIGEST_SIZE 20
|
|
35
|
+
#define CBSASL_SHA256_DIGEST_SIZE 32
|
|
36
|
+
#define CBSASL_SHA512_DIGEST_SIZE 64
|
|
37
|
+
|
|
25
38
|
typedef enum cbsasl_error {
|
|
26
39
|
SASL_OK,
|
|
27
40
|
SASL_CONTINUE,
|
|
@@ -33,6 +46,15 @@ extern "C" {
|
|
|
33
46
|
}
|
|
34
47
|
cbsasl_error_t;
|
|
35
48
|
|
|
49
|
+
typedef enum cbsasl_auth_mechanism {
|
|
50
|
+
SASL_AUTH_MECH_PLAIN,
|
|
51
|
+
SASL_AUTH_MECH_CRAM_MD5, // deprecated
|
|
52
|
+
SASL_AUTH_MECH_SCRAM_SHA1,
|
|
53
|
+
SASL_AUTH_MECH_SCRAM_SHA256,
|
|
54
|
+
SASL_AUTH_MECH_SCRAM_SHA512
|
|
55
|
+
}
|
|
56
|
+
cbsasl_auth_mechanism_t;
|
|
57
|
+
|
|
36
58
|
typedef struct {
|
|
37
59
|
unsigned long len;
|
|
38
60
|
unsigned char data[1];
|
|
@@ -60,13 +82,18 @@ extern "C" {
|
|
|
60
82
|
|
|
61
83
|
struct cbsasl_client_conn_t {
|
|
62
84
|
char *userdata;
|
|
63
|
-
|
|
85
|
+
cbsasl_auth_mechanism_t auth_mech; // authentication mechanism
|
|
64
86
|
int (*get_username)(void *context, int id, const char **result,
|
|
65
87
|
unsigned int *len);
|
|
66
88
|
void *get_username_ctx;
|
|
67
89
|
int (*get_password)(cbsasl_conn_t *conn, void *context, int id,
|
|
68
90
|
cbsasl_secret_t **psecret);
|
|
69
91
|
void *get_password_ctx;
|
|
92
|
+
char *nonce; // client nonce for SCRAM-SHA authentication
|
|
93
|
+
char *client_first_message_bare; // for SCRAM-SHA authentication
|
|
94
|
+
unsigned char *saltedpassword; // for SCRAM-SHA authentication
|
|
95
|
+
unsigned int saltedpasslen; // length of the salted password field
|
|
96
|
+
char *auth_message; // for SCRAM-SHA authentication
|
|
70
97
|
};
|
|
71
98
|
|
|
72
99
|
struct cbsasl_server_conn_t {
|
|
@@ -143,6 +170,20 @@ extern "C" {
|
|
|
143
170
|
const char **output,
|
|
144
171
|
unsigned *outputlen);
|
|
145
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Final authentication step, if need to be (depending on the mechanism).
|
|
175
|
+
*
|
|
176
|
+
* This is mainly use for SCRAM-SHA authentication family, to verify the
|
|
177
|
+
* server signature. Even if the server accepted the authentication, if
|
|
178
|
+
* we can't verify its signature, we must reject the connection.
|
|
179
|
+
*
|
|
180
|
+
* @return Whether or not the sasl check was successful
|
|
181
|
+
*/
|
|
182
|
+
CBSASL_PUBLIC_API
|
|
183
|
+
cbsasl_error_t cbsasl_client_check(cbsasl_conn_t *conn,
|
|
184
|
+
const char *input,
|
|
185
|
+
unsigned int inputlen);
|
|
186
|
+
|
|
146
187
|
/**
|
|
147
188
|
* Frees up funushed sasl connections
|
|
148
189
|
*
|
|
@@ -199,7 +240,8 @@ extern "C" {
|
|
|
199
240
|
void **prompt_need,
|
|
200
241
|
const char **clientout,
|
|
201
242
|
unsigned int *clientoutlen,
|
|
202
|
-
const char **mech
|
|
243
|
+
const char **mech,
|
|
244
|
+
int allow_scram_sha);
|
|
203
245
|
|
|
204
246
|
CBSASL_PUBLIC_API
|
|
205
247
|
cbsasl_error_t cbsasl_client_step(cbsasl_conn_t *conn,
|
|
@@ -14,24 +14,23 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
#include "config.h"
|
|
17
18
|
#include "cbsasl/cbsasl.h"
|
|
18
19
|
#include "cram-md5/hmac.h"
|
|
20
|
+
#include "scram-sha/scram_utils.h"
|
|
19
21
|
#include "util.h"
|
|
20
22
|
#include <time.h>
|
|
21
23
|
#include <stdlib.h>
|
|
22
24
|
#include <string.h>
|
|
25
|
+
#include <stdio.h>
|
|
23
26
|
|
|
24
27
|
CBSASL_PUBLIC_API
|
|
25
|
-
cbsasl_error_t cbsasl_client_new(const char *service,
|
|
26
|
-
const char *
|
|
27
|
-
const char *iplocalport,
|
|
28
|
-
const char *ipremoteport,
|
|
29
|
-
const cbsasl_callback_t *prompt_supp,
|
|
30
|
-
unsigned flags,
|
|
28
|
+
cbsasl_error_t cbsasl_client_new(const char *service, const char *serverFQDN, const char *iplocalport,
|
|
29
|
+
const char *ipremoteport, const cbsasl_callback_t *prompt_supp, unsigned flags,
|
|
31
30
|
cbsasl_conn_t **pconn)
|
|
32
31
|
{
|
|
33
32
|
cbsasl_conn_t *conn;
|
|
34
|
-
cbsasl_callback_t *callbacks = (cbsasl_callback_t*)prompt_supp;
|
|
33
|
+
cbsasl_callback_t *callbacks = (cbsasl_callback_t *)prompt_supp;
|
|
35
34
|
int ii;
|
|
36
35
|
|
|
37
36
|
if (prompt_supp == NULL) {
|
|
@@ -85,63 +84,138 @@ cbsasl_error_t cbsasl_client_new(const char *service,
|
|
|
85
84
|
}
|
|
86
85
|
|
|
87
86
|
CBSASL_PUBLIC_API
|
|
88
|
-
cbsasl_error_t cbsasl_client_start(cbsasl_conn_t *conn,
|
|
89
|
-
const char *
|
|
90
|
-
|
|
91
|
-
const char **clientout,
|
|
92
|
-
unsigned int *clientoutlen,
|
|
93
|
-
const char **mech)
|
|
87
|
+
cbsasl_error_t cbsasl_client_start(cbsasl_conn_t *conn, const char *mechlist, void **prompt_need,
|
|
88
|
+
const char **clientout, unsigned int *clientoutlen, const char **mech,
|
|
89
|
+
int allow_scram_sha)
|
|
94
90
|
{
|
|
95
91
|
if (conn->client == 0) {
|
|
96
92
|
return SASL_BADPARAM;
|
|
97
93
|
}
|
|
98
94
|
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
*mech = NULL;
|
|
96
|
+
if (allow_scram_sha) {
|
|
97
|
+
#if !defined(LCB_NO_SSL) && defined(HAVE_PKCS5_PBKDF2_HMAC)
|
|
98
|
+
// we use SCRAM-SHA only if OpenSSL is linked and has support for PBKDF2_HMAC functions
|
|
99
|
+
if (strstr(mechlist, MECH_SCRAM_SHA512) != NULL) {
|
|
100
|
+
*mech = MECH_SCRAM_SHA512;
|
|
101
|
+
conn->c.client.auth_mech = SASL_AUTH_MECH_SCRAM_SHA512;
|
|
102
|
+
} else if (strstr(mechlist, MECH_SCRAM_SHA256) != NULL) {
|
|
103
|
+
*mech = MECH_SCRAM_SHA256;
|
|
104
|
+
conn->c.client.auth_mech = SASL_AUTH_MECH_SCRAM_SHA256;
|
|
105
|
+
} else if (strstr(mechlist, MECH_SCRAM_SHA1) != NULL) {
|
|
106
|
+
*mech = MECH_SCRAM_SHA1;
|
|
107
|
+
conn->c.client.auth_mech = SASL_AUTH_MECH_SCRAM_SHA1;
|
|
108
|
+
}
|
|
109
|
+
#endif
|
|
110
|
+
}
|
|
111
|
+
if (*mech == NULL) {
|
|
112
|
+
if (strstr(mechlist, MECH_CRAM_MD5) != NULL) {
|
|
113
|
+
*mech = MECH_CRAM_MD5;
|
|
114
|
+
conn->c.client.auth_mech = SASL_AUTH_MECH_CRAM_MD5;
|
|
115
|
+
} else if (strstr(mechlist, MECH_PLAIN) != NULL) {
|
|
116
|
+
*mech = MECH_PLAIN;
|
|
117
|
+
conn->c.client.auth_mech = SASL_AUTH_MECH_PLAIN;
|
|
118
|
+
} else {
|
|
101
119
|
return SASL_NOMECH;
|
|
102
120
|
}
|
|
103
|
-
|
|
104
|
-
*mech = "PLAIN";
|
|
105
|
-
conn->c.client.plain = 1;
|
|
106
|
-
} else {
|
|
107
|
-
*mech = "CRAM-MD5";
|
|
108
|
-
conn->c.client.plain = 0;
|
|
109
121
|
}
|
|
110
122
|
|
|
123
|
+
switch (conn->c.client.auth_mech) {
|
|
124
|
+
case SASL_AUTH_MECH_PLAIN: {
|
|
125
|
+
const char *usernm = NULL;
|
|
126
|
+
unsigned int usernmlen;
|
|
127
|
+
cbsasl_secret_t *pass;
|
|
128
|
+
cbsasl_error_t ret;
|
|
111
129
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
130
|
+
ret = conn->c.client.get_username(conn->c.client.get_username_ctx, CBSASL_CB_USER, &usernm, &usernmlen);
|
|
131
|
+
if (ret != SASL_OK) {
|
|
132
|
+
return ret;
|
|
133
|
+
}
|
|
116
134
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (ret != SASL_OK) {
|
|
122
|
-
return ret;
|
|
123
|
-
}
|
|
135
|
+
ret = conn->c.client.get_password(conn, conn->c.client.get_password_ctx, CBSASL_CB_PASS, &pass);
|
|
136
|
+
if (ret != SASL_OK) {
|
|
137
|
+
return ret;
|
|
138
|
+
}
|
|
124
139
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return ret;
|
|
130
|
-
}
|
|
140
|
+
conn->c.client.userdata = calloc(usernmlen + 1 + pass->len + 1, 1);
|
|
141
|
+
if (conn->c.client.userdata == NULL) {
|
|
142
|
+
return SASL_NOMEM;
|
|
143
|
+
}
|
|
131
144
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
145
|
+
memcpy(conn->c.client.userdata + 1, usernm, usernmlen);
|
|
146
|
+
memcpy(conn->c.client.userdata + usernmlen + 2, pass->data, pass->len);
|
|
147
|
+
*clientout = conn->c.client.userdata;
|
|
148
|
+
*clientoutlen = (unsigned int)(usernmlen + 2 + pass->len);
|
|
149
|
+
break;
|
|
135
150
|
}
|
|
151
|
+
case SASL_AUTH_MECH_SCRAM_SHA1:
|
|
152
|
+
case SASL_AUTH_MECH_SCRAM_SHA256:
|
|
153
|
+
case SASL_AUTH_MECH_SCRAM_SHA512: {
|
|
154
|
+
const char *usernm = NULL;
|
|
155
|
+
unsigned int usernmlen;
|
|
156
|
+
int usernmspeccharsnb;
|
|
157
|
+
char binnonce[SCRAM_NONCE_SIZE]; // binary nonce
|
|
158
|
+
cbsasl_error_t ret;
|
|
159
|
+
|
|
160
|
+
ret = conn->c.client.get_username(conn->c.client.get_username_ctx, CBSASL_CB_USER, &usernm, &usernmlen);
|
|
161
|
+
if (ret != SASL_OK) {
|
|
162
|
+
return ret;
|
|
163
|
+
}
|
|
164
|
+
usernmspeccharsnb = compute_special_chars(usernm, usernmlen);
|
|
165
|
+
if (usernmspeccharsnb < 0) {
|
|
166
|
+
// invalid characters in the username
|
|
167
|
+
return SASL_BADPARAM;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
generate_nonce(binnonce, SCRAM_NONCE_SIZE);
|
|
171
|
+
conn->c.client.nonce = calloc(SCRAM_NONCE_SIZE * 2 + 1, 1);
|
|
172
|
+
if (conn->c.client.nonce == NULL) {
|
|
173
|
+
return SASL_NOMEM;
|
|
174
|
+
}
|
|
175
|
+
// stores binary nonce in hexadecimal format into conn->c.client.nonce array
|
|
176
|
+
cbsasl_hex_encode(conn->c.client.nonce, binnonce, SCRAM_NONCE_SIZE);
|
|
177
|
+
conn->c.client.nonce[SCRAM_NONCE_SIZE * 2] = '\0';
|
|
136
178
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
179
|
+
#define GS2_HEADER "n,,n=" // "no binding" + start of name attribute
|
|
180
|
+
#define NONCE_ATTR ",r=" // start of nonce attribute
|
|
181
|
+
conn->c.client.userdata = calloc(
|
|
182
|
+
strlen(GS2_HEADER) + usernmlen + usernmspeccharsnb * 2 + strlen(NONCE_ATTR) + SCRAM_NONCE_SIZE * 2, 1);
|
|
183
|
+
if (conn->c.client.userdata == NULL) {
|
|
184
|
+
return SASL_NOMEM;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
memcpy(conn->c.client.userdata, GS2_HEADER, strlen(GS2_HEADER));
|
|
188
|
+
if (!usernmspeccharsnb) {
|
|
189
|
+
// no special char, we can do a direct copy
|
|
190
|
+
memcpy(conn->c.client.userdata + strlen(GS2_HEADER), usernm, usernmlen);
|
|
191
|
+
} else {
|
|
192
|
+
// copy with substitution of special characters
|
|
193
|
+
usernmcpy(conn->c.client.userdata + strlen(GS2_HEADER), usernm, usernmlen);
|
|
194
|
+
}
|
|
195
|
+
memcpy(conn->c.client.userdata + strlen(GS2_HEADER) + usernmlen + usernmspeccharsnb * 2, NONCE_ATTR,
|
|
196
|
+
strlen(NONCE_ATTR));
|
|
197
|
+
memcpy(conn->c.client.userdata + strlen(GS2_HEADER) + usernmlen + usernmspeccharsnb * 2 +
|
|
198
|
+
strlen(NONCE_ATTR),
|
|
199
|
+
conn->c.client.nonce, SCRAM_NONCE_SIZE * 2);
|
|
200
|
+
|
|
201
|
+
*clientout = conn->c.client.userdata;
|
|
202
|
+
*clientoutlen = (unsigned int)(strlen(GS2_HEADER) + usernmlen + usernmspeccharsnb * 2 + strlen(NONCE_ATTR) +
|
|
203
|
+
SCRAM_NONCE_SIZE * 2);
|
|
204
|
+
|
|
205
|
+
// save the client first message for later step (without the first three characters)
|
|
206
|
+
conn->c.client.client_first_message_bare = calloc(*clientoutlen - 3 + 1, 1); // +1 for the binary zero
|
|
207
|
+
if (conn->c.client.client_first_message_bare == NULL) {
|
|
208
|
+
return SASL_NOMEM;
|
|
209
|
+
}
|
|
210
|
+
memcpy(conn->c.client.client_first_message_bare, *clientout + 3, *clientoutlen - 3);
|
|
211
|
+
// no need to add a final binary zero, as calloc already sets the memory to zero
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
case SASL_AUTH_MECH_CRAM_MD5:
|
|
215
|
+
// no data in the first CRAM-MD5 message
|
|
216
|
+
*clientout = NULL;
|
|
217
|
+
*clientoutlen = 0;
|
|
218
|
+
break;
|
|
145
219
|
}
|
|
146
220
|
|
|
147
221
|
(void)prompt_need;
|
|
@@ -149,15 +223,9 @@ cbsasl_error_t cbsasl_client_start(cbsasl_conn_t *conn,
|
|
|
149
223
|
}
|
|
150
224
|
|
|
151
225
|
CBSASL_PUBLIC_API
|
|
152
|
-
cbsasl_error_t cbsasl_client_step(cbsasl_conn_t *conn,
|
|
153
|
-
const char *
|
|
154
|
-
unsigned int serverinlen,
|
|
155
|
-
void **not_used,
|
|
156
|
-
const char **clientout,
|
|
157
|
-
unsigned int *clientoutlen)
|
|
226
|
+
cbsasl_error_t cbsasl_client_step(cbsasl_conn_t *conn, const char *serverin, unsigned int serverinlen, void **not_used,
|
|
227
|
+
const char **clientout, unsigned int *clientoutlen)
|
|
158
228
|
{
|
|
159
|
-
unsigned char digest[DIGEST_LENGTH];
|
|
160
|
-
char md5string[DIGEST_LENGTH * 2];
|
|
161
229
|
const char *usernm = NULL;
|
|
162
230
|
unsigned int usernmlen;
|
|
163
231
|
cbsasl_secret_t *pass;
|
|
@@ -169,39 +237,183 @@ cbsasl_error_t cbsasl_client_step(cbsasl_conn_t *conn,
|
|
|
169
237
|
return SASL_BADPARAM;
|
|
170
238
|
}
|
|
171
239
|
|
|
172
|
-
if (conn->c.client.
|
|
240
|
+
if (conn->c.client.auth_mech == SASL_AUTH_MECH_PLAIN) {
|
|
173
241
|
/* Shouldn't be called during plain auth */
|
|
174
242
|
return SASL_BADPARAM;
|
|
175
243
|
}
|
|
176
244
|
|
|
177
|
-
ret = conn->c.client.get_username(conn->c.client.get_username_ctx,
|
|
178
|
-
CBSASL_CB_USER, &usernm, &usernmlen);
|
|
245
|
+
ret = conn->c.client.get_username(conn->c.client.get_username_ctx, CBSASL_CB_USER, &usernm, &usernmlen);
|
|
179
246
|
if (ret != SASL_OK) {
|
|
180
247
|
return ret;
|
|
181
248
|
}
|
|
182
249
|
|
|
183
|
-
ret = conn->c.client.get_password(conn, conn->c.client.get_password_ctx,
|
|
184
|
-
CBSASL_CB_PASS, &pass);
|
|
250
|
+
ret = conn->c.client.get_password(conn, conn->c.client.get_password_ctx, CBSASL_CB_PASS, &pass);
|
|
185
251
|
if (ret != SASL_OK) {
|
|
186
252
|
return ret;
|
|
187
253
|
}
|
|
188
254
|
|
|
189
255
|
free(conn->c.client.userdata);
|
|
190
|
-
conn->c.client.userdata =
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
256
|
+
conn->c.client.userdata = NULL;
|
|
257
|
+
switch (conn->c.client.auth_mech) {
|
|
258
|
+
case SASL_AUTH_MECH_CRAM_MD5: {
|
|
259
|
+
unsigned char digest[DIGEST_LENGTH];
|
|
260
|
+
char md5string[DIGEST_LENGTH * 2];
|
|
261
|
+
conn->c.client.userdata = calloc(usernmlen + 1 + sizeof(md5string) + 1, 1);
|
|
262
|
+
if (conn->c.client.userdata == NULL) {
|
|
263
|
+
return SASL_NOMEM;
|
|
264
|
+
}
|
|
194
265
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
266
|
+
cbsasl_hmac_md5((unsigned char *)serverin, serverinlen, pass->data, pass->len, digest);
|
|
267
|
+
cbsasl_hex_encode(md5string, (char *)digest, DIGEST_LENGTH);
|
|
268
|
+
memcpy(conn->c.client.userdata, usernm, usernmlen);
|
|
269
|
+
conn->c.client.userdata[usernmlen] = ' ';
|
|
270
|
+
memcpy(conn->c.client.userdata + usernmlen + 1, md5string, sizeof(md5string));
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
case SASL_AUTH_MECH_SCRAM_SHA1:
|
|
274
|
+
case SASL_AUTH_MECH_SCRAM_SHA256:
|
|
275
|
+
case SASL_AUTH_MECH_SCRAM_SHA512: {
|
|
276
|
+
if (!conn->c.client.auth_message) {
|
|
277
|
+
const char *combinednonce = NULL; // nonce extracted from server's first reply
|
|
278
|
+
unsigned int noncelen = 0;
|
|
279
|
+
const char *salt = NULL; // salt extracted from server's first reply
|
|
280
|
+
unsigned int saltlen = 0;
|
|
281
|
+
unsigned int itcount = 0;
|
|
282
|
+
unsigned char saltedpassword[CBSASL_SHA512_DIGEST_SIZE]; // max digest size
|
|
283
|
+
unsigned int saltedpasslen = 0;
|
|
284
|
+
unsigned int prooflen = 0; // proof size in base64
|
|
202
285
|
|
|
286
|
+
ret =
|
|
287
|
+
parse_server_challenge(serverin, serverinlen, &combinednonce, &noncelen, &salt, &saltlen, &itcount);
|
|
288
|
+
if (ret != SASL_OK) {
|
|
289
|
+
return ret;
|
|
290
|
+
}
|
|
291
|
+
if (!combinednonce || !noncelen || !salt || !saltlen || !itcount) {
|
|
292
|
+
// missing or invalid value in server challenge
|
|
293
|
+
return SASL_BADPARAM;
|
|
294
|
+
}
|
|
295
|
+
if (noncelen < SCRAM_NONCE_SIZE * 2 ||
|
|
296
|
+
memcmp(combinednonce, conn->c.client.nonce, SCRAM_NONCE_SIZE * 2)) {
|
|
297
|
+
// the combined nonce doesn't start with the client nonce we sent previously
|
|
298
|
+
return SASL_BADPARAM;
|
|
299
|
+
}
|
|
300
|
+
// ok, now we can compute the client proof
|
|
301
|
+
ret = generate_salted_password(conn->c.client.auth_mech, pass, salt, saltlen, itcount, saltedpassword,
|
|
302
|
+
&saltedpasslen);
|
|
303
|
+
if (ret != SASL_OK) {
|
|
304
|
+
return ret;
|
|
305
|
+
}
|
|
306
|
+
// save salted password for later use
|
|
307
|
+
conn->c.client.saltedpassword = calloc(saltedpasslen, 1);
|
|
308
|
+
if (conn->c.client.saltedpassword == NULL) {
|
|
309
|
+
return SASL_NOMEM;
|
|
310
|
+
}
|
|
311
|
+
memcpy(conn->c.client.saltedpassword, saltedpassword, saltedpasslen);
|
|
312
|
+
conn->c.client.saltedpasslen = saltedpasslen;
|
|
313
|
+
|
|
314
|
+
// before building the client proof, we start building the client final message,
|
|
315
|
+
// as it is used for the computation of the proof
|
|
316
|
+
// The final message starts with the base64-encoded GS2 header from the initial message.
|
|
317
|
+
// As we always use "n,,", we can hardcode directly its base64-counterpart, so "biws".
|
|
318
|
+
#define FINAL_HEADER "c=biws,r="
|
|
319
|
+
#define PROOF_ATTR ",p="
|
|
320
|
+
switch (conn->c.client.auth_mech) {
|
|
321
|
+
case SASL_AUTH_MECH_SCRAM_SHA1:
|
|
322
|
+
prooflen = (CBSASL_SHA1_DIGEST_SIZE / 3 + 1) * 4;
|
|
323
|
+
break;
|
|
324
|
+
case SASL_AUTH_MECH_SCRAM_SHA256:
|
|
325
|
+
prooflen = (CBSASL_SHA256_DIGEST_SIZE / 3 + 1) * 4;
|
|
326
|
+
break;
|
|
327
|
+
case SASL_AUTH_MECH_SCRAM_SHA512:
|
|
328
|
+
prooflen = (CBSASL_SHA512_DIGEST_SIZE / 3 + 1) * 4;
|
|
329
|
+
break;
|
|
330
|
+
default:
|
|
331
|
+
break;
|
|
332
|
+
}
|
|
333
|
+
conn->c.client.userdata =
|
|
334
|
+
calloc(strlen(FINAL_HEADER) + noncelen + strlen(PROOF_ATTR) + prooflen + 1, 1);
|
|
335
|
+
if (conn->c.client.userdata == NULL) {
|
|
336
|
+
return SASL_NOMEM;
|
|
337
|
+
}
|
|
338
|
+
memcpy(conn->c.client.userdata, FINAL_HEADER, strlen(FINAL_HEADER));
|
|
339
|
+
memcpy(conn->c.client.userdata + strlen(FINAL_HEADER), combinednonce, noncelen);
|
|
340
|
+
memcpy(conn->c.client.userdata + strlen(FINAL_HEADER) + noncelen, PROOF_ATTR, strlen(PROOF_ATTR));
|
|
341
|
+
|
|
342
|
+
ret = compute_client_proof(
|
|
343
|
+
conn->c.client.auth_mech, saltedpassword, saltedpasslen, conn->c.client.client_first_message_bare,
|
|
344
|
+
strlen(conn->c.client.client_first_message_bare), serverin, serverinlen, conn->c.client.userdata,
|
|
345
|
+
strlen(FINAL_HEADER) + noncelen, &(conn->c.client.auth_message),
|
|
346
|
+
conn->c.client.userdata + strlen(FINAL_HEADER) + noncelen + strlen(PROOF_ATTR), prooflen + 1);
|
|
347
|
+
if (ret != SASL_OK) {
|
|
348
|
+
return ret;
|
|
349
|
+
}
|
|
350
|
+
} else {
|
|
351
|
+
// auth_message should not be already set
|
|
352
|
+
return SASL_FAIL;
|
|
353
|
+
}
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
default:
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
203
359
|
*clientout = conn->c.client.userdata;
|
|
204
360
|
*clientoutlen = strlen(conn->c.client.userdata);
|
|
205
361
|
|
|
206
362
|
return SASL_CONTINUE;
|
|
207
363
|
}
|
|
364
|
+
|
|
365
|
+
cbsasl_error_t cbsasl_client_check(cbsasl_conn_t *conn, const char *serverin, unsigned int serverinlen)
|
|
366
|
+
{
|
|
367
|
+
switch (conn->c.client.auth_mech) {
|
|
368
|
+
case SASL_AUTH_MECH_SCRAM_SHA1:
|
|
369
|
+
case SASL_AUTH_MECH_SCRAM_SHA256:
|
|
370
|
+
case SASL_AUTH_MECH_SCRAM_SHA512: {
|
|
371
|
+
if (conn->c.client.auth_message) {
|
|
372
|
+
char serversign[(CBSASL_SHA512_DIGEST_SIZE / 3 + 1) * 4 + 1]; // max sign len
|
|
373
|
+
unsigned int serversignlen = 0;
|
|
374
|
+
cbsasl_error_t ret;
|
|
375
|
+
|
|
376
|
+
// Last step: we have to verify the server's proof.
|
|
377
|
+
// In case of positive answer from the server, its final reply must start with "v=".
|
|
378
|
+
if (serverinlen <= 2 || memcmp(serverin, "v=", 2)) {
|
|
379
|
+
return SASL_FAIL;
|
|
380
|
+
}
|
|
381
|
+
switch (conn->c.client.auth_mech) {
|
|
382
|
+
case SASL_AUTH_MECH_SCRAM_SHA1:
|
|
383
|
+
serversignlen = (CBSASL_SHA1_DIGEST_SIZE / 3 + 1) * 4;
|
|
384
|
+
break;
|
|
385
|
+
case SASL_AUTH_MECH_SCRAM_SHA256:
|
|
386
|
+
serversignlen = (CBSASL_SHA256_DIGEST_SIZE / 3 + 1) * 4;
|
|
387
|
+
break;
|
|
388
|
+
case SASL_AUTH_MECH_SCRAM_SHA512:
|
|
389
|
+
serversignlen = (CBSASL_SHA512_DIGEST_SIZE / 3 + 1) * 4;
|
|
390
|
+
break;
|
|
391
|
+
default:
|
|
392
|
+
break;
|
|
393
|
+
}
|
|
394
|
+
ret = compute_server_signature(conn->c.client.auth_mech, conn->c.client.saltedpassword,
|
|
395
|
+
conn->c.client.saltedpasslen, conn->c.client.auth_message, serversign,
|
|
396
|
+
sizeof(serversign));
|
|
397
|
+
if (ret != SASL_OK) {
|
|
398
|
+
return ret;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// ok, we can now compare the two values
|
|
402
|
+
if ((serverinlen - 2 < serversignlen) || (memcmp(serverin + 2, serversign, serversignlen))) {
|
|
403
|
+
return SASL_FAIL;
|
|
404
|
+
}
|
|
405
|
+
} else {
|
|
406
|
+
// we have an issue: auth_message should not have been cleared
|
|
407
|
+
return SASL_FAIL;
|
|
408
|
+
}
|
|
409
|
+
break;
|
|
410
|
+
}
|
|
411
|
+
case SASL_AUTH_MECH_CRAM_MD5:
|
|
412
|
+
case SASL_AUTH_MECH_PLAIN:
|
|
413
|
+
default:
|
|
414
|
+
// nothing to do
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
return SASL_OK;
|
|
419
|
+
}
|