1* /*
2*  * External backend for file-backed passwords
3*  * Copyright (c) 2021, Patrick Steinhardt <ps@pks.im>
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* #include "utils/common.h"
12* #include "utils/config.h"
13* #include "ext_password_i.h"
14* 
15* 
16* /**
17*  * Data structure for the file-backed password backend.
18*  */
19* struct ext_password_file_data {
20* 	char *path; /* path of the password file */
21* };
22* 
23* 
24* /**
25*  * ext_password_file_init - Initialize file-backed password backend
26*  * @params: Parameters passed by the user.
27*  * Returns: Pointer to the initialized backend.
28*  *
29*  * This function initializes a new file-backed password backend. The user is
30*  * expected to initialize this backend with the parameters being the path of
31*  * the file that contains the passwords.
32*  */
ext_password_file_init(const char * params)33* static void * ext_password_file_init(const char *params)
34* {
35* 	struct ext_password_file_data *data;
36* 
37* 	if (!params) {
38* 		wpa_printf(MSG_ERROR, "EXT PW FILE: no path given");
39* 		return NULL;
40* 	}
41* 
42* 	data = os_zalloc(sizeof(*data));
43* 	if (!data)
44* 		return NULL;
45* 
46* 	data->path = os_strdup(params);
47* 	if (!data->path) {
48* 		os_free(data);
49* 		return NULL;
50* 	}
51* 
52* 	return data;
53* }
54* 
55* 
56* /**
57*  * ext_password_file_deinit - Deinitialize file-backed password backend
58*  * @ctx: The file-backed password backend
59*  *
60*  * This function frees all data associated with the file-backed password
61*  * backend.
62*  */
ext_password_file_deinit(void * ctx)63* static void ext_password_file_deinit(void *ctx)
64* {
65* 	struct ext_password_file_data *data = ctx;
66* 
67* 	str_clear_free(data->path);
68* 	os_free(data);
69* }
70* 
71* /**
72*  * ext_password_file_get - Retrieve password from the file-backed password backend
73*  * @ctx: The file-backed password backend
74*  * @name: Name of the password to retrieve
75*  * Returns: Buffer containing the password if one was found or %NULL.
76*  *
77*  * This function tries to find a password identified by name in the password
78*  * file. The password is expected to be stored in `NAME=PASSWORD` format.
79*  * Comments and empty lines in the file are ignored. Invalid lines will cause
80*  * an error message, but will not cause the function to fail.
81*  */
ext_password_file_get(void * ctx,const char * name)82* static struct wpabuf * ext_password_file_get(void *ctx, const char *name)
83* {
84* 	struct ext_password_file_data *data = ctx;
85* 	struct wpabuf *password = NULL;
86* 	char buf[512], *pos;
87* 	int line = 0;
88* 	FILE *f;
89* 
90* 	f = fopen(data->path, "r");
91* 	if (!f) {
92* 		wpa_printf(MSG_ERROR,
93* 			   "EXT PW FILE: could not open file '%s': %s",
94* 			   data->path, strerror(errno));
95* 		return NULL;
96* 	}
97* 
98* 	wpa_printf(MSG_DEBUG, "EXT PW FILE: get(%s)", name);
99* 
100* 	while (wpa_config_get_line(buf, sizeof(buf), f, &line, &pos)) {
101* 		char *sep = os_strchr(pos, '=');
102* 
103* 		if (!sep) {
104* 			wpa_printf(MSG_ERROR, "Invalid password line %d.",
105* 				   line);
106* 			continue;
107* 		}
108* 
109* 		if (!sep[1]) {
110* 			wpa_printf(MSG_ERROR, "No password for line %d.", line);
111* 			continue;
112* 
113* 		}
114* 
115* 		if (os_strncmp(name, pos, sep - pos) != 0)
116* 			continue;
117* 
118* 		password = wpabuf_alloc_copy(sep + 1, os_strlen(sep + 1));
119* 		goto done;
120* 	}
121* 
122* 	wpa_printf(MSG_ERROR, "Password for '%s' was not found.", name);
123* 
124* done:
125* 	forced_memzero(buf, sizeof(buf));
126* 	fclose(f);
127* 	return password;
128* }
129* 
130* 
131* const struct ext_password_backend ext_password_file = {
132* 	.name = "file",
133* 	.init = ext_password_file_init,
134* 	.deinit = ext_password_file_deinit,
135* 	.get = ext_password_file_get,
136* };
137*