#define _GNU_SOURCE
#define __USE_GNU
+#include <config.h>
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
#include <pwd.h>
#include <unistd.h>
#include <dirent.h>
#include <xcb/xcb.h>
#include <gio/gunixsocketaddress.h>
+#if HAVE_LIBAUDIT
+#include <libaudit.h>
+#endif
+
#include "status.h"
#define LOGIN_PROMPT "login:"
-static int console_fd = -1;
+static int tty_fd = -1;
static GList *user_entries = NULL;
static GList *getpwent_link = NULL;
struct pam_conv conversation;
};
+int
+gethostname (char *name, size_t len)
+{
+ snprintf (name, len, "lightdm-test");
+ return 0;
+}
+
uid_t
getuid (void)
{
if (g_str_has_prefix (path, "/tmp"))
return g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "tmp", path + strlen ("/tmp"), NULL);
+ if (g_str_has_prefix (path, "/run"))
+ return g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "run", path + strlen ("/run"), NULL);
+
if (g_str_has_prefix (path, "/etc/xdg"))
return g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "etc", "xdg", path + strlen ("/etc/xdg"), NULL);
_open = (int (*)(const char *pathname, int flags, mode_t mode)) dlsym (RTLD_NEXT, func);
- if (strcmp (pathname, "/dev/console") == 0)
+ if (strcmp (pathname, "/dev/tty0") == 0)
{
- if (console_fd < 0)
+ if (tty_fd < 0)
{
- console_fd = _open ("/dev/null", flags, mode);
- fcntl (console_fd, F_SETFD, FD_CLOEXEC);
+ tty_fd = _open ("/dev/null", flags, mode);
+ fcntl (tty_fd, F_SETFD, FD_CLOEXEC);
}
- return console_fd;
+ return tty_fd;
}
new_path = redirect_path (pathname);
_access = (int (*)(const char *pathname, int mode)) dlsym (RTLD_NEXT, "access");
+ if (strcmp (pathname, "/dev/tty0") == 0)
+ return F_OK;
+ if (strcmp (pathname, "/sys/class/tty/tty0/active") == 0)
+ return F_OK;
+
new_path = redirect_path (pathname);
ret = _access (new_path, mode);
g_free (new_path);
int (*_stat) (const char *path, struct stat *buf);
gchar *new_path = NULL;
int ret;
-
+
_stat = (int (*)(const char *path, struct stat *buf)) dlsym (RTLD_NEXT, "stat");
new_path = redirect_path (path);
int (*___xstat) (int version, const char *path, struct stat *buf);
gchar *new_path = NULL;
int ret;
-
+
___xstat = (int (*)(int version, const char *path, struct stat *buf)) dlsym (RTLD_NEXT, "__xstat");
new_path = redirect_path (path);
int (*___xstat64) (int version, const char *path, struct stat64 *buf);
gchar *new_path = NULL;
int ret;
-
+
___xstat64 = (int (*)(int version, const char *path, struct stat64 *buf)) dlsym (RTLD_NEXT, "__xstat64");
new_path = redirect_path (path);
int (*___fxstatat) (int ver, int dirfd, const char *pathname, struct stat *buf, int flags);
gchar *new_path = NULL;
int ret;
-
+
___fxstatat = (int (*)(int ver, int dirfd, const char *pathname, struct stat *buf, int flags)) dlsym (RTLD_NEXT, "__fxstatat");
new_path = redirect_path (pathname);
int (*___fxstatat64) (int ver, int dirfd, const char *pathname, struct stat64 *buf, int flags);
gchar *new_path = NULL;
int ret;
-
+
___fxstatat64 = (int (*)(int ver, int dirfd, const char *pathname, struct stat64 *buf, int flags)) dlsym (RTLD_NEXT, "__fxstatat64");
new_path = redirect_path (pathname);
result = _opendir (new_path);
g_free (new_path);
- return result;
+ return result;
}
int
int (*_ioctl) (int d, int request, ...);
_ioctl = (int (*)(int d, int request, ...)) dlsym (RTLD_NEXT, "ioctl");
- if (d > 0 && d == console_fd)
+ if (d > 0 && d == tty_fd)
{
- struct vt_stat *console_state;
+ struct vt_stat *vt_state;
int vt;
va_list ap;
{
case VT_GETSTATE:
va_start (ap, request);
- console_state = va_arg (ap, struct vt_stat *);
+ vt_state = va_arg (ap, struct vt_stat *);
va_end (ap);
- console_state->v_active = active_vt;
+ vt_state->v_active = active_vt;
break;
case VT_ACTIVATE:
va_start (ap, request);
}
}
+static void
+add_port_redirect (int requested_port, int redirected_port)
+{
+ GKeyFile *file;
+ gchar *path, *name, *data;
+
+ file = g_key_file_new ();
+ path = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), ".port-redirects", NULL);
+ g_key_file_load_from_file (file, path, G_KEY_FILE_NONE, NULL);
+
+ name = g_strdup_printf ("%d", requested_port);
+ g_key_file_set_integer (file, name, "redirected", redirected_port);
+ g_free (name);
+
+ data = g_key_file_to_data (file, NULL, NULL);
+ g_file_set_contents (path, data, -1, NULL);
+ g_free (data);
+ g_free (path);
+
+ g_key_file_free (file);
+}
+
+static int
+find_port_redirect (int port)
+{
+ GKeyFile *file;
+ gchar *path, *name;
+ int redirected_port;
+
+ file = g_key_file_new ();
+ path = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), ".port-redirects", NULL);
+ g_key_file_load_from_file (file, path, G_KEY_FILE_NONE, NULL);
+ g_free (path);
+
+ name = g_strdup_printf ("%d", port);
+ redirected_port = g_key_file_get_integer (file, name, "redirected", NULL);
+ g_free (name);
+ g_key_file_free (file);
+
+ return redirected_port;
+}
+
+int
+bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
+{
+ int port = 0, redirected_port = 0;
+ const char *path;
+ int (*_bind) (int sockfd, const struct sockaddr *addr, socklen_t addrlen);
+ const struct sockaddr *modified_addr = addr;
+ struct sockaddr_in temp_addr_in;
+ struct sockaddr_in6 temp_addr_in6;
+ struct sockaddr_un temp_addr_un;
+ int retval;
+
+ _bind = (int (*)(int sockfd, const struct sockaddr *addr, socklen_t addrlen)) dlsym (RTLD_NEXT, "bind");
+
+ switch (addr->sa_family)
+ {
+ case AF_UNIX:
+ path = ((const struct sockaddr_un *) addr)->sun_path;
+ if (path[0] != '\0')
+ {
+ gchar *new_path = redirect_path (path);
+ memcpy (&temp_addr_un, addr, sizeof (struct sockaddr_un));
+ strncpy (temp_addr_un.sun_path, new_path, sizeof (temp_addr_un.sun_path) - 1);
+ g_free (new_path);
+ modified_addr = (struct sockaddr *) &temp_addr_un;
+ }
+ break;
+ case AF_INET:
+ port = ntohs (((const struct sockaddr_in *) addr)->sin_port);
+ redirected_port = find_port_redirect (port);
+ memcpy (&temp_addr_in, addr, sizeof (struct sockaddr_in));
+ modified_addr = (struct sockaddr *) &temp_addr_in;
+ if (redirected_port != 0)
+ temp_addr_in.sin_port = htons (redirected_port);
+ else
+ temp_addr_in.sin_port = 0;
+ break;
+ case AF_INET6:
+ port = ntohs (((const struct sockaddr_in6 *) addr)->sin6_port);
+ redirected_port = find_port_redirect (port);
+ memcpy (&temp_addr_in6, addr, sizeof (struct sockaddr_in6));
+ modified_addr = (struct sockaddr *) &temp_addr_in6;
+ if (redirected_port != 0)
+ temp_addr_in6.sin6_port = htons (redirected_port);
+ else
+ temp_addr_in6.sin6_port = 0;
+ break;
+ }
+
+ retval = _bind (sockfd, modified_addr, addrlen);
+
+ socklen_t temp_addr_len;
+ switch (addr->sa_family)
+ {
+ case AF_INET:
+ temp_addr_len = sizeof (temp_addr_in);
+ getsockname (sockfd, &temp_addr_in, &temp_addr_len);
+ if (redirected_port == 0)
+ {
+ redirected_port = ntohs (temp_addr_in.sin_port);
+ add_port_redirect (port, redirected_port);
+ }
+ break;
+ case AF_INET6:
+ temp_addr_len = sizeof (temp_addr_in6);
+ getsockname (sockfd, &temp_addr_in6, &temp_addr_len);
+ if (redirected_port == 0)
+ {
+ redirected_port = ntohs (temp_addr_in6.sin6_port);
+ add_port_redirect (port, redirected_port);
+ }
+ break;
+ }
+
+ return retval;
+}
+
+#include <ctype.h>
+
+int
+connect (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
+{
+ int port, redirected_port;
+ const char *path;
+ const struct sockaddr *modified_addr = addr;
+ struct sockaddr_in temp_addr_in;
+ struct sockaddr_in6 temp_addr_in6;
+ struct sockaddr_un temp_addr_un;
+ int (*_connect) (int sockfd, const struct sockaddr *addr, socklen_t addrlen);
+
+ _connect = (int (*)(int sockfd, const struct sockaddr *addr, socklen_t addrlen)) dlsym (RTLD_NEXT, "connect");
+
+ switch (addr->sa_family)
+ {
+ case AF_UNIX:
+ path = ((const struct sockaddr_un *) addr)->sun_path;
+ if (path[0] != '\0')
+ {
+ gchar *new_path = redirect_path (path);
+ memcpy (&temp_addr_un, addr, addrlen);
+ strncpy (temp_addr_un.sun_path, new_path, sizeof (temp_addr_un.sun_path) - 1);
+ g_free (new_path);
+ modified_addr = (struct sockaddr *) &temp_addr_un;
+ }
+ break;
+ case AF_INET:
+ port = ntohs (((const struct sockaddr_in *) addr)->sin_port);
+ redirected_port = find_port_redirect (port);
+ if (redirected_port != 0)
+ {
+ memcpy (&temp_addr_in, addr, sizeof (struct sockaddr_in));
+ temp_addr_in.sin_port = htons (redirected_port);
+ modified_addr = (struct sockaddr *) &temp_addr_in;
+ }
+ break;
+ case AF_INET6:
+ port = ntohs (((const struct sockaddr_in6 *) addr)->sin6_port);
+ redirected_port = find_port_redirect (port);
+ if (redirected_port != 0)
+ {
+ memcpy (&temp_addr_in6, addr, sizeof (struct sockaddr_in6));
+ temp_addr_in6.sin6_port = htons (redirected_port);
+ modified_addr = (struct sockaddr *) &temp_addr_in6;
+ }
+ break;
+ }
+
+ return _connect (sockfd, modified_addr, addrlen);
+}
+
+ssize_t
+sendto (int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)
+{
+ int port, redirected_port;
+ const char *path;
+ const struct sockaddr *modified_addr = dest_addr;
+ struct sockaddr_in temp_addr_in;
+ struct sockaddr_in6 temp_addr_in6;
+ struct sockaddr_un temp_addr_un;
+ ssize_t (*_sendto) (int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
+
+ _sendto = (ssize_t (*)(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)) dlsym (RTLD_NEXT, "sendto");
+
+ switch (dest_addr->sa_family)
+ {
+ case AF_UNIX:
+ path = ((const struct sockaddr_un *) dest_addr)->sun_path;
+ if (path[0] != '\0')
+ {
+ gchar *new_path = redirect_path (path);
+ memcpy (&temp_addr_un, dest_addr, sizeof (struct sockaddr_un));
+ strncpy (temp_addr_un.sun_path, new_path, sizeof (temp_addr_un.sun_path) - 1);
+ g_free (new_path);
+ modified_addr = (struct sockaddr *) &temp_addr_un;
+ }
+ break;
+ case AF_INET:
+ port = ntohs (((const struct sockaddr_in *) dest_addr)->sin_port);
+ redirected_port = find_port_redirect (port);
+ if (redirected_port != 0)
+ {
+ memcpy (&temp_addr_in, dest_addr, sizeof (struct sockaddr_in));
+ temp_addr_in.sin_port = htons (redirected_port);
+ modified_addr = (struct sockaddr *) &temp_addr_in;
+ }
+ break;
+ case AF_INET6:
+ port = ntohs (((const struct sockaddr_in6 *) dest_addr)->sin6_port);
+ redirected_port = find_port_redirect (port);
+ if (redirected_port != 0)
+ {
+ memcpy (&temp_addr_in6, dest_addr, sizeof (struct sockaddr_in6));
+ temp_addr_in6.sin6_port = htons (redirected_port);
+ modified_addr = (struct sockaddr *) &temp_addr_in6;
+ }
+ break;
+ }
+
+ return _sendto (sockfd, buf, len, flags, modified_addr, addrlen);
+}
+
int
close (int fd)
{
int (*_close) (int fd);
- if (fd > 0 && fd == console_fd)
+ if (fd > 0 && fd == tty_fd)
return 0;
_close = (int (*)(int fd)) dlsym (RTLD_NEXT, "close");
free_user (gpointer data)
{
struct passwd *entry = data;
-
+
g_free (entry->pw_name);
g_free (entry->pw_passwd);
g_free (entry->pw_gecos);
getpwnam (const char *name)
{
GList *link;
-
+
if (name == NULL)
return NULL;
-
+
load_passwd_file ();
for (link = user_entries; link; link = link->next)
free_group (gpointer data)
{
struct group *entry = data;
-
+
g_free (entry->gr_name);
g_free (entry->gr_passwd);
g_strfreev (entry->gr_mem);
status_notify ("%s", status->str);
g_string_free (status, TRUE);
}
-
+
if (strcmp (pamh->service_name, "test-remote") == 0)
{
int result;
msg = malloc (sizeof (struct pam_message *) * 1);
msg[0] = malloc (sizeof (struct pam_message));
- msg[0]->msg_style = PAM_PROMPT_ECHO_ON;
+ msg[0]->msg_style = PAM_PROMPT_ECHO_ON;
msg[0]->msg = "remote-login:";
result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
free (msg[0]);
msg = malloc (sizeof (struct pam_message *) * 1);
msg[0] = malloc (sizeof (struct pam_message));
- msg[0]->msg_style = PAM_PROMPT_ECHO_ON;
+ msg[0]->msg_style = PAM_PROMPT_ECHO_ON;
msg[0]->msg = LOGIN_PROMPT;
result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
free (msg[0]);
free (resp);
return PAM_CONV_ERR;
}
-
+
pamh->user = strdup (resp[0].resp);
free (resp[0].resp);
free (resp);
result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
free (msg[0]);
free (msg);
+ if (result != PAM_SUCCESS)
+ return result;
if (resp == NULL)
return PAM_CONV_ERR;
get_env_value (const char *name_value, const char *name)
{
int j;
-
+
for (j = 0; name[j] && name_value[j] && name[j] == name_value[j]; j++);
if (name[j] == '\0' && name_value[j] == '=')
return &name_value[j + 1];
{
if (pamh == NULL || item == NULL)
return PAM_SYSTEM_ERR;
-
+
switch (item_type)
{
case PAM_SERVICE:
*item = pamh->service_name;
return PAM_SUCCESS;
-
+
case PAM_USER:
*item = pamh->user;
return PAM_SUCCESS;
case PAM_RUSER:
*item = pamh->ruser;
return PAM_SUCCESS;
-
+
case PAM_USER_PROMPT:
*item = LOGIN_PROMPT;
return PAM_SUCCESS;
-
+
case PAM_TTY:
*item = pamh->tty;
return PAM_SUCCESS;
status_notify ("%s", status->str);
g_string_free (status, TRUE);
}
-
+
if (!pamh->user)
return PAM_USER_UNKNOWN;
xcb_connection_t *c;
gchar *socket_path;
GError *error = NULL;
-
+
c = malloc (sizeof (xcb_connection_t));
c->display = g_strdup (display);
c->error = 0;
g_object_unref (c->socket);
free (c);
}
+
+#if HAVE_LIBAUDIT
+int
+audit_open (void)
+{
+ connect_status ();
+ if (g_key_file_get_boolean (config, "test-audit-config", "check-events", NULL))
+ status_notify ("AUDIT OPEN");
+
+ return dup (STDOUT_FILENO);
+}
+
+int
+audit_log_acct_message (int audit_fd, int type, const char *pgname,
+ const char *op, const char *name, unsigned int id,
+ const char *host, const char *addr, const char *tty, int result)
+{
+ gchar *type_string;
+
+ connect_status ();
+ if (!g_key_file_get_boolean (config, "test-audit-config", "check-events", NULL))
+ return 1;
+
+ switch (type)
+ {
+ case AUDIT_USER_LOGIN:
+ type_string = g_strdup ("USER_LOGIN");
+ break;
+ case AUDIT_USER_LOGOUT:
+ type_string = g_strdup ("USER_LOGOUT");
+ break;
+ default:
+ type_string = g_strdup_printf ("%d", type);
+ break;
+ }
+
+ status_notify ("AUDIT LOG-ACCT TYPE=%s PGNAME=%s OP=%s NAME=%s ID=%u HOST=%s ADDR=%s TTY=%s RESULT=%d",
+ type_string, pgname ? pgname : "", op ? op : "", name ? name : "", id, host ? host : "", addr ? addr : "", tty ? tty : "", result);
+
+ g_free (type_string);
+
+ return 1;
+}
+
+#endif