Question about adding another parameter for OpenSSH

Rudolf Cejka cejkar at fit.vutbr.cz
Fri Nov 28 04:37:08 EST 2003


Hello,
  I need to allow for some people to execute ssh with one shared private
key for remote executing command on various machines. However, it is not
possible to set group permissions for private keys and it is possible
to have just one private key file for one user. Please, is it possible
to add patches into openssh development tree like these, so that standard
behavior of ssh is not changed, but when option GroupPrivateKey is used
with ssh, it is allowed to have group readable private key?

Thank you very much.

--- authfile.c.orig	Thu Nov 27 15:01:01 2003
+++ authfile.c	Thu Nov 27 16:50:39 2003
@@ -496,7 +496,7 @@
 }
 
 static int
-key_perm_ok(int fd, const char *filename)
+key_perm_ok(int fd, const char *filename, int group_private_key)
 {
 	struct stat st;
 
@@ -510,7 +510,10 @@
 #ifdef HAVE_CYGWIN
 	if (check_ntsec(filename))
 #endif
-	if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) {
+	if ((!group_private_key
+	    && (st.st_uid == getuid()) && (st.st_mode & 077) != 0)
+	    || (group_private_key && (st.st_uid == getuid()
+	    || st.st_gid == getgid()) && (st.st_mode & 007) != 0)) {
 		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
 		error("@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @");
 		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
@@ -525,14 +528,14 @@
 
 Key *
 key_load_private_type(int type, const char *filename, const char *passphrase,
-    char **commentp)
+    char **commentp, int group_private_key)
 {
 	int fd;
 
 	fd = open(filename, O_RDONLY);
 	if (fd < 0)
 		return NULL;
-	if (!key_perm_ok(fd, filename)) {
+	if (!key_perm_ok(fd, filename, group_private_key)) {
 		error("bad permissions: ignore key: %s", filename);
 		close(fd);
 		return NULL;
@@ -558,7 +561,7 @@
 
 Key *
 key_load_private(const char *filename, const char *passphrase,
-    char **commentp)
+    char **commentp, int group_private_key)
 {
 	Key *pub, *prv;
 	int fd;
@@ -566,7 +569,7 @@
 	fd = open(filename, O_RDONLY);
 	if (fd < 0)
 		return NULL;
-	if (!key_perm_ok(fd, filename)) {
+	if (!key_perm_ok(fd, filename, group_private_key)) {
 		error("bad permissions: ignore key: %s", filename);
 		close(fd);
 		return NULL;
--- authfile.h.orig	Thu Nov 27 16:28:31 2003
+++ authfile.h	Thu Nov 27 16:28:42 2003
@@ -18,8 +18,8 @@
 int	 key_save_private(Key *, const char *, const char *, const char *);
 Key	*key_load_public(const char *, char **);
 Key	*key_load_public_type(int, const char *, char **);
-Key	*key_load_private(const char *, const char *, char **);
-Key	*key_load_private_type(int, const char *, const char *, char **);
+Key	*key_load_private(const char *, const char *, char **, int);
+Key	*key_load_private_type(int, const char *, const char *, char **, int);
 Key	*key_load_private_pem(int, int, const char *, char **);
 
 #endif
--- readconf.c.orig	Thu Nov 27 18:04:27 2003
+++ readconf.c	Thu Nov 27 18:06:49 2003
@@ -105,7 +105,7 @@
 	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
 	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
-	oDeprecated, oUnsupported
+	oGroupPrivateKey, oDeprecated, oUnsupported
 } OpCodes;
 
 /* Textual representations of the tokens. */
@@ -188,6 +188,7 @@
 	{ "rekeylimit", oRekeyLimit },
 	{ "connecttimeout", oConnectTimeout },
 	{ "addressfamily", oAddressFamily },
+	{ "groupprivatekey", oGroupPrivateKey },
 	{ NULL, oBadOption }
 };
 
@@ -732,6 +733,10 @@
 		intptr = &options->enable_ssh_keysign;
 		goto parse_flag;
 
+	case oGroupPrivateKey:
+		intptr = &options->group_private_key;
+		goto parse_flag;
+
 	case oDeprecated:
 		debug("%s line %d: Deprecated option \"%s\"",
 		    filename, linenum, keyword);
@@ -859,6 +864,7 @@
 	options->no_host_authentication_for_localhost = - 1;
 	options->rekey_limit = - 1;
 	options->verify_host_key_dns = -1;
+	options->group_private_key = -1;
 }
 
 /*
@@ -973,6 +979,8 @@
 		options->rekey_limit = 0;
 	if (options->verify_host_key_dns == -1)
 		options->verify_host_key_dns = 0;
+	if (options->group_private_key == -1)
+		options->group_private_key = 0;
 	/* options->proxy_command should not be set by default */
 	/* options->user will be set in the main program if appropriate */
 	/* options->hostname will be set in the main program if appropriate */
--- readconf.h.orig	Thu Nov 27 15:19:30 2003
+++ readconf.h	Thu Nov 27 15:20:11 2003
@@ -87,6 +87,7 @@
 	int     num_identity_files;	/* Number of files for RSA/DSA identities. */
 	char   *identity_files[SSH_MAX_IDENTITY_FILES];
 	Key    *identity_keys[SSH_MAX_IDENTITY_FILES];
+	int	group_private_key;
 
 	/* Local TCP/IP forward requests. */
 	int     num_local_forwards;
--- ssh.c.orig	Thu Nov 27 16:31:08 2003
+++ ssh.c	Thu Nov 27 16:30:46 2003
@@ -634,11 +634,13 @@
 
 		PRIV_START;
 		sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
-		    _PATH_HOST_KEY_FILE, "", NULL);
+		    _PATH_HOST_KEY_FILE, "", NULL, options.group_private_key);
 		sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
-		    _PATH_HOST_DSA_KEY_FILE, "", NULL);
+		    _PATH_HOST_DSA_KEY_FILE, "", NULL,
+		    options.group_private_key);
 		sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
