Skip to content

Commit 571b10e

Browse files
committed
CDRIVER-404 Implement SCRAM-SHA-1 SASL Mechanism
Implements Scram Sha1 for the c driver
1 parent adee50b commit 571b10e

19 files changed

+1924
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ depcomp
2323
.DS_Store
2424
echo-server
2525
example-client
26+
example-scram
2627
example-gridfs
2728
example-matcher
2829
filter-bsondump

doc/mongoc_rand.page

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?xml version="1.0"?>
2+
3+
<page id="mongoc_rand"
4+
type="guide"
5+
style="class"
6+
xmlns="http://projectmallard.org/1.0/"
7+
xmlns:api="http://projectmallard.org/experimental/api/"
8+
xmlns:ui="http://projectmallard.org/experimental/ui/">
9+
10+
<info>
11+
<link type="guide" xref="index#api-reference" />
12+
</info>
13+
14+
<title>mongoc_rand</title>
15+
<subtitle>MongoDB Random Number Generator</subtitle>
16+
17+
<section id="description">
18+
<title>Synopsis</title>
19+
<synopsis><code mime="text/x-csrc"><![CDATA[void
20+
mongoc_rand_add (const void *buf,
21+
int num,
22+
doubel entropy);
23+
24+
void
25+
mongoc_rand_seed (const void *buf,
26+
int num);
27+
28+
int
29+
mongoc_rand_status (void);]]></code></synopsis>
30+
</section>
31+
32+
<section id="description">
33+
<title>Description</title>
34+
<p>The <code>mongoc_rand</code> family of functions provide access to the low level randomness primitives used by the MongoDB C Driver. In particular, they control the creation of cryptographically strong pseudo-random bytes required by some security mechanisms.</p>
35+
36+
<p>While we can usually pull enough entropy from the environment, you may be required to seed the PRNG manually depending on your OS, hardware and other entropy consumers running on the same system.</p>
37+
</section>
38+
39+
<section id="entropy">
40+
<title>Entropy</title>
41+
42+
<p><code>mongoc_rand_add</code> and <code>mongoc_rand_seed</code> allow the user to directly provide entropy. They differ insofar as <code>mongoc_rand_seed</code> requires that each bit provided is fully random. <code>mongoc_rand_add</code> allows the user to specify the degree of randomness in the provided bytes as well.</p>
43+
</section>
44+
45+
<section id="status">
46+
<title>Status</title>
47+
48+
<p>The <code>mongoc_rand_status</code> function allows the user to check the status of the mongoc PRNG. This can be used to guarantee sufficient entropy at program startup, rather than waiting for runtime errors to occur.</p>
49+
</section>
50+
51+
<links type="topic" groups="function" style="2column">
52+
<title>Functions</title>
53+
</links>
54+
55+
</page>

doc/mongoc_rand_add.page

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?xml version="1.0"?>
2+
3+
<page xmlns="http://projectmallard.org/1.0/"
4+
type="topic"
5+
style="function"
6+
xmlns:api="http://projectmallard.org/experimental/api/"
7+
xmlns:ui="http://projectmallard.org/experimental/ui/"
8+
id="mongoc_rand_add">
9+
10+
11+
<info>
12+
<link type="guide" xref="mongoc_rand" group="function"/>
13+
</info>
14+
<title>mongoc_rand_add()</title>
15+
16+
<section id="synopsis">
17+
<title>Synopsis</title>
18+
<synopsis><code mime="text/x-csrc"><![CDATA[void
19+
mongoc_rand_add(const void *buf,
20+
int num,
21+
double entropy);
22+
]]></code></synopsis>
23+
</section>
24+
25+
<section id="description">
26+
<title>Description</title>
27+
<p>Mixes num bytes of data into the mongoc random number generator. Entropy specifies a lower bound estimate of the randomness contained in buf.</p>
28+
</section>
29+
30+
<section id="parameters">
31+
<title>Parameters</title>
32+
<table>
33+
<tr><td><p>buf</p></td><td><p>A buffer.</p></td></tr>
34+
<tr><td><p>num</p></td><td><p>An int of number of bytes in buf.</p></td></tr>
35+
<tr><td><p>entropy</p></td><td><p>A double of randomness estimate in buf.</p></td></tr>
36+
</table>
37+
</section>
38+
39+
</page>

