[BACK]Return to auth-rsa.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/Attic/auth-rsa.c between version 1.23 and 1.23.2.4

version 1.23, 2000/04/29 18:11:51 version 1.23.2.4, 2001/03/12 15:44:07
Line 1 
Line 1 
 /*  /*
  *  
  * auth-rsa.c  
  *  
  * Author: Tatu Ylonen <ylo@cs.hut.fi>   * Author: Tatu Ylonen <ylo@cs.hut.fi>
  *  
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland   * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved   *                    All rights reserved
  *  
  * Created: Mon Mar 27 01:46:52 1995 ylo  
  *  
  * RSA-based authentication.  This code determines whether to admit a login   * RSA-based authentication.  This code determines whether to admit a login
  * based on RSA authentication.  This file also contains functions to check   * based on RSA authentication.  This file also contains functions to check
  * validity of the host key.   * validity of the host key.
  *   *
    * As far as I am concerned, the code I have written for this software
    * can be used freely for any purpose.  Any derived versions of this
    * software must be clearly marked as such, and if the derived work is
    * incompatible with the protocol description in the RFC file, it must be
    * called by a name other than "ssh" or "Secure Shell".
  */   */
   
 #include "includes.h"  #include "includes.h"
 RCSID("$Id$");  RCSID("$OpenBSD$");
   
   #include <openssl/rsa.h>
   #include <openssl/md5.h>
   
 #include "rsa.h"  #include "rsa.h"
 #include "packet.h"  #include "packet.h"
 #include "xmalloc.h"  #include "xmalloc.h"
 #include "ssh.h"  #include "ssh1.h"
 #include "mpaux.h"  #include "mpaux.h"
 #include "uidswap.h"  #include "uidswap.h"
 #include "match.h"  #include "match.h"
   #include "auth-options.h"
   #include "pathnames.h"
   #include "log.h"
 #include "servconf.h"  #include "servconf.h"
   #include "auth.h"
   
 #include <openssl/rsa.h>  /* import */
 #include <openssl/md5.h>  extern ServerOptions options;
   
 /* Flags that may be set in authorized_keys options. */  
 extern int no_port_forwarding_flag;  
 extern int no_agent_forwarding_flag;  
 extern int no_x11_forwarding_flag;  
 extern int no_pty_flag;  
 extern char *forced_command;  
 extern struct envstring *custom_environment;  
   
 /*  /*
  * Session identifier that is used to bind key exchange and authentication   * Session identifier that is used to bind key exchange and authentication
  * responses to a particular session.   * responses to a particular session.
  */   */
 extern unsigned char session_id[16];  extern u_char session_id[16];
   
 /*  /*
  * The .ssh/authorized_keys file contains public keys, one per line, in the   * The .ssh/authorized_keys file contains public keys, one per line, in the
Line 65 
Line 62 
 {  {
         BIGNUM *challenge, *encrypted_challenge;          BIGNUM *challenge, *encrypted_challenge;
         BN_CTX *ctx;          BN_CTX *ctx;
         unsigned char buf[32], mdbuf[16], response[16];          u_char buf[32], mdbuf[16], response[16];
         MD5_CTX md;          MD5_CTX md;
         unsigned int i;          u_int i;
         int plen, len;          int plen, len;
   
         encrypted_challenge = BN_new();          encrypted_challenge = BN_new();
Line 125 
Line 122 
 int  int
 auth_rsa(struct passwd *pw, BIGNUM *client_n)  auth_rsa(struct passwd *pw, BIGNUM *client_n)
 {  {
         extern ServerOptions options;          char line[8192], file[MAXPATHLEN];
         char line[8192], file[1024];  
         int authenticated;          int authenticated;
         unsigned int bits;          u_int bits;
         FILE *f;          FILE *f;
         unsigned long linenum = 0;          u_long linenum = 0;
         struct stat st;          struct stat st;
         RSA *pk;          RSA *pk;
   
           /* no user given */
           if (pw == NULL)
                   return 0;
   
         /* Temporarily use the user's uid. */          /* Temporarily use the user's uid. */
         temporarily_use_uid(pw->pw_uid);          temporarily_use_uid(pw->pw_uid);
   
         /* The authorized keys. */          /* The authorized keys. */
         snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir,          snprintf(file, sizeof file, "%.500s/%.100s", pw->pw_dir,
                  SSH_USER_PERMITTED_KEYS);                   _PATH_SSH_USER_PERMITTED_KEYS);
   
         /* Fail quietly if file does not exist */          /* Fail quietly if file does not exist */
         if (stat(file, &st) < 0) {          if (stat(file, &st) < 0) {
Line 167 
Line 167 
                                  "bad ownership or modes for '%s'.", pw->pw_name, file);                                   "bad ownership or modes for '%s'.", pw->pw_name, file);
                         fail = 1;                          fail = 1;
                 } else {                  } else {
                         /* Check path to SSH_USER_PERMITTED_KEYS */                          /* Check path to _PATH_SSH_USER_PERMITTED_KEYS */
                         int i;                          int i;
                         static const char *check[] = {                          static const char *check[] = {
                                 "", SSH_USER_DIR, NULL                                  "", _PATH_SSH_USER_DIR, NULL
                         };                          };
                         for (i = 0; check[i]; i++) {                          for (i = 0; check[i]; i++) {
                                 snprintf(line, sizeof line, "%.500s/%.100s", pw->pw_dir, check[i]);                                  snprintf(line, sizeof line, "%.500s/%.100s", pw->pw_dir, check[i]);
Line 186 
Line 186 
                 }                  }
                 if (fail) {                  if (fail) {
                         fclose(f);                          fclose(f);
                         log(buf);                          log("%s",buf);
                         packet_send_debug(buf);                          packet_send_debug("%s",buf);
                         restore_uid();                          restore_uid();
                         return 0;                          return 0;
                 }                  }
Line 237 
Line 237 
                 /* Parse the key from the line. */                  /* Parse the key from the line. */
                 if (!auth_rsa_read_key(&cp, &bits, pk->e, pk->n)) {                  if (!auth_rsa_read_key(&cp, &bits, pk->e, pk->n)) {
                         debug("%.100s, line %lu: bad key syntax",                          debug("%.100s, line %lu: bad key syntax",
                               SSH_USER_PERMITTED_KEYS, linenum);                              file, linenum);
                         packet_send_debug("%.100s, line %lu: bad key syntax",                          packet_send_debug("%.100s, line %lu: bad key syntax",
                                           SSH_USER_PERMITTED_KEYS, linenum);                              file, linenum);
                         continue;                          continue;
                 }                  }
                 /* cp now points to the comment part. */                  /* cp now points to the comment part. */
Line 255 
Line 255 
                             file, linenum, BN_num_bits(pk->n), bits);                              file, linenum, BN_num_bits(pk->n), bits);
   
                 /* We have found the desired key. */                  /* We have found the desired key. */
                   /*
                    * If our options do not allow this key to be used,
                    * do not send challenge.
                    */
                   if (!auth_parse_options(pw, options, file, linenum))
                           continue;
   
                 /* Perform the challenge-response dialog for this key. */                  /* Perform the challenge-response dialog for this key. */
                 if (!auth_rsa_challenge_dialog(pk)) {                  if (!auth_rsa_challenge_dialog(pk)) {
Line 268 
Line 274 
                  * authenticated. Note that we have not yet processed the                   * authenticated. Note that we have not yet processed the
                  * options; this will be reset if the options cause the                   * options; this will be reset if the options cause the
                  * authentication to be rejected.                   * authentication to be rejected.
                  */  
                 authenticated = 1;  
   
                 /* RSA part of authentication was accepted.  Now process the options. */  
                 if (options) {  
                         while (*options && *options != ' ' && *options != '\t') {  
                                 cp = "no-port-forwarding";  
                                 if (strncmp(options, cp, strlen(cp)) == 0) {  
                                         packet_send_debug("Port forwarding disabled.");  
                                         no_port_forwarding_flag = 1;  
                                         options += strlen(cp);  
                                         goto next_option;  
                                 }  
                                 cp = "no-agent-forwarding";  
                                 if (strncmp(options, cp, strlen(cp)) == 0) {  
                                         packet_send_debug("Agent forwarding disabled.");  
                                         no_agent_forwarding_flag = 1;  
                                         options += strlen(cp);  
                                         goto next_option;  
                                 }  
                                 cp = "no-X11-forwarding";  
                                 if (strncmp(options, cp, strlen(cp)) == 0) {  
                                         packet_send_debug("X11 forwarding disabled.");  
                                         no_x11_forwarding_flag = 1;  
                                         options += strlen(cp);  
                                         goto next_option;  
                                 }  
                                 cp = "no-pty";  
                                 if (strncmp(options, cp, strlen(cp)) == 0) {  
                                         packet_send_debug("Pty allocation disabled.");  
                                         no_pty_flag = 1;  
                                         options += strlen(cp);  
                                         goto next_option;  
                                 }  
                                 cp = "command=\"";  
                                 if (strncmp(options, cp, strlen(cp)) == 0) {  
                                         int i;  
                                         options += strlen(cp);  
                                         forced_command = xmalloc(strlen(options) + 1);  
                                         i = 0;  
                                         while (*options) {  
                                                 if (*options == '"')  
                                                         break;  
                                                 if (*options == '\\' && options[1] == '"') {  
                                                         options += 2;  
                                                         forced_command[i++] = '"';  
                                                         continue;  
                                                 }  
                                                 forced_command[i++] = *options++;  
                                         }  
                                         if (!*options) {  
                                                 debug("%.100s, line %lu: missing end quote",  
                                                       SSH_USER_PERMITTED_KEYS, linenum);  
                                                 packet_send_debug("%.100s, line %lu: missing end quote",  
                                                                   SSH_USER_PERMITTED_KEYS, linenum);  
                                                 continue;  
                                         }  
                                         forced_command[i] = 0;  
                                         packet_send_debug("Forced command: %.900s", forced_command);  
                                         options++;  
                                         goto next_option;  
                                 }  
                                 cp = "environment=\"";  
                                 if (strncmp(options, cp, strlen(cp)) == 0) {  
                                         int i;  
                                         char *s;  
                                         struct envstring *new_envstring;  
                                         options += strlen(cp);  
                                         s = xmalloc(strlen(options) + 1);  
                                         i = 0;  
                                         while (*options) {  
                                                 if (*options == '"')  
                                                         break;  
                                                 if (*options == '\\' && options[1] == '"') {  
                                                         options += 2;  
                                                         s[i++] = '"';  
                                                         continue;  
                                                 }  
                                                 s[i++] = *options++;  
                                         }  
                                         if (!*options) {  
                                                 debug("%.100s, line %lu: missing end quote",  
                                                       SSH_USER_PERMITTED_KEYS, linenum);  
                                                 packet_send_debug("%.100s, line %lu: missing end quote",  
                                                                   SSH_USER_PERMITTED_KEYS, linenum);  
                                                 continue;  
                                         }  
                                         s[i] = 0;  
                                         packet_send_debug("Adding to environment: %.900s", s);  
                                         debug("Adding to environment: %.900s", s);  
                                         options++;  
                                         new_envstring = xmalloc(sizeof(struct envstring));  
                                         new_envstring->s = s;  
                                         new_envstring->next = custom_environment;  
                                         custom_environment = new_envstring;  
                                         goto next_option;  
                                 }  
                                 cp = "from=\"";  
                                 if (strncmp(options, cp, strlen(cp)) == 0) {  
                                         char *patterns = xmalloc(strlen(options) + 1);  
                                         int i;  
                                         options += strlen(cp);  
                                         i = 0;  
                                         while (*options) {  
                                                 if (*options == '"')  
                                                         break;  
                                                 if (*options == '\\' && options[1] == '"') {  
                                                         options += 2;  
                                                         patterns[i++] = '"';  
                                                         continue;  
                                                 }  
                                                 patterns[i++] = *options++;  
                                         }  
                                         if (!*options) {  
                                                 debug("%.100s, line %lu: missing end quote",  
                                                       SSH_USER_PERMITTED_KEYS, linenum);  
                                                 packet_send_debug("%.100s, line %lu: missing end quote",  
                                                                   SSH_USER_PERMITTED_KEYS, linenum);  
                                                 continue;  
                                         }  
                                         patterns[i] = 0;  
                                         options++;  
                                         if (!match_hostname(get_canonical_hostname(), patterns,  
                                                      strlen(patterns)) &&  
                                             !match_hostname(get_remote_ipaddr(), patterns,  
                                                      strlen(patterns))) {  
                                                 log("RSA authentication tried for %.100s with correct key but not from a permitted host (host=%.200s, ip=%.200s).",  
                                                     pw->pw_name, get_canonical_hostname(),  
                                                     get_remote_ipaddr());  
                                                 packet_send_debug("Your host '%.200s' is not permitted to use this key for login.",  
                                                 get_canonical_hostname());  
                                                 xfree(patterns);  
                                                 /* key invalid for this host, reset flags */  
                                                 authenticated = 0;  
                                                 no_agent_forwarding_flag = 0;  
                                                 no_port_forwarding_flag = 0;  
                                                 no_pty_flag = 0;  
                                                 no_x11_forwarding_flag = 0;  
                                                 while (custom_environment) {  
                                                         struct envstring *ce = custom_environment;  
                                                         custom_environment = ce->next;  
                                                         xfree(ce->s);  
                                                         xfree(ce);  
                                                 }  
                                                 if (forced_command) {  
                                                         xfree(forced_command);  
                                                         forced_command = NULL;  
                                                 }  
                                                 break;  
                                         }  
                                         xfree(patterns);  
                                         /* Host name matches. */  
                                         goto next_option;  
                                 }  
                 bad_option:  
                                 log("Bad options in %.100s file, line %lu: %.50s",  
                                     SSH_USER_PERMITTED_KEYS, linenum, options);  
                                 packet_send_debug("Bad options in %.100s file, line %lu: %.50s",  
                                                   SSH_USER_PERMITTED_KEYS, linenum, options);  
                                 authenticated = 0;  
                                 break;  
   
                 next_option:  
                                 /*  
                                  * Skip the comma, and move to the next option  
                                  * (or break out if there are no more).  
                                  */  
                                 if (!*options)  
                                         fatal("Bugs in auth-rsa.c option processing.");  
                                 if (*options == ' ' || *options == '\t')  
                                         break;          /* End of options. */  
                                 if (*options != ',')  
                                         goto bad_option;  
                                 options++;  
                                 /* Process the next option. */  
                                 continue;  
                         }  
                 }  
                 /*  
                  * Break out of the loop if authentication was successful;                   * Break out of the loop if authentication was successful;
                  * otherwise continue searching.                   * otherwise continue searching.
                  */                   */
                 if (authenticated)                  authenticated = 1;
                         break;                  break;
         }          }
   
         /* Restore the privileged uid. */          /* Restore the privileged uid. */
Line 464 
Line 291 
   
         if (authenticated)          if (authenticated)
                 packet_send_debug("RSA authentication accepted.");                  packet_send_debug("RSA authentication accepted.");
           else
                   auth_clear_options();
   
         /* Return authentication result. */          /* Return authentication result. */
         return authenticated;          return authenticated;

Legend:
Removed from v.1.23  
changed lines
  Added in v.1.23.2.4