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

Diff for /src/usr.bin/ssh/servconf.c between version 1.225 and 1.226

version 1.225, 2012/04/12 02:42:32 version 1.226, 2012/05/13 01:42:32
Line 1 
Line 1 
   
 /* $OpenBSD$ */  /* $OpenBSD$ */
 /*  /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland   * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
Line 43 
Line 44 
 #include "match.h"  #include "match.h"
 #include "channels.h"  #include "channels.h"
 #include "groupaccess.h"  #include "groupaccess.h"
   #include "canohost.h"
   #include "packet.h"
   
 static void add_listen_addr(ServerOptions *, char *, int);  static void add_listen_addr(ServerOptions *, char *, int);
 static void add_one_listen_addr(ServerOptions *, char *, int);  static void add_one_listen_addr(ServerOptions *, char *, int);
Line 500 
Line 503 
         options->listen_addrs = aitop;          options->listen_addrs = aitop;
 }  }
   
   struct connection_info *
   get_connection_info(int populate, int use_dns)
   {
           static struct connection_info ci;
   
           if (!populate)
                   return &ci;
           ci.host = get_canonical_hostname(use_dns);
           ci.address = get_remote_ipaddr();
           ci.laddress = get_local_ipaddr(packet_get_connection_in());
           ci.lport = get_local_port();
           return &ci;
   }
   
 /*  /*
  * The strategy for the Match blocks is that the config file is parsed twice.   * The strategy for the Match blocks is that the config file is parsed twice.
  *   *
Line 561 
Line 578 
         return result;          return result;
 }  }
   
   /*
    * All of the attributes on a single Match line are ANDed together, so we need to check every
    * attribute and set the result to zero if any attribute does not match.
    */
 static int  static int
 match_cfg_line(char **condition, int line, const char *user, const char *host,  match_cfg_line(char **condition, int line, struct connection_info *ci)
     const char *address)  
 {  {
         int result = 1;          int result = 1, port;
         char *arg, *attrib, *cp = *condition;          char *arg, *attrib, *cp = *condition;
         size_t len;          size_t len;
   
         if (user == NULL)          if (ci == NULL)
                 debug3("checking syntax for 'Match %s'", cp);                  debug3("checking syntax for 'Match %s'", cp);
         else          else
                 debug3("checking match for '%s' user %s host %s addr %s", cp,                  debug3("checking match for '%s' user %s host %s addr %s "
                     user ? user : "(null)", host ? host : "(null)",                      "laddr %s lport %d", cp, ci->user ? ci->user : "(null)",
                     address ? address : "(null)");                      ci->host ? ci->host : "(null)",
                       ci->address ? ci->address : "(null)",
                       ci->laddress ? ci->laddress : "(null)", ci->lport);
   
         while ((attrib = strdelim(&cp)) && *attrib != '\0') {          while ((attrib = strdelim(&cp)) && *attrib != '\0') {
                 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {                  if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
Line 583 
Line 605 
                 }                  }
                 len = strlen(arg);                  len = strlen(arg);
                 if (strcasecmp(attrib, "user") == 0) {                  if (strcasecmp(attrib, "user") == 0) {
                         if (!user) {                          if (ci == NULL || ci->user == NULL) {
                                 result = 0;                                  result = 0;
                                 continue;                                  continue;
                         }                          }
                         if (match_pattern_list(user, arg, len, 0) != 1)                          if (match_pattern_list(ci->user, arg, len, 0) != 1)
                                 result = 0;                                  result = 0;
                         else                          else
                                 debug("user %.100s matched 'User %.100s' at "                                  debug("user %.100s matched 'User %.100s' at "
                                     "line %d", user, arg, line);                                      "line %d", ci->user, arg, line);
                 } else if (strcasecmp(attrib, "group") == 0) {                  } else if (strcasecmp(attrib, "group") == 0) {
                         switch (match_cfg_line_group(arg, line, user)) {                          if (ci == NULL || ci->user == NULL) {
                                   result = 0;
                                   continue;
                           }
                           switch (match_cfg_line_group(arg, line, ci->user)) {
                         case -1:                          case -1:
                                 return -1;                                  return -1;
                         case 0:                          case 0:
                                 result = 0;                                  result = 0;
                         }                          }
                 } else if (strcasecmp(attrib, "host") == 0) {                  } else if (strcasecmp(attrib, "host") == 0) {
                         if (!host) {                          if (ci == NULL || ci->host == NULL) {
                                 result = 0;                                  result = 0;
                                 continue;                                  continue;
                         }                          }
                         if (match_hostname(host, arg, len) != 1)                          if (match_hostname(ci->host, arg, len) != 1)
                                 result = 0;                                  result = 0;
                         else                          else
                                 debug("connection from %.100s matched 'Host "                                  debug("connection from %.100s matched 'Host "
                                     "%.100s' at line %d", host, arg, line);                                      "%.100s' at line %d", ci->host, arg, line);
                 } else if (strcasecmp(attrib, "address") == 0) {                  } else if (strcasecmp(attrib, "address") == 0) {
                         switch (addr_match_list(address, arg)) {                          if (ci == NULL || ci->address == NULL) {
                                   result = 0;
                                   continue;
                           }
                           switch (addr_match_list(ci->address, arg)) {
                         case 1:                          case 1:
                                 debug("connection from %.100s matched 'Address "                                  debug("connection from %.100s matched 'Address "
                                     "%.100s' at line %d", address, arg, line);                                      "%.100s' at line %d", ci->address, arg, line);
                                 break;                                  break;
                         case 0:                          case 0:
                         case -1:                          case -1:
Line 622 
Line 652 
                         case -2:                          case -2:
                                 return -1;                                  return -1;
                         }                          }
                   } else if (strcasecmp(attrib, "localaddress") == 0){
                           if (ci == NULL || ci->laddress == NULL) {
                                   result = 0;
                                   continue;
                           }
                           switch (addr_match_list(ci->laddress, arg)) {
                           case 1:
                                   debug("connection from %.100s matched "
                                       "'LocalAddress %.100s' at line %d",
                                       ci->laddress, arg, line);
                                   break;
                           case 0:
                           case -1:
                                   result = 0;
                                   break;
                           case -2:
                                   return -1;
                           }
                   } else if (strcasecmp(attrib, "localport") == 0) {
                           if ((port = a2port(arg)) == -1) {
                                   error("Invalid LocalPort '%s' on Match line",
                                       arg);
                                   return -1;
                           }
                           if (ci == NULL || ci->lport == 0) {
                                   result = 0;
                                   continue;
                           }
                           /* TODO support port lists */
                           if (port == ci->lport)
                                   debug("connection from %.100s matched "
                                       "'LocalPort %d' at line %d",
                                       ci->laddress, port, line);
                           else
                                   result = 0;
                 } else {                  } else {
                         error("Unsupported Match attribute %s", attrib);                          error("Unsupported Match attribute %s", attrib);
                         return -1;                          return -1;
                 }                  }
         }          }
         if (user != NULL)          if (ci != NULL)
                 debug3("match %sfound", result ? "" : "not ");                  debug3("match %sfound", result ? "" : "not ");
         *condition = cp;          *condition = cp;
         return result;          return result;
Line 674 
Line 739 
   
 int  int
 process_server_config_line(ServerOptions *options, char *line,  process_server_config_line(ServerOptions *options, char *line,
     const char *filename, int linenum, int *activep, const char *user,      const char *filename, int linenum, int *activep,
     const char *host, const char *address)      struct connection_info *connectinfo)
 {  {
         char *cp, **charptr, *arg, *p;          char *cp, **charptr, *arg, *p;
         int cmdline = 0, *intptr, value, value2, n;          int cmdline = 0, *intptr, value, value2, n;
Line 706 
Line 771 
         if (*activep && opcode != sMatch)          if (*activep && opcode != sMatch)
                 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);                  debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
         if (*activep == 0 && !(flags & SSHCFG_MATCH)) {          if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
                 if (user == NULL) {                  if (connectinfo == NULL) {
                         fatal("%s line %d: Directive '%s' is not allowed "                          fatal("%s line %d: Directive '%s' is not allowed "
                             "within a Match block", filename, linenum, arg);                              "within a Match block", filename, linenum, arg);
                 } else { /* this is a directive we have already processed */                  } else { /* this is a directive we have already processed */
Line 1271 
Line 1336 
                 if (cmdline)                  if (cmdline)
                         fatal("Match directive not supported as a command-line "                          fatal("Match directive not supported as a command-line "
                            "option");                             "option");
                 value = match_cfg_line(&cp, linenum, user, host, address);                  value = match_cfg_line(&cp, linenum, connectinfo);
                 if (value < 0)                  if (value < 0)
                         fatal("%s line %d: Bad Match condition", filename,                          fatal("%s line %d: Bad Match condition", filename,
                             linenum);                              linenum);
Line 1433 
Line 1498 
 }  }
   
 void  void
 parse_server_match_config(ServerOptions *options, const char *user,  parse_server_match_config(ServerOptions *options,
     const char *host, const char *address)     struct connection_info *connectinfo)
 {  {
         ServerOptions mo;          ServerOptions mo;
   
         initialize_server_options(&mo);          initialize_server_options(&mo);
         parse_server_config(&mo, "reprocess config", &cfg, user, host, address);          parse_server_config(&mo, "reprocess config", &cfg, connectinfo);
         copy_set_server_options(options, &mo, 0);          copy_set_server_options(options, &mo, 0);
 }  }
   
   int parse_server_match_testspec(struct connection_info *ci, char *spec)
   {
           char *p;
   
           while ((p = strsep(&spec, ",")) && *p != '\0') {
                   if (strncmp(p, "addr=", 5) == 0) {
                           ci->address = xstrdup(p + 5);
                   } else if (strncmp(p, "host=", 5) == 0) {
                           ci->host = xstrdup(p + 5);
                   } else if (strncmp(p, "user=", 5) == 0) {
                           ci->user = xstrdup(p + 5);
                   } else if (strncmp(p, "laddr=", 6) == 0) {
                           ci->laddress = xstrdup(p + 6);
                   } else if (strncmp(p, "lport=", 6) == 0) {
                           ci->lport = a2port(p + 6);
                           if (ci->lport == -1) {
                                   fprintf(stderr, "Invalid port '%s' in test mode"
                                      " specification %s\n", p+6, p);
                                   return -1;
                           }
                   } else {
                           fprintf(stderr, "Invalid test mode specification %s\n",
                              p);
                           return -1;
                   }
           }
           return 0;
   }
   
   /*
    * returns 1 for a complete spec, 0 for partial spec and -1 for an
    * empty spec.
    */
   int server_match_spec_complete(struct connection_info *ci)
   {
           if (ci->user && ci->host && ci->address)
                   return 1;       /* complete */
           if (!ci->user && !ci->host && !ci->address)
                   return -1;      /* empty */
           return 0;       /* partial */
   }
   
 /* Helper macros */  /* Helper macros */
 #define M_CP_INTOPT(n) do {\  #define M_CP_INTOPT(n) do {\
         if (src->n != -1) \          if (src->n != -1) \
Line 1516 
Line 1623 
   
 void  void
 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,  parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
     const char *user, const char *host, const char *address)      struct connection_info *connectinfo)
 {  {
         int active, linenum, bad_options = 0;          int active, linenum, bad_options = 0;
         char *cp, *obuf, *cbuf;          char *cp, *obuf, *cbuf;
Line 1524 
Line 1631 
         debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));          debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
   
         obuf = cbuf = xstrdup(buffer_ptr(conf));          obuf = cbuf = xstrdup(buffer_ptr(conf));
         active = user ? 0 : 1;          active = connectinfo ? 0 : 1;
         linenum = 1;          linenum = 1;
         while ((cp = strsep(&cbuf, "\n")) != NULL) {          while ((cp = strsep(&cbuf, "\n")) != NULL) {
                 if (process_server_config_line(options, cp, filename,                  if (process_server_config_line(options, cp, filename,
                     linenum++, &active, user, host, address) != 0)                      linenum++, &active, connectinfo) != 0)
                         bad_options++;                          bad_options++;
         }          }
         xfree(obuf);          xfree(obuf);

Legend:
Removed from v.1.225  
changed lines
  Added in v.1.226