ssh keys in ldap (fwd)

Tomasz Kłoczko kloczek w rudy.mif.pg.gda.pl
Nie, 26 Wrz 1999, 16:33:42 CEST


Mały forward. Myślę, że to jest coś wartego uwagi.

---------- Forwarded message ----------
Date: Sat, 25 Sep 1999 16:38:02 -0600 (MDT)
From: Jason Gunthorpe <jgg w ualberta.ca>
To: Debian Admin <debian-admin w lists.debian.org>
Cc: Debian Developers <debian-devel w lists.debian.org>
Subject: ssh keys in ldap
Resent-Date: 25 Sep 1999 22:38:21 -0000
Resent-From: debian-devel w lists.debian.org
Resent-cc: recipient list not shown: ;


Hi all,

I would like a couple people to look over this patch I have made to SSH.
It creates a new option that allows ssh to lookup RSA authentication keys
in a global file modeled after the shadow password file. The intent is to
allow users to place their RSA ssh key into the ldap directory and then
have that key replicated automatically to all machines and used by ssh.

Checking of the global key file is done after looking at the users
.ssh/authorizes_key file and the global file is keyed to each maintainer.
LDAP entries would look like this:

sshrsaauthkey=1024 35
131889136666800864665310056145282172752809896969986210687776638992421269538682667499807562325681722264279958572627924253677904887346542958562754647616248471798299277451202136815142932982865314941795877586991831796183279248323438349823299332680534314763423857547649263063185581654408646481264156574330001283021
jgg w Wakko

And I would probably put a PGP mail gateway to set new keys. [ie gpg
--clearsign < .ssh/identity.pub | mail sshkey w db.debian.org]

The advantage would be that everyone can use their ssh key uniformly on
all the machines. If someone looses their key or needs to revoke it due to
a compromise it can be done quickly and correctly. 

If nobody can see why this would be a bad idea I will deploy this system
on db.debian.org and the debian.org machines in the near future. I hope
that when lsh becomes usable a similar patch to it can be made.

Thanks,
Jason

diff -ur ssh-1.2.27/auth-rsa.c ssh-1.2.27+jgg/auth-rsa.c
--- ssh-1.2.27/auth-rsa.c	Wed May 12 05:19:24 1999
+++ ssh-1.2.27+jgg/auth-rsa.c	Sat Sep 25 14:25:40 1999
@@ -211,7 +211,7 @@
    successful.  This may exit if there is a serious protocol violation. */
 
 int auth_rsa(struct passwd *pw, MP_INT *client_n, RandomState *state,
-             int strict_modes)
+             int strict_modes,int global)
 {
   char line[8192];
   int authenticated;
@@ -220,61 +220,93 @@
   UserFile uf;
   unsigned long linenum = 0;
   struct stat st;
-
-  /* Check permissions & owner of user's .ssh directory */
-  snprintf(line, sizeof(line), "%.500s/%.100s", pw->pw_dir, SSH_USER_DIR);
-
-  /* Check permissions & owner of user's home directory */
-  if (strict_modes && !userfile_check_owner_permissions(pw, pw->pw_dir))
-    {
-      log_msg("Rsa authentication refused for %.100s: bad modes for %.200s",
-          pw->pw_name, pw->pw_dir);
-      packet_send_debug("Bad file modes for %.200s", pw->pw_dir);
-      return 0;
-    }
-
-  /* Check if user have .ssh directory */
-  if (userfile_stat(pw->pw_uid, line, &st) < 0)
-    {
-      log_msg("Rsa authentication refused for %.100s: no %.200s directory",
-              pw->pw_name, line);
-      packet_send_debug("Rsa authentication refused, no %.200s directory",
-                        line);
-      return 0;
-    }
-  
-  if (strict_modes && !userfile_check_owner_permissions(pw, line))
-    {
-      log_msg("Rsa authentication refused for %.100s: bad modes for %.200s",
-          pw->pw_name, line);
-      packet_send_debug("Bad file modes for %.200s", line);
-      return 0;
-    }
+  const char *keyfile = 0;
+   
+  if (global == 0)
+  {
+     /* Check permissions & owner of user's .ssh directory */
+     snprintf(line, sizeof(line), "%.500s/%.100s", pw->pw_dir, SSH_USER_DIR);
+     
+     /* Check permissions & owner of user's home directory */
+     if (strict_modes && !userfile_check_owner_permissions(pw, pw->pw_dir))
+     {
+	log_msg("Rsa authentication refused for %.100s: bad modes for %.200s",
+		pw->pw_name, pw->pw_dir);
+	packet_send_debug("Bad file modes for %.200s", pw->pw_dir);
+	return 0;
+     }
+     
+     /* Check if user have .ssh directory */
+     if (userfile_stat(pw->pw_uid, line, &st) < 0)
+     {
+	log_msg("Rsa authentication refused for %.100s: no %.200s directory",
+		pw->pw_name, line);
+	packet_send_debug("Rsa authentication refused, no %.200s directory",
+			  line);
+	return 0;
+     }
+     
+     if (strict_modes && !userfile_check_owner_permissions(pw, line))
+     {
+	log_msg("Rsa authentication refused for %.100s: bad modes for %.200s",
+		pw->pw_name, line);
+	packet_send_debug("Bad file modes for %.200s", line);
+	return 0;
+     }
+     
+     /* Check permissions & owner of user's authorized keys file */
+     snprintf(line, sizeof(line),
+	      "%.500s/%.100s", pw->pw_dir, SSH_USER_PERMITTED_KEYS);
+     
+     /* Open the file containing the authorized keys. */
+     if (userfile_stat(pw->pw_uid, line, &st) < 0)
+	return 0;
+     
+     if (strict_modes && !userfile_check_owner_permissions(pw, line))
+     {
+	log_msg("Rsa authentication refused for %.100s: bad modes for %.200s",
+		pw->pw_name, line);
+	packet_send_debug("Bad file modes for %.200s", line);
+	return 0;
+     }
+
+     uf = userfile_open(pw->pw_uid, line, O_RDONLY, 0);
+     if (uf == NULL)
+     {
+	packet_send_debug("Could not open %.900s for reading.", line);
+	packet_send_debug("If your home is on an NFS volume, it may need to be world-readable.");
+	return 0;
+     }
+     
+     keyfile = SSH_USER_PERMITTED_KEYS;
+  }
+  else
+  {
+     struct passwd rootpw;
+     rootpw.pw_uid = 0;
+     
+     /* Open the global RSA key file */
+     if (options.global_rsa_file == 0)
+	return 0;
+     
+     if (strict_modes && !userfile_check_owner_permissions(&rootpw, options.global_rsa_file))
+     {
+	log_msg("Bad modes on global RSA key file %.200s",
+		options.global_rsa_file);
+	return 0;
+     }
+     
+     uf = userfile_open(rootpw.pw_uid,options.global_rsa_file , O_RDONLY, 0);
+     if (uf == NULL)
+     {
+	log_msg("Missing global RSA key file %.200s",
+		options.global_rsa_file);
+	return 0;
+     }     
+     
+     keyfile = options.global_rsa_file;
+  }
   
-  /* Check permissions & owner of user's authorized keys file */
-  snprintf(line, sizeof(line),
-           "%.500s/%.100s", pw->pw_dir, SSH_USER_PERMITTED_KEYS);
-
-  /* Open the file containing the authorized keys. */
-  if (userfile_stat(pw->pw_uid, line, &st) < 0)
-    return 0;
-
-  if (strict_modes && !userfile_check_owner_permissions(pw, line))
-    {
-      log_msg("Rsa authentication refused for %.100s: bad modes for %.200s",
-          pw->pw_name, line);
-      packet_send_debug("Bad file modes for %.200s", line);
-      return 0;
-    }
-
-  uf = userfile_open(pw->pw_uid, line, O_RDONLY, 0);
-  if (uf == NULL)
-    {
-      packet_send_debug("Could not open %.900s for reading.", line);
-      packet_send_debug("If your home is on an NFS volume, it may need to be world-readable.");
-      return 0;
-    }
-
   /* Flag indicating whether authentication has succeeded. */
   authenticated = 0;
   
@@ -303,6 +335,26 @@
       if (!*cp || *cp == '\n' || *cp == '#')
         continue;
 
+      /* Verify that this line is for the correct user if we are reading the global
+       	 RSA keyfile */
+      if (global != 0)
+      {
+	 /* Make sure that there is enough text to even be a user name */
+	 if (strlen(cp) <= strlen(pw->pw_name) + 2)
+	    continue;
+	 /* Make sure the user name is terminated with a : */
+	 if (cp[strlen(pw->pw_name)] != ':')
+	    continue;
+	 
+	 /* Make sure that the user name is the one we are looking for */
+	 if (strncmp(cp,pw->pw_name,strlen(pw->pw_name)) != 0)
+	    continue;
+	 
+	 /* Got it, advance cp, the rest of the string + routine are just as if it
+	    came from the users authorizes_keys */
+	 cp += strlen(pw->pw_name) + 1;
+      }
+       
       /* Check if there are options for this key, and if so, save their 
          starting address and skip the option part for now.  If there are no 
          options, set the starting address to NULL. */
@@ -326,9 +378,9 @@
       if (!auth_rsa_read_key(&cp, &bits, &e, &n))
         {
           debug("%.100s, line %lu: bad key syntax", 
-                SSH_USER_PERMITTED_KEYS, linenum);
+                keyfile, linenum);
           packet_send_debug("%.100s, line %lu: bad key syntax", 
-                            SSH_USER_PERMITTED_KEYS, linenum);
+                            keyfile, linenum);
           continue;
         }
       /* cp now points to the comment part. */
@@ -586,9 +638,9 @@
                   if (!*opts)
                     {
                       debug("%.100s, line %lu: missing end quote",
-                            SSH_USER_PERMITTED_KEYS, linenum);
+                            keyfile, linenum);
                       packet_send_debug("%.100s, line %lu: missing end quote",
-                                        SSH_USER_PERMITTED_KEYS, linenum);
+                                        keyfile, linenum);
                       continue;
                     }
                   forced_command[i] = 0;
@@ -620,9 +672,9 @@
                   if (!*opts)
                     {
                       debug("%.100s, line %lu: missing end quote",
-                            SSH_USER_PERMITTED_KEYS, linenum);
+                            keyfile, linenum);
                       packet_send_debug("%.100s, line %lu: missing end quote",
-                                        SSH_USER_PERMITTED_KEYS, linenum);
+                                        keyfile, linenum);
                       continue;
                     }
                   s[i] = 0;
@@ -657,9 +709,9 @@
                   if (!*opts)
                     {
                       debug("%.100s, line %lu: missing end quote",
-                            SSH_USER_PERMITTED_KEYS, linenum);
+                            keyfile, linenum);
                       packet_send_debug("%.100s, line %lu: missing end quote",
-                                        SSH_USER_PERMITTED_KEYS, linenum);
+                                        keyfile, linenum);
                       continue;
                     }
                   patterns[i] = 0;
@@ -684,9 +736,9 @@
             bad_option:
               /* Unknown option. */
               log_msg("Bad options in %.100s file, line %lu: %.50s",
-                  SSH_USER_PERMITTED_KEYS, linenum, opts);
+                  keyfile, linenum, opts);
               packet_send_debug("Bad options in %.100s file, line %lu: %.50s",
-                                SSH_USER_PERMITTED_KEYS, linenum, opts);
+                                keyfile, linenum, opts);
               authenticated = 0;
               break;
 
diff -ur ssh-1.2.27/servconf.c ssh-1.2.27+jgg/servconf.c
--- ssh-1.2.27/servconf.c	Wed May 12 05:19:28 1999
+++ ssh-1.2.27+jgg/servconf.c	Sat Sep 25 14:06:34 1999
@@ -86,6 +86,7 @@
   options->host_key_file = NULL;
   options->random_seed_file = NULL;
   options->pid_file = NULL;
+  options->global_rsa_file = NULL;
   options->server_key_bits = -1;
   options->login_grace_time = -1;
   options->key_regeneration_time = -1;
@@ -252,7 +253,7 @@
   sKerberosTgtPassing, sAllowTcpForwarding, sAllowUsers, sDenyUsers,
   sXauthPath, sCheckMail, sDenyGroups, sAllowGroups, sIgnoreRootRhosts,
   sAllowSHosts, sDenySHosts, sPasswordExpireWarningDays,
-  sAccountExpireWarningDays
+  sAccountExpireWarningDays, sGlobalRSAFile,
 #ifdef F_SECURE_COMMERCIAL
 
 
@@ -307,6 +308,7 @@
   { "randomseed", sRandomSeedFile },
   { "keepalive", sKeepAlives },
   { "pidfile", sPidFile },
+  { "globalrsafile", sGlobalRSAFile },
   { "umask", sUmask },
   { "silentdeny", sSilentDeny },
   { "idletimeout", sIdleTimeout },
@@ -479,6 +481,10 @@
 
 	case sPidFile:
 	  charptr = &options->pid_file;
+	  goto parse_pathname;
+
+	case sGlobalRSAFile:
+	  charptr = &options->global_rsa_file;
 	  goto parse_pathname;
 
 	case sPermitRootLogin:
diff -ur ssh-1.2.27/servconf.h ssh-1.2.27+jgg/servconf.h
--- ssh-1.2.27/servconf.h	Wed May 12 05:19:28 1999
+++ ssh-1.2.27+jgg/servconf.h	Sat Sep 25 14:05:10 1999
@@ -87,6 +87,7 @@
   char *host_key_file;		/* File containing host key. */
   char *random_seed_file;	/* File containing random seed. */
   char *pid_file;		/* File containing process ID number. */
+  char *global_rsa_file;        /* File containing a global set of RSA keys */
   int server_key_bits;		/* Size of the server key. */
   int login_grace_time;		/* Disconnect if no auth in this time (sec). */
   int key_regeneration_time;	/* Server key lifetime (seconds). */
diff -ur ssh-1.2.27/ssh.h ssh-1.2.27+jgg/ssh.h
--- ssh-1.2.27/ssh.h	Wed May 12 05:19:28 1999
+++ ssh-1.2.27+jgg/ssh.h	Sat Sep 25 14:25:48 1999
@@ -490,7 +490,7 @@
    0 if the client could not be authenticated, and 1 if authentication was
    successful.  This may exit if there is a serious protocol violation. */
 int auth_rsa(struct passwd *pw, MP_INT *client_n, RandomState *state,
-             int strict_modes);
+             int strict_modes,int global);
 
 /* Parses an RSA key (number of bits, e, n) from a string.  Moves the pointer
    over the key.  Skips any whitespace at the beginning and at end. */
diff -ur ssh-1.2.27/sshd.c ssh-1.2.27+jgg/sshd.c
--- ssh-1.2.27/sshd.c	Sat Sep 25 14:53:20 1999
+++ ssh-1.2.27+jgg/sshd.c	Sat Sep 25 14:26:51 1999
@@ -2547,7 +2547,9 @@
             mpz_init(&n);
             packet_get_mp_int(&n);
             if (auth_rsa(pw, &n, &sensitive_data.random_state,
-                         options.strict_modes))
+                         options.strict_modes,0) ||
+		auth_rsa(pw, &n, &sensitive_data.random_state,
+			 options.strict_modes,1))
               { 
                 /* Successful authentication. */
                 mpz_clear(&n);


-- 
To UNSUBSCRIBE, email to debian-devel-request w lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster w lists.debian.org



Więcej informacji o liście dyskusyjnej pld-devel-pl