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*