From 11f2c30f5b58de7c543ffc3e93fd508e3c8bcab3 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 12 May 2015 16:35:54 +0200 Subject: Split module into a helper executable and a minimal module --- pam_wlan.c | 249 ++++--------------------------------------------------------- 1 file changed, 14 insertions(+), 235 deletions(-) (limited to 'pam_wlan.c') diff --git a/pam_wlan.c b/pam_wlan.c index 181bb6a..81abe8a 100644 --- a/pam_wlan.c +++ b/pam_wlan.c @@ -26,27 +26,17 @@ /* - Helpful pages: + See: http://www.linux-pam.org/Linux-PAM-html/mwg-expected-of-module-auth.html http://www.linux-pam.org/Linux-PAM-html/mwg-expected-by-module-item.html http://www.linux-pam.org/Linux-PAM-html/mwg-see-programming-libs.html some (bad) example.. https://github.com/beatgammit/simple-pam/blob/master/src/mypam.c - - https://developer.gnome.org/libnm-glib/0.9/ - https://developer.gnome.org/libnm-util/0.9/ */ #define PAM_SM_AUTH -#ifdef TEST - #include - -#endif - -#include -#include #include #include @@ -54,237 +44,25 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define TIMEOUT 10 -#define CONNECTION_ID "UzL-Wlan" -#define CONNECTION_UUID "af7b7f0b-3e09-442e-8841-f7d7482fa7b0" - -#define CONNECTION_SSID "UzL-Wlan" -#define CONNECTION_AUTH_ALG "open" -#define CONNECTION_KEY_MGMT "wpa-eap" -#define CONNECTION_EAP "ttls" -#define CONNECTION_PHASE2_AUTHEAP "mschapv2" - - -static GByteArray * string_to_byte_array(const char *str) { - size_t len = strlen(str); - GByteArray *ba = g_byte_array_sized_new(len); - - g_byte_array_append(ba, (const unsigned char *)str, len); - - return ba; -} - -static int setup_connection(NMConnection *con, const char *user, const char *pass) { - NMSetting *setting; - - /* NMSettingConnection */ - setting = nm_setting_connection_new(); - g_object_set(G_OBJECT(setting), - NM_SETTING_CONNECTION_UUID, CONNECTION_UUID, - NM_SETTING_CONNECTION_ID, CONNECTION_ID, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NULL); - nm_connection_add_setting(con, setting); - - /* NMSettingWireless */ - setting = nm_setting_wireless_new(); - GByteArray *ssid = string_to_byte_array(CONNECTION_SSID); - g_object_set(G_OBJECT(setting), - NM_SETTING_WIRELESS_SSID, ssid, - NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_INFRA, - NULL); - g_byte_array_unref(ssid); - nm_connection_add_setting(con, setting); - - /* NMSettingWirelessSecurity */ - setting = nm_setting_wireless_security_new(); - g_object_set(G_OBJECT(setting), - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, CONNECTION_AUTH_ALG, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, CONNECTION_KEY_MGMT, - NULL); - nm_connection_add_setting(con, setting); +#include - /* NMSetting8021x */ - setting = nm_setting_802_1x_new(); - /* TODO: Add certificate and subject check */ - nm_setting_802_1x_add_eap_method(NM_SETTING_802_1X(setting), CONNECTION_EAP); - g_object_set(setting, - NM_SETTING_802_1X_IDENTITY, user, - NM_SETTING_802_1X_PASSWORD, pass, - NM_SETTING_802_1X_PHASE2_AUTHEAP, CONNECTION_PHASE2_AUTHEAP, - NULL); - nm_connection_add_setting(con, setting); - /* NMSettingIP4Config */ - setting = nm_setting_ip4_config_new(); - g_object_set(G_OBJECT(setting), - NM_SETTING_IP4_CONFIG_METHOD, "auto", - NULL); - nm_connection_add_setting(con, setting); +#define UNUSED __attribute__((unused)) - /* NMSettingIP6Config */ - setting = nm_setting_ip6_config_new(); - g_object_set(G_OBJECT(setting), - NM_SETTING_IP6_CONFIG_METHOD, "auto", - NULL); - nm_connection_add_setting(con, setting); - - return PAM_SUCCESS; -} - -typedef struct { - int ret; - GMainLoop *loop; - NMClient *client; -} cb_arg; - - -static NMDevice * find_device(NMClient *client) { - size_t i; - const GPtrArray *devices = nm_client_get_devices(client); - - for (i = 0; i < devices->len; i++) { - NMDevice *device = g_ptr_array_index(devices, i); - - if (nm_device_get_device_type(device) == NM_DEVICE_TYPE_WIFI) - return device; - } - - return NULL; -} - -static void state_cb(NMDevice *device, GParamSpec *pspec, gpointer user_data) { - cb_arg *arg = user_data; - - NMActiveConnection *active_connection = nm_device_get_active_connection(device); - if (!active_connection) - return; - - NMActiveConnectionState state = nm_active_connection_get_state(active_connection); - - if (state != NM_ACTIVE_CONNECTION_STATE_ACTIVATING && state != NM_ACTIVE_CONNECTION_STATE_DEACTIVATING) { - if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) - arg->ret = PAM_SUCCESS; - - g_main_loop_quit(arg->loop); - } -} - -static void activate_cb(NMClient *client, NMActiveConnection *active_connection, GError *error, gpointer user_data) { - cb_arg *arg = user_data; - - if (error) - goto error; - - - return; - - error: - g_main_loop_quit(arg->loop); -} - -static void add_cb(NMRemoteSettings *settings, NMRemoteConnection *con, GError *error, gpointer user_data) { - cb_arg *arg = user_data; - - if (error) - goto error; - - NMDevice *device = find_device(arg->client); - if (!device) - goto error; - - g_signal_connect(device, "notify::state", G_CALLBACK(state_cb), arg); - nm_client_activate_connection(arg->client, NM_CONNECTION(con), device, NULL, activate_cb, arg); - return; - - error: - g_main_loop_quit(arg->loop); -} - -static int do_authenticate(const char *user, const char *pass) { - DBusGConnection *dbus = NULL; - NMRemoteSettings *settings = NULL; - NMConnection *con = NULL; - cb_arg arg = {}; - - arg.ret = PAM_SYSTEM_ERR; - arg.loop = g_main_loop_new(NULL, FALSE); - - arg.client = nm_client_new(); - if (!arg.client) - goto end; - - dbus = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL); - if (!dbus) - goto end; - - settings = nm_remote_settings_new(dbus); - if (!settings) - goto end; - - con = nm_connection_new(); - setup_connection(con, user, pass); - - if (!nm_remote_settings_add_connection_unsaved(settings, con, add_cb, &arg)) - goto end; - - arg.ret = PAM_AUTH_ERR; - - g_main_loop_run(arg.loop); - - end: - g_object_unref(con); - - g_object_unref(settings); - dbus_g_connection_unref(dbus); - g_object_unref(arg.client); - g_main_loop_unref(arg.loop); - - return arg.ret; -} static int authenticate(const char *user, const char *pass) { - int status; - int fds[2]; - if (pipe(fds)) - return PAM_SYSTEM_ERR; + FILE *stream = popen(PAM_WLAN_HELPER, "we"); - pid_t pid = fork(); - if (pid < 0) - return PAM_SYSTEM_ERR; - - if (pid == 0) { - close(fds[0]); - status = do_authenticate(user, pass); - write(fds[1], &status, sizeof(status)); - close(fds[1]); - _exit(0); - } - - close(fds[1]); + fputs(user, stream); + fputc(0, stream); + fputs(pass, stream); - if (waitpid(pid, NULL, 0) < 0) - goto error; + int status = fclose(stream); - if (read(fds[0], &status, sizeof(status)) != sizeof(status)) - goto error; - - close(fds[0]); - return status; - - error: - close(fds[0]); - return PAM_SYSTEM_ERR; + if (WIFEXITED(status)) + return WEXITSTATUS(status); + else + return PAM_SYSTEM_ERR; } #ifdef TEST @@ -304,7 +82,7 @@ int main(int argc, char *argv[]) { #else -PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, __attribute__((unused)) int flags, __attribute__((unused)) int argc, __attribute__((unused)) const char **argv) { +PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, UNUSED int flags, UNUSED int argc, UNUSED const char **argv) { const void *pass; const void *user; int result; @@ -319,4 +97,5 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, __attribute__((unused)) i return authenticate(user, pass); } + #endif -- cgit v1.2.3