doc/mongoc_rand_seed.page

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0"?>
2+
3+
<page xmlns="http://projectmallard.org/1.0/"
4+
type="topic"
5+
style="function"
6+
xmlns:api="http://projectmallard.org/experimental/api/"
7+
xmlns:ui="http://projectmallard.org/experimental/ui/"
8+
id="mongoc_rand_seed">
9+
10+
11+
<info>
12+
<link type="guide" xref="mongoc_rand" group="function"/>
13+
</info>
14+
<title>mongoc_rand_seed()</title>
15+
16+
<section id="synopsis">
17+
<title>Synopsis</title>
18+
<synopsis><code mime="text/x-csrc"><![CDATA[void
19+
mongoc_rand_seed(const void *buf,
20+
int num);
21+
]]></code></synopsis>
22+
</section>
23+
24+
<section id="description">
25+
<title>Description</title>
26+
<p>Seeds the mongoc random number generator with num bytes of entropy.</p>
27+
</section>
28+
29+
<section id="parameters">
30+
<title>Parameters</title>
31+
<table>
32+
<tr><td><p>buf</p></td><td><p>A buffer.</p></td></tr>
33+
<tr><td><p>num</p></td><td><p>An int of number of bytes in buf.</p></td></tr>
34+
</table>
35+
</section>
36+
37+
</page>

doc/mongoc_rand_status.page

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0"?>
2+
3+
<page xmlns="http://projectmallard.org/1.0/"
4+
type="topic"
5+
style="function"
6+
xmlns:api="http://projectmallard.org/experimental/api/"
7+
xmlns:ui="http://projectmallard.org/experimental/ui/"
8+
id="mongoc_rand_status">
9+
10+
11+
<info>
12+
<link type="guide" xref="mongoc_rand" group="function"/>
13+
</info>
14+
<title>mongoc_rand_status()</title>
15+
16+
<section id="synopsis">
17+
<title>Synopsis</title>
18+
<synopsis><code mime="text/x-csrc"><![CDATA[int
19+
mongoc_rand_status(void);
20+
]]></code></synopsis>
21+
</section>
22+
23+
<section id="description">
24+
<title>Description</title>
25+
<p>The status of the mongoc random number generator.</p>
26+
</section>
27+
28+
<section id="return">
29+
<title>Returns</title>
30+
<p>Returns 1 if the PRNG has been seeded with enough data, 0 otherwise.</p>
31+
</section>
32+
33+
</page>

examples/Makefile.am

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ example_client_SOURCES = examples/example-client.c
2929
example_client_CFLAGS = $(EXAMPLE_CFLAGS)
3030
example_client_LDADD = $(EXAMPLE_LDADD)
3131

32+
noinst_PROGRAMS += example-scram
33+
example_scram_SOURCES = examples/example-scram.c
34+
example_scram_CFLAGS = $(EXAMPLE_CFLAGS)
35+
example_scram_LDADD = $(EXAMPLE_LDADD)
36+
3237
noinst_PROGRAMS += mongoc-ping
3338
mongoc_ping_SOURCES = examples/mongoc-ping.c
3439
mongoc_ping_CFLAGS = $(EXAMPLE_CFLAGS)

