[X2Go-Commits] libpam-x2go.git - build-main (branch) updated: 343ae349c3645c8ad6f80215ceaf685a5b975cc7

X2Go dev team git-admin at x2go.org
Sat Apr 27 13:45:38 CEST 2013


The branch, build-main has been updated
       via  343ae349c3645c8ad6f80215ceaf685a5b975cc7 (commit)
      from  c06ef184d455532c267526f82fb73f00081f70f9 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
-----------------------------------------------------------------------

Summary of changes:
 src/Makefile.am               |    3 +-
 src/pam-freerdp.c             |  196 ++---------------------------------------
 tests/mock_guest.c            |   71 +++++++++++++++
 tests/mock_guest.h            |    2 +
 tests/test-freerdp-wrapper.cc |    2 +
 5 files changed, 82 insertions(+), 192 deletions(-)

The diff of changes is:
diff --git a/src/Makefile.am b/src/Makefile.am
index 34d1ddd..ed9087c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,7 +23,8 @@ noinst_LTLIBRARIES = \
 	libfreerdpcore.la
 
 libfreerdpcore_la_SOURCES = \
-	pam-freerdp.c
+	pam-freerdp.c \
+	pam-freerdp-children.c
 libfreerdpcore_la_CFLAGS = \
 	-Wall -Werror \
 	$(COVERAGE_CFLAGS)
diff --git a/src/pam-freerdp.c b/src/pam-freerdp.c
index fbfe182..8979e6e 100644
--- a/src/pam-freerdp.c
+++ b/src/pam-freerdp.c
@@ -34,11 +34,9 @@
 #include <security/pam_modutil.h>
 #include <security/pam_appl.h>
 
+#include "pam-freerdp-children.h"
 #include "auth-check-path.h"
 
-#define PAM_TYPE_DOMAIN  1234
-#define ALL_GOOD_SIGNAL  "Ar, ready to authenticate cap'n"
-
 static int unpriveleged_kill (struct passwd * pwdent);
 
 static char * global_domain = NULL;
