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

Diff for /src/usr.bin/ssh/misc.c between version 1.29.2.2 and 1.30

version 1.29.2.2, 2006/02/03 02:53:44 version 1.30, 2005/04/09 04:32:54
Line 1 
Line 1 
 /*  /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.   * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2005 Damien Miller.  All rights reserved.  
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions   * modification, are permitted provided that the following conditions
Line 26 
Line 25 
 #include "includes.h"  #include "includes.h"
 RCSID("$OpenBSD$");  RCSID("$OpenBSD$");
   
 #include <net/if.h>  
   
 #include "misc.h"  #include "misc.h"
 #include "log.h"  #include "log.h"
 #include "xmalloc.h"  #include "xmalloc.h"
Line 190 
Line 187 
         return port;          return port;
 }  }
   
 int  
 a2tun(const char *s, int *remote)  
 {  
         const char *errstr = NULL;  
         char *sp, *ep;  
         int tun;  
   
         if (remote != NULL) {  
                 *remote = SSH_TUNID_ANY;  
                 sp = xstrdup(s);  
                 if ((ep = strchr(sp, ':')) == NULL) {  
                         xfree(sp);  
                         return (a2tun(s, NULL));  
                 }  
                 ep[0] = '\0'; ep++;  
                 *remote = a2tun(ep, NULL);  
                 tun = a2tun(sp, NULL);  
                 xfree(sp);  
                 return (*remote == SSH_TUNID_ERR ? *remote : tun);  
         }  
   
         if (strcasecmp(s, "any") == 0)  
                 return (SSH_TUNID_ANY);  
   
         tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr);  
         if (errstr != NULL)  
                 return (SSH_TUNID_ERR);  
   
         return (tun);  
 }  
   
 #define SECONDS         1  #define SECONDS         1
 #define MINUTES         (SECONDS * 60)  #define MINUTES         (SECONDS * 60)
 #define HOURS           (MINUTES * 60)  #define HOURS           (MINUTES * 60)
Line 383 
Line 349 
 addargs(arglist *args, char *fmt, ...)  addargs(arglist *args, char *fmt, ...)
 {  {
         va_list ap;          va_list ap;
         char *cp;          char buf[1024];
         u_int nalloc;          u_int nalloc;
         int r;  
   
         va_start(ap, fmt);          va_start(ap, fmt);
         r = vasprintf(&cp, fmt, ap);          vsnprintf(buf, sizeof(buf), fmt, ap);
         va_end(ap);          va_end(ap);
         if (r == -1)  
                 fatal("addargs: argument too long");  
   
         nalloc = args->nalloc;          nalloc = args->nalloc;
         if (args->list == NULL) {          if (args->list == NULL) {
Line 402 
Line 365 
   
         args->list = xrealloc(args->list, nalloc * sizeof(char *));          args->list = xrealloc(args->list, nalloc * sizeof(char *));
         args->nalloc = nalloc;          args->nalloc = nalloc;
         args->list[args->num++] = cp;          args->list[args->num++] = xstrdup(buf);
         args->list[args->num] = NULL;          args->list[args->num] = NULL;
 }  }
   
 void  
 replacearg(arglist *args, u_int which, char *fmt, ...)  
 {  
         va_list ap;  
         char *cp;  
         int r;  
   
         va_start(ap, fmt);  
         r = vasprintf(&cp, fmt, ap);  
         va_end(ap);  
         if (r == -1)  
                 fatal("replacearg: argument too long");  
   
         if (which >= args->num)  
                 fatal("replacearg: tried to replace invalid arg %d >= %d",  
                     which, args->num);  
         xfree(args->list[which]);  
         args->list[which] = cp;  
 }  
   
 void  
 freeargs(arglist *args)  
 {  
         u_int i;  
   
         if (args->list != NULL) {  
                 for (i = 0; i < args->num; i++)  
                         xfree(args->list[i]);  
                 xfree(args->list);  
                 args->nalloc = args->num = 0;  
                 args->list = NULL;  
         }  
 }  
   
 /*  /*
  * Expands tildes in the file name.  Returns data allocated by xmalloc.   * Expands tildes in the file name.  Returns data allocated by xmalloc.
  * Warning: this calls getpw*.   * Warning: this calls getpw*.
Line 450 
Line 379 
         const char *path;          const char *path;
         char user[128], ret[MAXPATHLEN];          char user[128], ret[MAXPATHLEN];
         struct passwd *pw;          struct passwd *pw;
         u_int len, slash;          int len;
   
         if (*filename != '~')          if (*filename != '~')
                 return (xstrdup(filename));                  return (xstrdup(filename));
Line 458 
Line 387 
   
         path = strchr(filename, '/');          path = strchr(filename, '/');
         if (path != NULL && path > filename) {          /* ~user/path */          if (path != NULL && path > filename) {          /* ~user/path */
                 slash = path - filename;                  if (path - filename > sizeof(user) - 1)
                 if (slash > sizeof(user) - 1)  
                         fatal("tilde_expand_filename: ~username too long");                          fatal("tilde_expand_filename: ~username too long");
                 memcpy(user, filename, slash);                  memcpy(user, filename, path - filename);
                 user[slash] = '\0';                  user[path - filename] = '\0';
                 if ((pw = getpwnam(user)) == NULL)                  if ((pw = getpwnam(user)) == NULL)
                         fatal("tilde_expand_filename: No such user %s", user);                          fatal("tilde_expand_filename: No such user %s", user);
         } else if ((pw = getpwuid(uid)) == NULL)        /* ~/path */          } else if ((pw = getpwuid(uid)) == NULL)        /* ~/path */
