summaryrefslogtreecommitdiffstats
path: root/pam_wlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'pam_wlan.c')
-rw-r--r--pam_wlan.c249
1 files changed, 14 insertions, 235 deletions
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 <stdio.h>
-
-#endif
-
-#include <stdlib.h>
-#include <string.h>
#include <unistd.h>
#include <sys/types.h>
@@ -54,237 +44,25 @@
#include <security/pam_modules.h>
-#include <nm-client.h>
-#include <nm-remote-settings.h>
-#include <nm-setting-connection.h>
-#include <nm-setting-wireless.h>
-#include <nm-setting-wireless-security.h>
-#include <nm-setting-8021x.h>
-#include <nm-setting-ip4-config.h>
-#include <nm-setting-ip6-config.h>
-
-
-#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 <config.h>
- /* 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