[X2Go-Commits] libpam-x2go.git - x2gosession (branch) updated: b17e449c99af738d4cbc8c5d177a1b6943f601d7

X2Go dev team git-admin at x2go.org
Wed Apr 24 18:47:30 CEST 2013


The branch, x2gosession has been updated
       via  b17e449c99af738d4cbc8c5d177a1b6943f601d7 (commit)
      from  343ae349c3645c8ad6f80215ceaf685a5b975cc7 (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/pam-freerdp-children.c                         |  231 ++++++++++++++++++++
 .../pam-freerdp-children.h                         |   45 +---
 2 files changed, 240 insertions(+), 36 deletions(-)
 create mode 100644 src/pam-freerdp-children.c
 copy tests/test-freerdp-auth.c => src/pam-freerdp-children.h (56%)

The diff of changes is:
diff --git a/src/pam-freerdp-children.c b/src/pam-freerdp-children.c
new file mode 100644
index 0000000..ea29c14
--- /dev/null
+++ b/src/pam-freerdp-children.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright © 2012 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Ted Gould <ted at canonical.com>
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/un.h>
+#include <pwd.h>
+#include <grp.h>
+#include <errno.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/pam_appl.h>
+
+#include "pam-freerdp-children.h"
+#include "auth-check-path.h"
+
+void
+pam_sm_authenticate_helper (int *stdinpipe, const char* username, const char* rhost, const char* ruser, const char* rdomain)
+{
+
+	dup2(stdinpipe[0], 0);
+
+	char * args[5];
+
+	args[0] = (char *)auth_check_path;
+	args[1] = (char *)rhost;
+	args[2] = (char *)ruser;
+	args[3] = (char *)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(0);
+}
+
+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) {
+		_exit (0);
+	}
+
+	_exit(EXIT_FAILURE);
+}
+
diff --git a/tests/test-freerdp-auth.c b/src/pam-freerdp-children.h
similarity index 56%
copy from tests/test-freerdp-auth.c
copy to src/pam-freerdp-children.h
index a83885e..cb36312 100644
--- a/tests/test-freerdp-auth.c
+++ b/src/pam-freerdp-children.h
@@ -16,42 +16,15 @@
  * Author: Ted Gould <ted at canonical.com>
  */
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
+#ifndef _PAM_FREERDP_CHILDREN_H_
+#define _PAM_FREERDP_CHILDREN_H_
 
-int
-main (int argc, char * argv[])
-{
-	char password[512];
-	if (argc != 4) {
-		printf("Not enough params");
-		return -1;
-	}
-
-	if (scanf("%511s", password) != 1) {
-		return -1;
-	}
-
-	/* Check username */
-	if (strcmp(argv[2], "ruser")) {
-		return -1;
-	}
+#define PAM_TYPE_DOMAIN  1234
+#define ALL_GOOD_SIGNAL  "Ar, ready to authenticate cap'n"
 
-	/* Check password */
-	if (strcmp(password, "password")) {
-		return -1;
-	}
+void
+pam_sm_authenticate_helper (int *stdinpipe, const char* username, const char* rhost, const char* ruser, const char* rdomain);
 
-	/* Check domain */
-	if (strcmp(argv[3], "domain")) {
-		return -1;
-	}
-
-	/* Check hostname */
-	if (strcmp(argv[1], "rhost")) {
-		return -1;
-	}
-
-	return 0;
-}
+int
+session_socket_handler (struct passwd * pwdent, int readypipe, const char * ruser, const char * rhost, const char * rdomain, const char * password);
+#endif //_PAM_FREERDP_CHILDREN_H_


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