1252190Srpaulo/*
2252190Srpaulo * External password backend
3252190Srpaulo * Copyright (c) 2012, Jouni Malinen <j@w1.fi>
4252190Srpaulo *
5252190Srpaulo * This software may be distributed under the terms of the BSD license.
6252190Srpaulo * See README for more details.
7252190Srpaulo */
8252190Srpaulo
9252190Srpaulo#include "includes.h"
10252190Srpaulo
11252190Srpaulo#ifdef __linux__
12252190Srpaulo#include <sys/mman.h>
13252190Srpaulo#endif /* __linux__ */
14252190Srpaulo
15252190Srpaulo#include "common.h"
16252190Srpaulo#include "ext_password_i.h"
17252190Srpaulo
18252190Srpaulo
19252190Srpaulo#ifdef CONFIG_EXT_PASSWORD_TEST
20252190Srpauloextern struct ext_password_backend ext_password_test;
21252190Srpaulo#endif /* CONFIG_EXT_PASSWORD_TEST */
22252190Srpaulo
23252190Srpaulostatic const struct ext_password_backend *backends[] = {
24252190Srpaulo#ifdef CONFIG_EXT_PASSWORD_TEST
25252190Srpaulo	&ext_password_test,
26252190Srpaulo#endif /* CONFIG_EXT_PASSWORD_TEST */
27252190Srpaulo	NULL
28252190Srpaulo};
29252190Srpaulo
30252190Srpaulostruct ext_password_data {
31252190Srpaulo	const struct ext_password_backend *backend;
32252190Srpaulo	void *priv;
33252190Srpaulo};
34252190Srpaulo
35252190Srpaulo
36252190Srpaulostruct ext_password_data * ext_password_init(const char *backend,
37252190Srpaulo					     const char *params)
38252190Srpaulo{
39252190Srpaulo	struct ext_password_data *data;
40252190Srpaulo	int i;
41252190Srpaulo
42252190Srpaulo	data = os_zalloc(sizeof(*data));
43252190Srpaulo	if (data == NULL)
44252190Srpaulo		return NULL;
45252190Srpaulo
46252190Srpaulo	for (i = 0; backends[i]; i++) {
47252190Srpaulo		if (os_strcmp(backends[i]->name, backend) == 0) {
48252190Srpaulo			data->backend = backends[i];
49252190Srpaulo			break;
50252190Srpaulo		}
51252190Srpaulo	}
52252190Srpaulo
53252190Srpaulo	if (!data->backend) {
54252190Srpaulo		os_free(data);
55252190Srpaulo		return NULL;
56252190Srpaulo	}
57252190Srpaulo
58252190Srpaulo	data->priv = data->backend->init(params);
59252190Srpaulo	if (data->priv == NULL) {
60252190Srpaulo		os_free(data);
61252190Srpaulo		return NULL;
62252190Srpaulo	}
63252190Srpaulo
64252190Srpaulo	return data;
65252190Srpaulo}
66252190Srpaulo
67252190Srpaulo
68252190Srpaulovoid ext_password_deinit(struct ext_password_data *data)
69252190Srpaulo{
70252190Srpaulo	if (data && data->backend && data->priv)
71252190Srpaulo		data->backend->deinit(data->priv);
72252190Srpaulo	os_free(data);
73252190Srpaulo}
74252190Srpaulo
75252190Srpaulo
76252190Srpaulostruct wpabuf * ext_password_get(struct ext_password_data *data,
77252190Srpaulo				 const char *name)
78252190Srpaulo{
79252190Srpaulo	if (data == NULL)
80252190Srpaulo		return NULL;
81252190Srpaulo	return data->backend->get(data->priv, name);
82252190Srpaulo}
83252190Srpaulo
84252190Srpaulo
85252190Srpaulostruct wpabuf * ext_password_alloc(size_t len)
86252190Srpaulo{
87252190Srpaulo	struct wpabuf *buf;
88252190Srpaulo
89252190Srpaulo	buf = wpabuf_alloc(len);
90252190Srpaulo	if (buf == NULL)
91252190Srpaulo		return NULL;
92252190Srpaulo
93252190Srpaulo#ifdef __linux__
94252190Srpaulo	if (mlock(wpabuf_head(buf), wpabuf_len(buf)) < 0) {
95252190Srpaulo		wpa_printf(MSG_ERROR, "EXT PW: mlock failed: %s",
96252190Srpaulo			   strerror(errno));
97252190Srpaulo	}
98252190Srpaulo#endif /* __linux__ */
99252190Srpaulo
100252190Srpaulo	return buf;
101252190Srpaulo}
102252190Srpaulo
103252190Srpaulo
104252190Srpaulovoid ext_password_free(struct wpabuf *pw)
105252190Srpaulo{
106252190Srpaulo	if (pw == NULL)
107252190Srpaulo		return;
108252190Srpaulo	os_memset(wpabuf_mhead(pw), 0, wpabuf_len(pw));
109252190Srpaulo#ifdef __linux__
110252190Srpaulo	if (munlock(wpabuf_head(pw), wpabuf_len(pw)) < 0) {
111252190Srpaulo		wpa_printf(MSG_ERROR, "EXT PW: munlock failed: %s",
112252190Srpaulo			   strerror(errno));
113252190Srpaulo	}
114252190Srpaulo#endif /* __linux__ */
115252190Srpaulo	wpabuf_free(pw);
116252190Srpaulo}
117