examples/example-scram.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/* gcc example.c -o example $(pkg-config --cflags --libs libmongoc-1.0) */
2+
3+
/* ./example-scram */
4+
5+
#include <mongoc.h>
6+
#include <stdio.h>
7+
#include <stdlib.h>
8+
9+
int
10+
main (int argc,
11+
char *argv[])
12+
{
13+
mongoc_client_t *client = NULL;
14+
mongoc_database_t *database = NULL;
15+
mongoc_collection_t *collection = NULL;
16+
mongoc_cursor_t *cursor = NULL;
17+
bson_error_t error;
18+
const char *uristr = "mongodb://127.0.0.1/";
19+
const char *authuristr;
20+
bson_t roles;
21+
bson_t query;
22+
const bson_t *doc;
23+
24+
if (argc != 2) {
25+
printf("%s - [implicit|scram|cr]\n", argv[0]);
26+
return 1;
27+
}
28+
29+
if (strcmp(argv[1], "implicit") == 0) {
30+
authuristr = "mongodb://user,=:[email protected]/test";
31+
} else if (strcmp(argv[1], "scram") == 0) {
32+
authuristr = "mongodb://user,=:[email protected]/test?authMechanism=SCRAM-SHA-1";
33+
} else if (strcmp(argv[1], "cr") == 0) {
34+
authuristr = "mongodb://user,=:[email protected]/test?authMechanism=MONGODB-CR";
35+
} else {
36+
printf("%s - [implicit|scram|cr]\n", argv[0]);
37+
}
38+
39+
mongoc_init ();
40+
41+
bson_init (&roles);
42+
bson_init (&query);
43+
44+
client = mongoc_client_new (uristr);
45+
46+
if (!client) {
47+
fprintf (stderr, "Failed to parse URI.\n");
48+
goto CLEANUP;
49+
}
50+
51+
database = mongoc_client_get_database (client, "test");
52+
53+
BCON_APPEND (&roles,
54+
"0", "{", "role", "root", "db", "admin", "}");
55+
56+
mongoc_database_add_user (database, "user,=", "pass", &roles, NULL, &error);
57+
58+
mongoc_database_destroy (database);
59+
database = NULL;
60+
61+
mongoc_client_destroy (client);
62+
client = NULL;
63+
64+
client = mongoc_client_new (authuristr);
65+
66+
if (!client) {
67+
fprintf (stderr, "failed to parse SCRAM uri\n");
68+
goto CLEANUP;
69+
}
70+
71+
collection = mongoc_client_get_collection (client, "test", "test");
72+
73+
cursor = mongoc_collection_find (collection, 0, 0, 0, 0, &query, NULL, NULL);
74+
75+
mongoc_cursor_next (cursor, &doc);
76+
77+
if (mongoc_cursor_error (cursor, &error)) {
78+
fprintf (stderr, "Auth error: %s\n", error.message);
79+
goto CLEANUP;
80+
}
81+
82+
CLEANUP:
83+
84+
bson_destroy (&roles);
85+
bson_destroy (&query);
86+
87+
if (collection) {
88+
mongoc_collection_destroy (collection);
89+
}
90+
91+
if (database) {
92+
mongoc_database_destroy (database);
93+
}
94+
95+
if (client) {
96+
mongoc_client_destroy (client);
97+
}
98+
99+
if (cursor) {
100+
mongoc_cursor_destroy (cursor);
101+
}
102+
103+
mongoc_cleanup ();
104+
105+
return EXIT_SUCCESS;
106+
}

src/libmongoc.symbols

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ mongoc_log_level_str
139139
mongoc_log_set_handler
140140
mongoc_matcher_destroy
141141
mongoc_matcher_match
142+
mongoc_rand_seed
143+
mongoc_rand_add
144+
mongoc_rand_status
142145
mongoc_matcher_new
143146
mongoc_read_prefs_add_tag
144147
mongoc_read_prefs_copy

src/mongoc/Makefile.am

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ MONGOC_DEF_FILES = \
1919
INST_H_FILES = \
2020
src/mongoc/mongoc.h \
2121
src/mongoc/mongoc-array-private.h \
22+
src/mongoc/mongoc-b64-private.h \
2223
src/mongoc/mongoc-buffer-private.h \
2324
src/mongoc/mongoc-bulk-operation-private.h \
2425
src/mongoc/mongoc-bulk-operation.h \
@@ -62,6 +63,7 @@ INST_H_FILES = \
6263
src/mongoc/mongoc-read-prefs.h \
6364
src/mongoc/mongoc-rpc-private.h \
6465
src/mongoc/mongoc-sasl-private.h \
66+
src/mongoc/mongoc-scram-private.h \
6567
src/mongoc/mongoc-socket.h \
6668
src/mongoc/mongoc-ssl-private.h \
6769
src/mongoc/mongoc-stream-buffered.h \
@@ -81,6 +83,8 @@ INST_H_FILES = \
8183

8284
if ENABLE_SSL
8385
INST_H_FILES += \
86+
src/mongoc/mongoc-rand.h \
87+
src/mongoc/mongoc-rand-private.h \
8488
src/mongoc/mongoc-stream-tls.h \
8589
src/mongoc/mongoc-ssl.h
8690
endif
@@ -125,6 +129,8 @@ MONGOC_SOURCES_SHARED += \
125129

126130
if ENABLE_SSL
127131
MONGOC_SOURCES_SHARED += \
132+
src/mongoc/mongoc-rand.c \
133+
src/mongoc/mongoc-scram.c \
128134
src/mongoc/mongoc-stream-tls.c \
129135
src/mongoc/mongoc-ssl.c
130136
endif

0 commit comments

Comments
 (0)