ext_password.c revision 61d9df3e62aaa0e87ad05452fcb95142159a17b6
16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*
26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * External password backend
36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * Copyright (c) 2012, Jouni Malinen <j@w1.fi>
46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *
56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * This software may be distributed under the terms of the BSD license.
66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn * See README for more details.
76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn */
86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "includes.h"
106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef __linux__
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include <sys/mman.h>
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif /* __linux__ */
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "common.h"
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "ext_password_i.h"
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef CONFIG_EXT_PASSWORD_TEST
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennextern struct ext_password_backend ext_password_test;
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif /* CONFIG_EXT_PASSWORD_TEST */
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const struct ext_password_backend *backends[] = {
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef CONFIG_EXT_PASSWORD_TEST
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	&ext_password_test,
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif /* CONFIG_EXT_PASSWORD_TEST */
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	NULL
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstruct ext_password_data {
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	const struct ext_password_backend *backend;
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	void *priv;
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstruct ext_password_data * ext_password_init(const char *backend,
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn					     const char *params)
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	struct ext_password_data *data;
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	int i;
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	data = os_zalloc(sizeof(*data));
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	if (data == NULL)
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn		return NULL;
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	for (i = 0; backends[i]; i++) {
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn		if (os_strcmp(backends[i]->name, backend) == 0) {
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn			data->backend = backends[i];
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn			break;
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn		}
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	}
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	if (!data->backend) {
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn		os_free(data);
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn		return NULL;
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	}
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	data->priv = data->backend->init(params);
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	if (data->priv == NULL) {
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn		os_free(data);
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn		return NULL;
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	}
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	return data;
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid ext_password_deinit(struct ext_password_data *data)
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	if (data && data->backend && data->priv)
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn		data->backend->deinit(data->priv);
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	os_free(data);
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstruct wpabuf * ext_password_get(struct ext_password_data *data,
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn				 const char *name)
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	if (data == NULL)
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn		return NULL;
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	return data->backend->get(data->priv, name);
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstruct wpabuf * ext_password_alloc(size_t len)
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	struct wpabuf *buf;
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	buf = wpabuf_alloc(len);
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	if (buf == NULL)
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn		return NULL;
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef __linux__
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	if (mlock(wpabuf_head(buf), wpabuf_len(buf)) < 0) {
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn		wpa_printf(MSG_ERROR, "EXT PW: mlock failed: %s",
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn			   strerror(errno));
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	}
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif /* __linux__ */
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	return buf;
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennvoid ext_password_free(struct wpabuf *pw)
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	if (pw == NULL)
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn		return;
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	os_memset(wpabuf_mhead(pw), 0, wpabuf_len(pw));
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef __linux__
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	if (munlock(wpabuf_head(pw), wpabuf_len(pw)) < 0) {
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn		wpa_printf(MSG_ERROR, "EXT PW: munlock failed: %s",
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn			   strerror(errno));
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	}
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif /* __linux__ */
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	wpabuf_free(pw);
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn