1 /*
2  * External password backend
3  * Copyright (c) 2012, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "includes.h"
10 
11 #ifdef __linux__
12 #include <sys/mman.h>
13 #endif /* __linux__ */
14 
15 #include "common.h"
16 #include "ext_password_i.h"
17 
18 
19 #ifdef CONFIG_EXT_PASSWORD_TEST
20 extern struct ext_password_backend ext_password_test;
21 #endif /* CONFIG_EXT_PASSWORD_TEST */
22 
23 static const struct ext_password_backend *backends[] = {
24 #ifdef CONFIG_EXT_PASSWORD_TEST
25 	&ext_password_test,
26 #endif /* CONFIG_EXT_PASSWORD_TEST */
27 	NULL
28 };
29 
30 struct ext_password_data {
31 	const struct ext_password_backend *backend;
32 	void *priv;
33 };
34 
35 
36 struct ext_password_data * ext_password_init(const char *backend,
37 					     const char *params)
38 {
39 	struct ext_password_data *data;
40 	int i;
41 
42 	data = os_zalloc(sizeof(*data));
43 	if (data == NULL)
44 		return NULL;
45 
46 	for (i = 0; backends[i]; i++) {
47 		if (os_strcmp(backends[i]->name, backend) == 0) {
48 			data->backend = backends[i];
49 			break;
50 		}
51 	}
52 
53 	if (!data->backend) {
54 		os_free(data);
55 		return NULL;
56 	}
57 
58 	data->priv = data->backend->init(params);
59 	if (data->priv == NULL) {
60 		os_free(data);
61 		return NULL;
62 	}
63 
64 	return data;
65 }
66 
67 
68 void ext_password_deinit(struct ext_password_data *data)
69 {
70 	if (data && data->backend && data->priv)
71 		data->backend->deinit(data->priv);
72 	os_free(data);
73 }
74 
75 
76 struct wpabuf * ext_password_get(struct ext_password_data *data,
77 				 const char *name)
78 {
79 	if (data == NULL)
80 		return NULL;
81 	return data->backend->get(data->priv, name);
82 }
83 
84 
85 struct wpabuf * ext_password_alloc(size_t len)
86 {
87 	struct wpabuf *buf;
88 
89 	buf = wpabuf_alloc(len);
90 	if (buf == NULL)
91 		return NULL;
92 
93 #ifdef __linux__
94 	if (mlock(wpabuf_head(buf), wpabuf_len(buf)) < 0) {
95 		wpa_printf(MSG_ERROR, "EXT PW: mlock failed: %s",
96 			   strerror(errno));
97 	}
98 #endif /* __linux__ */
99 
100 	return buf;
101 }
102 
103 
104 void ext_password_free(struct wpabuf *pw)
105 {
106 	if (pw == NULL)
107 		return;
108 	os_memset(wpabuf_mhead(pw), 0, wpabuf_len(pw));
109 #ifdef __linux__
110 	if (munlock(wpabuf_head(pw), wpabuf_len(pw)) < 0) {
111 		wpa_printf(MSG_ERROR, "EXT PW: munlock failed: %s",
112 			   strerror(errno));
113 	}
114 #endif /* __linux__ */
115 	wpabuf_free(pw);
116 }
117