aboutsummaryrefslogtreecommitdiffstats
path: root/auth.c
blob: 5a9d8bb8f0858f9adf0c09f75a72eb2d28ee1375 (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
#define BITLBEE_CORE
#include "bitlbee.h"

#ifdef WITH_PAM
extern auth_backend_t auth_pam;
#endif
#ifdef WITH_LDAP
extern auth_backend_t auth_ldap;
#endif

GList *auth_init(const char *backend)
{
	GList *gl = NULL;
	int ok = backend ? 0 : 1;
#ifdef WITH_PAM
	gl = g_list_append(gl, &auth_pam);
	if (backend && !strcmp(backend, "pam")) {
		ok = 1;
	}
#endif
#ifdef WITH_LDAP
	gl = g_list_append(gl, &auth_ldap);
	if (backend && !strcmp(backend, "ldap")) {
		ok = 1;
	}
#endif

	return ok ? gl : NULL;
}

storage_status_t auth_check_pass(irc_t *irc, const char *nick, const char *password)
{
	GList *gl;
	storage_status_t status = storage_check_pass(irc, nick, password);

	if (status == STORAGE_CHECK_BACKEND) {
		for (gl = global.auth; gl; gl = gl->next) {
			auth_backend_t *be = gl->data;
			if (!strcmp(be->name, irc->auth_backend)) {
				status = be->check_pass(nick, password);
				break;
			}
		}
	} else if (status == STORAGE_NO_SUCH_USER && global.conf->auth_backend) {
		for (gl = global.auth; gl; gl = gl->next) {
			auth_backend_t *be = gl->data;
			if (!strcmp(be->name, global.conf->auth_backend)) {
				status = be->check_pass(nick, password);
				/* Save the user so storage_load will pick them up, similar to
				 * what the register command would do */
				if (status == STORAGE_OK) {
					irc->auth_backend = g_strdup(global.conf->auth_backend);
					storage_save(irc, (char *)password, 0);
				}
				break;
			}
		}
	}

	if (status == STORAGE_OK) {
		irc_setpass(irc, password);
	}

	return status;
}
an>in[1]<<2) & 0x3c) | (in[2]>>6)]; out[outlen++] = b64digits[in[2] & 0x3f]; in += 3; } if (inlen > 0) { out[outlen++] = b64digits[in[0] >> 2]; if (inlen > 1) { out[outlen++] = b64digits[((in[0]<<4) & 0x30) | (in[1]>>4)]; out[outlen++] = b64digits[((in[1]<<2) & 0x3c)]; } else { out[outlen++] = b64digits[((in[0]<<4) & 0x30)]; out[outlen++] = b64digits[64]; } out[outlen++] = b64digits[64]; } out[outlen] = 0; return outlen; } /* Just a simple wrapper, but usually not very convenient because of zero termination. */ char *frombase64(const char *in) { unsigned char *out; base64_decode(in, &out); return (char*) out; } /* FIXME: Lookup table stuff is not threadsafe! (But for now BitlBee is not threaded.) */ int base64_decode(const char *in, unsigned char **out) { static char b64rev[256] = { 0 }; int len, i; /* Create a reverse-lookup for the Base64 sequence. */ if( b64rev[0] == 0 ) { memset( b64rev, 0xff, 256 ); for( i = 0; i <= 64; i ++ ) b64rev[(int)real_b64[i]] = i; } len = strlen( in ); *out = g_malloc( ( len + 6 ) / 4 * 3 ); len = base64_decode_real( (unsigned char*) in, *out, b64rev ); *out = g_realloc( *out, len + 1 ); out[0][len] = 0; /* Zero termination can't hurt. */ return len; } int base64_decode_real(const unsigned char *in, unsigned char *out, char *b64rev) { int i, outlen = 0; for( i = 0; in[i]; i += 4 ) { int sx; sx = b64rev[(int)in[i+0]]; if( sx >= 64 ) break; out[outlen] = ( sx << 2 ) & 0xfc; sx = b64rev[(int)in[i+1]]; if( sx >= 64 ) break; out[outlen] |= ( sx >> 4 ) & 0x03; outlen ++; out[outlen] = ( sx << 4 ) & 0xf0; sx = b64rev[(int)in[i+2]]; if( sx >= 64 ) break; out[outlen] |= ( sx >> 2 ) & 0x0f; outlen ++; out[outlen] = ( sx << 6 ) & 0xc0; sx = b64rev[(int)in[i+3]]; if( sx >= 64 ) break; out[outlen] |= sx; outlen ++; } /* If sx > 64 the base64 string was damaged. Should we ignore this? */ return outlen; }