1 // +build !windows
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <sasl/sasl.h>
7
mgo_sasl_simple(void * context,int id,const char ** result,unsigned int * len)8 static int mgo_sasl_simple(void *context, int id, const char **result, unsigned int *len)
9 {
10 if (!result) {
11 return SASL_BADPARAM;
12 }
13 switch (id) {
14 case SASL_CB_USER:
15 *result = (char *)context;
16 break;
17 case SASL_CB_AUTHNAME:
18 *result = (char *)context;
19 break;
20 case SASL_CB_LANGUAGE:
21 *result = NULL;
22 break;
23 default:
24 return SASL_BADPARAM;
25 }
26 if (len) {
27 *len = *result ? strlen(*result) : 0;
28 }
29 return SASL_OK;
30 }
31
32 typedef int (*callback)(void);
33
mgo_sasl_secret(sasl_conn_t * conn,void * context,int id,sasl_secret_t ** result)34 static int mgo_sasl_secret(sasl_conn_t *conn, void *context, int id, sasl_secret_t **result)
35 {
36 if (!conn || !result || id != SASL_CB_PASS) {
37 return SASL_BADPARAM;
38 }
39 *result = (sasl_secret_t *)context;
40 return SASL_OK;
41 }
42
mgo_sasl_callbacks(const char * username,const char * password)43 sasl_callback_t *mgo_sasl_callbacks(const char *username, const char *password)
44 {
45 sasl_callback_t *cb = malloc(4 * sizeof(sasl_callback_t));
46 int n = 0;
47
48 size_t len = strlen(password);
49 sasl_secret_t *secret = (sasl_secret_t*)malloc(sizeof(sasl_secret_t) + len);
50 if (!secret) {
51 free(cb);
52 return NULL;
53 }
54 strcpy((char *)secret->data, password);
55 secret->len = len;
56
57 cb[n].id = SASL_CB_PASS;
58 cb[n].proc = (callback)&mgo_sasl_secret;
59 cb[n].context = secret;
60 n++;
61
62 cb[n].id = SASL_CB_USER;
63 cb[n].proc = (callback)&mgo_sasl_simple;
64 cb[n].context = (char*)username;
65 n++;
66
67 cb[n].id = SASL_CB_AUTHNAME;
68 cb[n].proc = (callback)&mgo_sasl_simple;
69 cb[n].context = (char*)username;
70 n++;
71
72 cb[n].id = SASL_CB_LIST_END;
73 cb[n].proc = NULL;
74 cb[n].context = NULL;
75
76 return cb;
77 }
78