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 static const struct ext_password_backend *backends[] = {
20 #ifdef CONFIG_EXT_PASSWORD_TEST
21 	&ext_password_test,
22 #endif /* CONFIG_EXT_PASSWORD_TEST */
23 #ifdef CONFIG_EXT_PASSWORD_FILE
24 	&ext_password_file,
25 #endif /* CONFIG_EXT_PASSWORD_FILE */
26 	NULL
27 };
28 
29 struct ext_password_data {
30 	const struct ext_password_backend *backend;
31 	void *priv;
32 };
33 
34 
ext_password_init(const char * backend,const char * params)35 struct ext_password_data * ext_password_init(const char *backend,
36 					     const char *params)
37 {
38 	struct ext_password_data *data;
39 	int i;
40 
41 	data = os_zalloc(sizeof(*data));
42 	if (data == NULL)
43 		return NULL;
44 
45 	for (i = 0; backends[i]; i++) {
46 		if (os_strcmp(backends[i]->name, backend) == 0) {
47 			data->backend = backends[i];
48 			break;
49 		}
50 	}
51 
52 	if (!data->backend) {
53 		os_free(data);
54 		return NULL;
55 	}
56 
57 	data->priv = data->backend->init(params);
58 	if (data->priv == NULL) {
59 		os_free(data);
60 		return NULL;
61 	}
62 
63 	return data;
64 }
65 
66 
ext_password_deinit(struct ext_password_data * data)67 void ext_password_deinit(struct ext_password_data *data)
68 {
69 	if (data && data->backend && data->priv)
70 		data->backend->deinit(data->priv);
71 	os_free(data);
72 }
73 
74 
ext_password_get(struct ext_password_data * data,const char * name)75 struct wpabuf * ext_password_get(struct ext_password_data *data,
76 				 const char *name)
77 {
78 	if (data == NULL)
79 		return NULL;
80 	return data->backend->get(data->priv, name);
81 }
82 
83 
ext_password_alloc(size_t len)84 struct wpabuf * ext_password_alloc(size_t len)
85 {
86 	struct wpabuf *buf;
87 
88 	buf = wpabuf_alloc(len);
89 	if (buf == NULL)
90 		return NULL;
91 
92 #ifdef __linux__
93 	if (mlock(wpabuf_head(buf), wpabuf_len(buf)) < 0) {
94 		wpa_printf(MSG_ERROR, "EXT PW: mlock failed: %s",
95 			   strerror(errno));
96 	}
97 #endif /* __linux__ */
98 
99 	return buf;
100 }
101 
102 
ext_password_free(struct wpabuf * pw)103 void ext_password_free(struct wpabuf *pw)
104 {
105 	if (pw == NULL)
106 		return;
107 	os_memset(wpabuf_mhead(pw), 0, wpabuf_len(pw));
108 #ifdef __linux__
109 	if (munlock(wpabuf_head(pw), wpabuf_len(pw)) < 0) {
110 		wpa_printf(MSG_ERROR, "EXT PW: munlock failed: %s",
111 			   strerror(errno));
112 	}
113 #endif /* __linux__ */
114 	wpabuf_free(pw);
115 }
116