@@ -236,44 +234,7 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc, const char **argv)
 	pid_t pid;
 	switch (pid = fork()) {
 	case 0: { /* child */
-		dup2(stdinpipe[0], 0);
-
-		char * args[5];
-
-		args[0] = (char *)auth_check_path;
-		args[1] = rhost;
-		args[2] = ruser;
-		args[3] = rdomain;
-		args[4] = NULL;
-
-		struct passwd * pwdent = getpwnam(username);
-		if (pwdent == NULL) {
-			_exit(EXIT_FAILURE);
-		}
-
-		/* Setting groups, but allowing EPERM as if we're not 100% root
-		   we might not be able to do this */
-		if (setgroups(1, &pwdent->pw_gid) != 0 && errno != EPERM) {
-			_exit(EXIT_FAILURE);
-		}
-
-		if (setgid(pwdent->pw_gid) < 0 || setuid(pwdent->pw_uid) < 0 ||
-				setegid(pwdent->pw_gid) < 0 || seteuid(pwdent->pw_uid) < 0) {
-			_exit(EXIT_FAILURE);
-		}
-
-		if (clearenv() != 0) {
-			_exit(EXIT_FAILURE);
-		}
-
-		if (chdir(pwdent->pw_dir) != 0) {
-			_exit(EXIT_FAILURE);
-		}
-
-		setenv("HOME", pwdent->pw_dir, 1);
-
-		execvp(args[0], args);
-		_exit(EXIT_FAILURE);
+		pam_sm_authenticate_helper (stdinpipe, username, rhost, ruser, rdomain);
 		break;
 	}
 	case -1: { /* fork'n error! */
@@ -304,153 +265,7 @@ done:
 	return retval;
 }
 
-static int
-session_socket_handler (struct passwd * pwdent, int readypipe, const char * ruser, const char * rhost, const char * rdomain, const char * password)
-{
-	/* Socket stuff */
-	int socketfd = 0;
-	struct sockaddr_un socket_addr;
-
-	/* Connected user */
-	socklen_t connected_addr_size;
-	int connectfd = 0;
-	struct sockaddr_un connected_addr;
-
-	/* Our buffer */
-	char * buffer = NULL;
-	int buffer_len = 0;
-	int buffer_fill = 0;
-
-	/* Track write out */
-	int writedata = 0;
-
-	/* Track ready writing */
-	int readywrite = 0;
-
-	/* Setting groups, but allowing EPERM as if we're not 100% root
-	   we might not be able to do this */
-	if (setgroups(1, &pwdent->pw_gid) != 0 && errno != EPERM) {
-		_exit(EXIT_FAILURE);
-	}
-
-	if (setgid(pwdent->pw_gid) < 0 || setuid(pwdent->pw_uid) < 0 ||
-			setegid(pwdent->pw_gid) < 0 || seteuid(pwdent->pw_uid) < 0) {
-		/* Don't need to clean up yet */
-		return EXIT_FAILURE;
-	}
-
-	if (clearenv() != 0) {
-		/* Don't need to clean up yet */
-		return EXIT_FAILURE;
-	}
-
-	if (chdir(pwdent->pw_dir) != 0) {
-		/* Don't need to clean up yet */
-		return EXIT_FAILURE;
-	}
-
-	if (rdomain[0] == '\0') {
-		rdomain = ".";
-	}
-
-	/* Build this up as a buffer so we can just write it and see that
-	   very, very clearly */
-	buffer_len += strlen(ruser) + 1;    /* Add one for the space */
-	buffer_len += strlen(rhost) + 1;    /* Add one for the space */
-	buffer_len += strlen(rdomain) + 1;  /* Add one for the space */
-	buffer_len += strlen(password) + 1; /* Add one for the NULL */
-
-	if (buffer_len < 5) {
-		/* Don't need to clean up yet */
-		return EXIT_FAILURE;
-	}
-
-	buffer = malloc(buffer_len);
-
-	if (buffer == NULL) {
-		/* Don't need to clean up yet */
-		return EXIT_FAILURE;
-	}
-
-	/* Lock the buffer before writing */
-	if (mlock(buffer, buffer_len) != 0) {
-		/* We can't lock, we go home */
-		goto cleanup;
-	}
-
-	buffer_fill = snprintf(buffer, buffer_len, "%s %s %s %s", ruser, password, rdomain, rhost);
-	if (buffer_fill > buffer_len) {
-		/* This really shouldn't happen, but if for some reason we have an
-		   difference between they way that the lengths are calculated we want
-		   to catch that. */
-		goto cleanup;
-	}
-
-	/* Make our socket and bind it */
-	socketfd = socket(AF_UNIX, SOCK_STREAM, 0);
-	if (socketfd < 0) {
-		goto cleanup;
-	}
 
-	memset(&socket_addr, 0, sizeof(struct sockaddr_un));
-	socket_addr.sun_family = AF_UNIX;
-	strncpy(socket_addr.sun_path, pwdent->pw_dir, sizeof(socket_addr.sun_path) - 1);
-	strncpy(socket_addr.sun_path + strlen(pwdent->pw_dir), "/.freerdp-socket", (sizeof(socket_addr.sun_path) - strlen(pwdent->pw_dir)) - 1);
-
-	/* We bind the socket before forking so that we ensure that
-	   there isn't a race condition to get to it.  Things will block
-	   otherwise. */
-	if (bind(socketfd, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr_un)) < 0) {
-		goto cleanup;
-	}
-
-	/* Set the socket file permissions to be 600 and the user and group
-	   to be the guest user.  NOTE: This won't protect on BSD */
-	if (chmod(socket_addr.sun_path, S_IRUSR | S_IWUSR) != 0 ||
-			chown(socket_addr.sun_path, pwdent->pw_uid, pwdent->pw_gid) != 0) {
-		goto cleanup;
-	}
-
-	if (listen(socketfd, 1) < 0) {
-		goto cleanup;
-	}
-
-	readywrite = write(readypipe, ALL_GOOD_SIGNAL, strlen(ALL_GOOD_SIGNAL) + 1);
-	if (readywrite != strlen(ALL_GOOD_SIGNAL) + 1) {
-		goto cleanup;
-	}
-
-	connected_addr_size = sizeof(struct sockaddr_un);
-	connectfd = accept(socketfd, (struct sockaddr *)&connected_addr, &connected_addr_size);
-	if (connectfd < 0) {
-		goto cleanup;
-	}
-
-	writedata = write(connectfd, buffer, buffer_len);
-
-cleanup:
-	if (socketfd != 0) {
-		close(socketfd);
-	}
-	if (connectfd != 0) {
-		close(connectfd);
-	}
-
-	if (buffer != NULL) {
-		memset(buffer, 0, buffer_len);
-		munlock(buffer, buffer_len);
-		free(buffer);
-		buffer = NULL;
-	}
-
-	/* This should be only true on the write, so we can use this to check
-	   out as writedata is init to 0 */
-	if (writedata == buffer_len) {
-		return 0;
-	}
-
-	return EXIT_FAILURE;
-}
 
 pid_t session_pid = 0;
 /* Open Session.  Here we need to fork a little process so that we can
@@ -492,12 +307,11 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char ** argv
 
 	pid_t pid = fork();
 	if (pid == 0) {
-		int retval = 0;
-
-		retval = session_socket_handler(pwdent, sessionready[1], ruser, rhost, rdomain, password);
+		
+		int ret = session_socket_handler(pwdent, sessionready[1], ruser, rhost, rdomain, password);
 
 		close(sessionready[1]);
-		_exit(retval);
+		_exit(ret);
 	} else if (pid < 0) {
 		close(sessionready[0]);
 		close(sessionready[1]);
diff --git a/tests/mock_guest.c b/tests/mock_guest.c
index 2cf04b3..8bf2c3a 100644
--- a/tests/mock_guest.c
+++ b/tests/mock_guest.c
@@ -9,6 +9,11 @@
 #include <errno.h>
 #include <unistd.h>
 #include <sys/stat.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <stdio.h>
 
 static struct passwd guest = { "guest",
 							   "password",
@@ -49,3 +54,69 @@ int chmod(const char *path, mode_t mode)
 int chown(const char *path, uid_t owner, gid_t group)
 { return 0; }
 
+int execvp(const char *file, char *const argv[])
+{
+	return 0;
+}
+/* wrap _exit, to make sure the gcov_exit function installed with atexit()
+   is really called to collect coverage statistics */
+void _exit (int exitcode)
+{
+	exit (exitcode);
+}
+
+
+#define BUFFER_SIZE  512
+
+/*Borrowed this code form socket-sucker.c in lightdm-remote-session-freerdp*/
+int
+socket_sucker ()
+{
+	int socket_fd = 0;
+	int servlen = 0;
+	struct sockaddr_un serv_addr;
+
+	bzero((char *)&serv_addr, sizeof(serv_addr));
+
+	const char * home = getenv("HOME");
+	if (home == NULL) {
+		return -1;
+	}
+
+	serv_addr.sun_family = AF_UNIX;
+	
+	int printsize = snprintf(serv_addr.sun_path, sizeof(serv_addr.sun_path) - 1, "%s/%s", home, ".freerdp-socket");
+	if (printsize > sizeof(serv_addr.sun_path) - 1 || printsize < 0) {
+		return -1;
+	}
+
+	servlen = strlen(serv_addr.sun_path) + sizeof(serv_addr.sun_family);
+
+	if ((socket_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+		return -1;
+	}
+
+	if (connect(socket_fd, (struct sockaddr *)&serv_addr, servlen) < 0) {
+		return -1;
+	}
+
+	char buffer[BUFFER_SIZE + 2];
+	int in = 0;
+	int out = 0;
+
+	in = read(socket_fd, buffer, BUFFER_SIZE);
+
+	if (in > 0) {
+		out = write(1, buffer, in);
+	}
+
+	close(socket_fd);
+
+	if (in > 0 && out > 0 && in == out) {
+		return 0;
+	} else {
+		return -1;
+	}
+}
+
+
diff --git a/tests/mock_guest.h b/tests/mock_guest.h
index c4179b9..2c17536 100644
--- a/tests/mock_guest.h
+++ b/tests/mock_guest.h
@@ -20,5 +20,7 @@ int setegid(gid_t gid);
 int seteuid(uid_t uid);
 int chmod(const char *path, mode_t mode);
 int chown(const char *path, uid_t owner, gid_t group);
+int execvp(const char *file, char *const argv[]);
+int socket_sucker();
 
 #endif
diff --git a/tests/test-freerdp-wrapper.cc b/tests/test-freerdp-wrapper.cc
index cfe86de..147682d 100644
--- a/tests/test-freerdp-wrapper.cc
+++ b/tests/test-freerdp-wrapper.cc
@@ -67,8 +67,10 @@ namespace {
 				 pam_sm_authenticate (pamh, 0, 0, argv));
 	  EXPECT_EQ (PAM_SUCCESS, 
 				 pam_sm_setcred (pamh, 0, 0, argv));
+	  
 	  EXPECT_EQ (PAM_SUCCESS, 
 				 pam_sm_open_session (pamh, 0, 0, argv));
+	  EXPECT_EQ(0, socket_sucker()); 
 	  EXPECT_EQ (PAM_SUCCESS, 
 				 pam_sm_close_session (pamh, 0, 0, argv));
   }


hooks/post-receive
-- 
libpam-x2go.git (Remote login session via X2Go (PAM module))

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "libpam-x2go.git" (Remote login session via X2Go (PAM module)).




More information about the x2go-commits mailing list