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