-		    _PATH_HOST_RSA_KEY_FILE, "", NULL);
+		    _PATH_HOST_RSA_KEY_FILE, "", NULL,
+		    options.group_private_key);
 		PRIV_END;
 
 		if (options.hostbased_authentication == 1 &&
--- ssh_config.5.orig	Thu Nov 27 17:40:32 2003
+++ ssh_config.5	Thu Nov 27 18:03:02 2003
@@ -349,6 +349,15 @@
 Specifies a file to use for the global
 host key database instead of
 .Pa /etc/ssh/ssh_known_hosts .
+.It Cm GroupPrivateKey
+If this flag is set to
+.Dq yes ,
+ssh will allow to have private key file with group permissions set.
+If the option is set to
+.Dq no ,
+only user is allowed to own the private key file.
+The default is
+.Dq no .
 .It Cm GSSAPIAuthentication
 Specifies whether authentication based on GSSAPI may be used, either using
 the result of a successful key exchange, or using GSSAPI user
--- sshconnect1.c.orig	Thu Nov 27 16:31:20 2003
+++ sshconnect1.c	Thu Nov 27 16:32:05 2003
@@ -243,7 +243,8 @@
 	if (public->flags & KEY_FLAG_EXT)
 		private = public;
 	else
-		private = key_load_private_type(KEY_RSA1, authfile, "", NULL);
+		private = key_load_private_type(KEY_RSA1, authfile, "", NULL,
+		    options.group_private_key);
 	if (private == NULL && !options.batch_mode) {
 		snprintf(buf, sizeof(buf),
 		    "Enter passphrase for RSA key '%.100s': ", comment);
@@ -251,7 +252,8 @@
 			passphrase = read_passphrase(buf, 0);
 			if (strcmp(passphrase, "") != 0) {
 				private = key_load_private_type(KEY_RSA1,
-				    authfile, passphrase, NULL);
+				    authfile, passphrase, NULL,
+				    options.group_private_key);
 				quit = 0;
 			} else {
 				debug2("no passphrase given, try next key");
--- sshconnect2.c.orig	Thu Nov 27 16:31:25 2003
+++ sshconnect2.c	Thu Nov 27 16:36:38 2003
@@ -967,7 +967,8 @@
 		debug3("no such identity: %s", filename);
 		return NULL;
 	}
-	private = key_load_private_type(KEY_UNSPEC, filename, "", NULL);
+	private = key_load_private_type(KEY_UNSPEC, filename, "", NULL,
+	    options.group_private_key);
 	if (private == NULL) {
 		if (options.batch_mode)
 			return NULL;
@@ -977,7 +978,8 @@
 			passphrase = read_passphrase(prompt, 0);
 			if (strcmp(passphrase, "") != 0) {
 				private = key_load_private_type(KEY_UNSPEC, filename,
-				    passphrase, NULL);
+				    passphrase, NULL,
+				    options.group_private_key);
 				quit = 0;
 			} else {
 				debug2("no passphrase given, try next key");
--- sshd.c.orig	Thu Nov 27 16:33:07 2003
+++ sshd.c	Thu Nov 27 16:35:19 2003
@@ -966,7 +966,7 @@
 	sensitive_data.have_ssh2_key = 0;
 
 	for (i = 0; i < options.num_host_key_files; i++) {
-		key = key_load_private(options.host_key_files[i], "", NULL);
+		key = key_load_private(options.host_key_files[i], "", NULL, 0);
 		sensitive_data.host_keys[i] = key;
 		if (key == NULL) {
 			error("Could not load host key: %s",
--- ssh-add.c.orig	Thu Nov 27 18:14:33 2003
+++ ssh-add.c	Thu Nov 27 18:15:04 2003
@@ -142,12 +142,12 @@
 		return -1;
 	}
 	/* At first, try empty passphrase */
-	private = key_load_private(filename, "", &comment);
+	private = key_load_private(filename, "", &comment, 0);
 	if (comment == NULL)
 		comment = xstrdup(filename);
 	/* try last */
 	if (private == NULL && pass != NULL)
-		private = key_load_private(filename, pass, NULL);
+		private = key_load_private(filename, pass, NULL, 0);
 	if (private == NULL) {
 		/* clear passphrase since it did not work */
 		clear_pass();
@@ -160,7 +160,8 @@
 				xfree(comment);
 				return -1;
 			}
-			private = key_load_private(filename, pass, &comment);
+			private = key_load_private(filename, pass,
+			    &comment, 0);
 			if (private != NULL)
 				break;
 			clear_pass();
--- ssh-keygen.c.orig	Thu Nov 27 18:15:47 2003
+++ ssh-keygen.c	Thu Nov 27 18:16:19 2003
@@ -127,14 +127,14 @@
 	char *pass;
 	Key *prv;
 
-	prv = key_load_private(filename, "", NULL);
+	prv = key_load_private(filename, "", NULL, 0);
 	if (prv == NULL) {
 		if (identity_passphrase)
 			pass = xstrdup(identity_passphrase);
 		else
 			pass = read_passphrase("Enter passphrase: ",
 			    RP_ALLOW_STDIN);
-		prv = key_load_private(filename, pass, NULL);
+		prv = key_load_private(filename, pass, NULL, 0);
 		memset(pass, 0, strlen(pass));
 		xfree(pass);
 	}
@@ -560,7 +560,7 @@
 		exit(1);
 	}
 	/* Try to load the file with empty passphrase. */
-	private = key_load_private(identity_file, "", &comment);
+	private = key_load_private(identity_file, "", &comment, 0);
 	if (private == NULL) {
 		if (identity_passphrase)
 			old_passphrase = xstrdup(identity_passphrase);
@@ -569,7 +569,7 @@
 			    read_passphrase("Enter old passphrase: ",
 			    RP_ALLOW_STDIN);
 		private = key_load_private(identity_file, old_passphrase,
-		    &comment);
+		    &comment, 0);
 		memset(old_passphrase, 0, strlen(old_passphrase));
 		xfree(old_passphrase);
 		if (private == NULL) {
@@ -672,7 +672,7 @@
 		perror(identity_file);
 		exit(1);
 	}
-	private = key_load_private(identity_file, "", &comment);
+	private = key_load_private(identity_file, "", &comment, 0);
 	if (private == NULL) {
 		if (identity_passphrase)
 			passphrase = xstrdup(identity_passphrase);
@@ -682,7 +682,8 @@
 			passphrase = read_passphrase("Enter passphrase: ",
 			    RP_ALLOW_STDIN);
 		/* Try to load using the passphrase. */
-		private = key_load_private(identity_file, passphrase, &comment);
+		private = key_load_private(identity_file, passphrase,
+		    &comment, 0);
 		if (private == NULL) {
 			memset(passphrase, 0, strlen(passphrase));
 			xfree(passphrase);
-- 
Rudolf Cejka <cejkar at fit.vutbr.cz> http://www.fit.vutbr.cz/~cejkar
Brno University of Technology, Faculty of Information Technology
Bozetechova 2, 612 66  Brno, Czech Republic




More information about the openssh-unix-dev mailing list