summaryrefslogtreecommitdiff
path: root/vendor/gopkg.in/mgo.v2/internal/sasl/sasl.c
blob: 8be0bc459641013cee8eb7da231ad86bae7f24e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// +build !windows

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sasl/sasl.h>

static int mgo_sasl_simple(void *context, int id, const char **result, unsigned int *len)
{
	if (!result) {
		return SASL_BADPARAM;
	}
	switch (id) {
	case SASL_CB_USER:
		*result = (char *)context;
		break;
	case SASL_CB_AUTHNAME:
		*result = (char *)context;
		break;
	case SASL_CB_LANGUAGE:
		*result = NULL;
		break;
	default:
		return SASL_BADPARAM;
	}
	if (len) {
		*len = *result ? strlen(*result) : 0;
	}
	return SASL_OK;
}

typedef int (*callback)(void);

static int mgo_sasl_secret(sasl_conn_t *conn, void *context, int id, sasl_secret_t **result)
{
	if (!conn || !result || id != SASL_CB_PASS) {
		return SASL_BADPARAM;
	}
	*result = (sasl_secret_t *)context;
	return SASL_OK;
}

sasl_callback_t *mgo_sasl_callbacks(const char *username, const char *password)
{
	sasl_callback_t *cb = malloc(4 * sizeof(sasl_callback_t));
	int n = 0;

	size_t len = strlen(password);
	sasl_secret_t *secret = (sasl_secret_t*)malloc(sizeof(sasl_secret_t) + len);
	if (!secret) {
		free(cb);
		return NULL;
	}
	strcpy((char *)secret->data, password);
	secret->len = len;

	cb[n].id = SASL_CB_PASS;
	cb[n].proc = (callback)&mgo_sasl_secret;
	cb[n].context = secret;
	n++;

	cb[n].id = SASL_CB_USER;
	cb[n].proc = (callback)&mgo_sasl_simple;
	cb[n].context = (char*)username;
	n++;

	cb[n].id = SASL_CB_AUTHNAME;
	cb[n].proc = (callback)&mgo_sasl_simple;
	cb[n].context = (char*)username;
	n++;

	cb[n].id = SASL_CB_LIST_END;
	cb[n].proc = NULL;
	cb[n].context = NULL;

	return cb;
}