Line 487 
Line 415 
 }  }
   
 /*  /*
  * Expand a string with a set of %[char] escapes. A number of escapes may be  
  * specified as (char *escape_chars, char *replacement) pairs. The list must  
  * be terminated by a NULL escape_char. Returns replaced string in memory  
  * allocated by xmalloc.  
  */  
 char *  
 percent_expand(const char *string, ...)  
 {  
 #define EXPAND_MAX_KEYS 16  
         struct {  
                 const char *key;  
                 const char *repl;  
         } keys[EXPAND_MAX_KEYS];  
         u_int num_keys, i, j;  
         char buf[4096];  
         va_list ap;  
   
         /* Gather keys */  
         va_start(ap, string);  
         for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) {  
                 keys[num_keys].key = va_arg(ap, char *);  
                 if (keys[num_keys].key == NULL)  
                         break;  
                 keys[num_keys].repl = va_arg(ap, char *);  
                 if (keys[num_keys].repl == NULL)  
                         fatal("percent_expand: NULL replacement");  
         }  
         va_end(ap);  
   
         if (num_keys >= EXPAND_MAX_KEYS)  
                 fatal("percent_expand: too many keys");  
   
         /* Expand string */  
         *buf = '\0';  
         for (i = 0; *string != '\0'; string++) {  
                 if (*string != '%') {  
  append:  
                         buf[i++] = *string;  
                         if (i >= sizeof(buf))  
                                 fatal("percent_expand: string too long");  
                         buf[i] = '\0';  
                         continue;  
                 }  
                 string++;  
                 if (*string == '%')  
                         goto append;  
                 for (j = 0; j < num_keys; j++) {  
                         if (strchr(keys[j].key, *string) != NULL) {  
                                 i = strlcat(buf, keys[j].repl, sizeof(buf));  
                                 if (i >= sizeof(buf))  
                                         fatal("percent_expand: string too long");  
                                 break;  
                         }  
                 }  
                 if (j >= num_keys)  
                         fatal("percent_expand: unknown key %%%c", *string);  
         }  
         return (xstrdup(buf));  
 #undef EXPAND_MAX_KEYS  
 }  
   
 /*  
  * Read an entire line from a public key file into a static buffer, discarding   * Read an entire line from a public key file into a static buffer, discarding
  * lines that exceed the buffer size.  Returns 0 on success, -1 on failure.   * lines that exceed the buffer size.  Returns 0 on success, -1 on failure.
  */   */
Line 570 
Line 436 
         }          }
         return -1;          return -1;
 }  }
   
 int  
 tun_open(int tun, int mode)  
 {  
         struct ifreq ifr;  
         char name[100];  
         int fd = -1, sock;  
   
         /* Open the tunnel device */  
         if (tun <= SSH_TUNID_MAX) {  
                 snprintf(name, sizeof(name), "/dev/tun%d", tun);  
                 fd = open(name, O_RDWR);  
         } else if (tun == SSH_TUNID_ANY) {  
                 for (tun = 100; tun >= 0; tun--) {  
                         snprintf(name, sizeof(name), "/dev/tun%d", tun);  
                         if ((fd = open(name, O_RDWR)) >= 0)  
                                 break;  
                 }  
         } else {  
                 debug("%s: invalid tunnel %u", __func__, tun);  
                 return (-1);  
         }  
   
         if (fd < 0) {  
                 debug("%s: %s open failed: %s", __func__, name, strerror(errno));  
                 return (-1);  
         }  
   
         debug("%s: %s mode %d fd %d", __func__, name, mode, fd);  
   
         /* Set the tunnel device operation mode */  
         snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun);  
         if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)  
                 goto failed;  
   
         if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1)  
                 goto failed;  
   
         /* Set interface mode */  
         ifr.ifr_flags &= ~IFF_UP;  
         if (mode == SSH_TUNMODE_ETHERNET)  
                 ifr.ifr_flags |= IFF_LINK0;  
         else  
                 ifr.ifr_flags &= ~IFF_LINK0;  
         if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)  
                 goto failed;  
   
         /* Bring interface up */  
         ifr.ifr_flags |= IFF_UP;  
         if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1)  
                 goto failed;  
   
         close(sock);  
         return (fd);  
   
  failed:  
         if (fd >= 0)  
                 close(fd);  
         if (sock >= 0)  
                 close(sock);  
         debug("%s: failed to set %s mode %d: %s", __func__, name,  
             mode, strerror(errno));  
         return (-1);  
 }  
   
 void  
 sanitise_stdfd(void)  
 {  
         int nullfd, dupfd;  
   
         if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {  
                 fprintf(stderr, "Couldn't open /dev/null: %s", strerror(errno));  
                 exit(1);  
         }  
         while (++dupfd <= 2) {  
                 /* Only clobber closed fds */  
                 if (fcntl(dupfd, F_GETFL, 0) >= 0)  
                         continue;  
                 if (dup2(nullfd, dupfd) == -1) {  
                         fprintf(stderr, "dup2: %s", strerror(errno));  
                         exit(1);  
                 }  
         }  
         if (nullfd > 2)  
                 close(nullfd);  
 }  
   
 char *  
 tohex(const u_char *d, u_int l)  
 {  
         char b[3], *r;  
         u_int i, hl;  
   
         hl = l * 2 + 1;  
         r = xmalloc(hl);  
         *r = '\0';  
         for (i = 0; i < l; i++) {  
                 snprintf(b, sizeof(b), "%02x", d[i]);  
                 strlcat(r, b, hl);  
         }  
         return (r);  
 }  
   

Legend:
Removed from v.1.29.2.2  
changed lines
  Added in v.1.30