Beispiel #1
0
/* load the history
 * ----------------------------------------------------------------------- */
void history_load(void) {
  unsigned int i;
  unsigned int hlen;
  char fname[PATH_MAX + 1];

  hlen = str_copyn(fname, sh_home, PATH_MAX);
  if(hlen >= PATH_MAX - 3)
    return;
  
  /* append a trailing slash if not already there */
  if(hlen && fname[hlen - 1] != '/')
    fname[hlen++] = '/';
  
  fname[hlen++] = '.';
  
  /* mapped history entries */
  history_mapped = 0;
  
  for(i = 0; history_files[i]; i++) {
    /* append history file name */
    str_copyn(&fname[hlen], history_files[i], PATH_MAX - hlen);

    /* then try to open the history file */
    if(buffer_mmapread(&history_buffer, fname) == 0)
      break;
  }
  
  /* we tried all files: nothing to load */
  if(history_files[i] == NULL)
    return;

  /* loop through the mapped history file and separate
   * history entries using nul-string-termination 
   *
   * note that quote-balancing is applied because there 
   * may be quoted multiline words in the history 
   */
  while(history_buffer.p < history_buffer.n) {
    unsigned long len;
    
    /* next entry will begin after the termination */
    if(!(len = history_cmdlen(&history_buffer.x[history_buffer.p])))
      break;
    
    while(parse_isspace(history_buffer.x[history_buffer.p]))
      history_buffer.p++;
    
    history_set(&history_buffer.x[history_buffer.p]);
    history_advance();
    history_mapped++;
    
    history_buffer.p += len;
  }
  
  /* unmap the file if it didn't contain any entries */
  if(history_buffer.n && history_mapped == 0)
    buffer_close(&history_buffer);
}
Beispiel #2
0
static void print_escape(char *x, int wall) {
  char ch, *y, *start, *from = "abefnrtv\\c", *to= "\a\b\033\f\n\r\t\v\\";
  unsigned long len;
  start = alloca(str_len(x) + 3);
  for (y=start; (ch=*x); x++) {
    if (ch == '\\') {
      unsigned long u;
      len = scan_8ulong(x+1, &u);
      if (len) { /* 012...9 */
	ch = u;
	x += len;
      } else {
	len = str_chr(from, x[1]);
	switch (from[len]) {
	  case 0: break;
	  case 'c': goto do_it;
	  default: /* \a\b... */ ++x; ch = to[len];
	}
      }
    }
    *y++ = ch;
  }
  *y++ = '\n';

 do_it:
  len = y-start;

  if (wall==0) write(1, start, len);
  else {
    struct utmp u;
    int fd, r;
    char line[8 + sizeof(u.ut_line)];

    fd = open(_PATH_UTMP, O_RDONLY | O_NOCTTY);
    if (fd < 0) return;

    while (utmp_io(fd, &u, F_RDLCK)) {
      if (u.ut_type != USER_PROCESS) continue;
      if (u.ut_user[0] == 0 || u.ut_pid < 2 ||
	  u.ut_line[0] == 0 || u.ut_line[0] == '/') continue; 

      y = line;
      y += str_copyn(y, "/dev/", 8);
      y += str_copyn(y, u.ut_line, sizeof(u.ut_line));
      y[0] = 0;
      if (line[str_chr(line, '.')]) continue;

      if (kill(u.ut_pid, 0) && errno == ESRCH) continue;
      r = open(line, O_WRONLY | O_NOCTTY | O_NDELAY);
      if (r < 0) continue;

      write(r, start, len);
      close(r);
    }
    close(fd);
  }
}
Beispiel #3
0
/*
The 'channel_exec' function executes new process.
If terminal is requsted, than users shell is executed,
if exec is requested, than command 'cmd' is executed.
Process is executed under appropriate users UID.
*/
int channel_exec(const char *cmd) {

    char *run[4];
    char *shell;
    char *name;
    int fd[3];
    char ln[32];

    if (channel.maxpacket == 0) bug_proto();
    if (channel.pid != 0 ) bug_proto();

    if (channel.flagterminal) {
        channel.pid = channel_forkpty(fd, channel.master, channel.slave);
        if (channel.pid > 0) {
            name = ptsname(fd[0]);
            if (!name) bug();
            if (!str_copyn(channel.termname, sizeof channel.termname, name)) bug_nomem();
        }
    }
    else {
        channel.pid = channel_fork(fd);
    }
    if (channel.pid == -1) return 0;
    if (channel.pid == 0) {
        logsys_login(channel.user, channel.remoteip, 0, 0);
        if (!channel_droppriv(channel.user, &shell)) _exit(111);
        if (cmd) {
            run[0] = shell;
            run[1] = (char *)"-c";
            run[2] = (char *)cmd;
            run[3] = 0;
        }
        else {
            if (!loginshell(ln, sizeof ln, shell)) bug();
            run[0] = ln;
            run[1] = 0;
        }
        signal(SIGPIPE, SIG_DFL);
        newenv_exec(shell, run);
        _exit(111);
    }
    channel.fd0 = fd[0];
    channel.fd1 = fd[1];
    channel.fd2 = fd[2];
    channel.len0 = 0;
    newenv_purge();
    if (channel.flagterminal && channel.pid > 0) channel_ptyresize(channel.a, channel.b, channel.x, channel.y);
    return 1;
}
Beispiel #4
0
/*
The 'channel_open' function opens the channel.
It sets 'localwindow' and maxpacket, values obtained from 
from SSH_MSG_CHANNEL_OPEN message.
Function also obtaines connection information and sets
environment variables PATH, SSH_CONNECTION and MAIL.
*/
int channel_open(const char *user, crypto_uint32 id, crypto_uint32 remotewindow, crypto_uint32 maxpacket, crypto_uint32 *localwindow) {

    struct buf b = { channel.buf0, 0, CHANNEL_BUFSIZE };

    if (!localwindow) bug_inval();
    if (!maxpacket) bug_inval();
    if (!remotewindow) bug_inval();
    if (channel.maxpacket != 0) bug_proto();
    if (channel.pid != 0) bug_proto();

    /* copy user-name */
    if (!str_copyn(channel.user, sizeof channel.user, user)) bug_nomem();

    /* set id, maxpacket, remotewindow, localwindow */
    channel.id = id;
    channel.maxpacket    = maxpacket;
    channel.remotewindow = remotewindow;
    channel.localwindow  = *localwindow = CHANNEL_BUFSIZE;

    /* copy PATH */
    if (!newenv_copyenv("PATH")) if (!newenv_env("PATH", "/bin:/usr/bin")) return 0;

    /* create env. SSH_CONNECTION */
    connectioninfo(channel.localip, channel.localport, channel.remoteip, channel.remoteport);
    buf_purge(&b);
    buf_puts(&b, channel.remoteip);
    buf_puts(&b, " ");
    buf_puts(&b, channel.remoteport);
    buf_puts(&b, " ");
    buf_puts(&b, channel.localip);
    buf_puts(&b, " ");
    buf_puts(&b, channel.localport);
    buf_putnum8(&b, 0);
    if (!newenv_env("SSH_CONNECTION", (char *)b.buf)) return 0;

    /* create env. MAIL */
#ifdef _PATH_MAILDIR
    buf_purge(&b);
    buf_puts(&b, _PATH_MAILDIR);
    buf_puts(&b, "/");
    buf_puts(&b, user);
    buf_putnum8(&b, 0);
    if (!newenv_env("MAIL", (char *)b.buf)) return 0;
#endif

    purge(channel.buf0, sizeof channel.buf0);
    return 1;
}
Beispiel #5
0
union node*
expand_param(struct nargparam* param, union node** nptr, struct vartab* varstack, char* argv[], int exitcode, int flags) {
  union node* n = *nptr;
  stralloc value;
  char* str = NULL;
  const char *v = NULL;
  unsigned long argc, vlen = 0;

        for(argc = 0; argv[argc]; ++argc)
          ;
  stralloc_init(&value);

  /* treat special arguments */
  if(param->flag & S_SPECIAL) {
    switch(param->flag & S_SPECIAL) {
      /* $# substitution */
      case S_ARGC: {
        stralloc_catulong0(&value, argc, 0);
        break;
      }

      /* $* substitution */
      case S_ARGV: {
        char** s;

        for(s = argv; *s;) {
          stralloc_cats(&n->narg.stra, *s);
          if(*++s) stralloc_catc(&n->narg.stra, ' ');
        }
        break;
      }

      /* $@ substitution */
      case S_ARGVS: {
        unsigned int i = 0;

        while(i < argc) {
          param->flag &= ~S_SPECIAL;
          param->flag |= S_ARG;
          param->numb = 1 + i;

          n = expand_param(param, nptr, varstack, argv, exitcode,flags);

          if(++i < argc) nptr = &n->list.next;
        }

        return n;
      }

        /* $? substitution */
      case S_EXITCODE: {
        stralloc_catulong0(&value, exitcode, 0);
        break;
      }

      /* $- substitution */
      case S_FLAGS: break;

      /* $! substitution */
      case S_BGEXCODE:
        break;

        /* $[0-9] arg subst */
      case S_ARG: {
        if(param->numb == 0) {
        /*  stralloc_cats(&value, sh_argv0); */
        } else if(param->numb - 1 < argc) {
          stralloc_cats(&value, argv[param->numb - 1]);
        }
        break;
      }

        /* $$ arg subst */
      case S_PID: {
        stralloc_catulong0(&value, getpid(), 0);
        break;
      }
    }

    /* special parameters are always set */
    if(value.len) {
      stralloc_nul(&value);
      v = value.s;
    }

    vlen = value.len;
  }
  /* ..and variable substitutions */
  else {
    size_t offset;

    /* look for the variable.
       if the S_NULL flag is set and we have a var which is null
       set v to NULL */
    if((v = var_get(varstack, param->name, &offset))) {
      if(v[offset] == '\0' && (param->flag & S_NULL)) {
        v = NULL;
        vlen = 0;
      } else {
        v = &v[offset];
        vlen = str_len(v);
      }
    }
  }

  /* check for S_STRLEN substitution */
  if(param->flag & S_STRLEN) {
    char lstr[FMT_ULONG];

    n = expand_cat(lstr, fmt_ulong(lstr, vlen), nptr, varstack, flags);

    stralloc_free(&value);

    return n;
  }

  str = str_ndup(v, vlen);

  /* otherwise expand the apropriate variable/word subst */
  switch(param->flag & S_VAR) {
    /* return word if parameter unset (or null) */
    case S_DEFAULT: {
      if(v) n = expand_cat(v, vlen, nptr, varstack, flags);
      /* unset, substitute */
      else
        n = expand_arg(&param->word->narg, nptr, varstack, argv, exitcode, flags);
      break;
    }
    /* if parameter unset (or null) then expand word to it
       and substitute paramter */
    case S_ASGNDEF: {
      if(v)
        n = expand_cat(v, vlen, nptr, varstack, flags);
      else {
        n = expand_arg(&param->word->narg, nptr, varstack, argv, exitcode, flags | X_NOSPLIT);
        var_setvsa(param->name, /* BUG */ &n->narg.stra, V_DEFAULT);
      }
      break;
    }

    /* indicate error if null or unset */
    case S_ERRNULL: {
      if(v)
        n = expand_cat(v, vlen, nptr, varstack, flags);
      else {
        union node* tmpnode = NULL;

        n = expand_arg(&param->word->narg, &tmpnode, varstack, argv, exitcode, flags);
       errmsg_warn((n && n->narg.stra.s) ? n->narg.stra.s : "parameter null or not set", 0);
        if(tmpnode) tree_free(tmpnode);
      }
      break;
    }

      /* if parameter unset (or null) then substitute null,
         otherwise substitute word */
    case S_ALTERNAT: {
      if(v) n = expand_arg(&param->word->narg, nptr, varstack, argv, exitcode, flags);
      break;

        /* remove smallest matching suffix */
      case S_RSSFX: {
        int i;
        stralloc sa;

        if(v && vlen) {
          expand_copysa(param->word, &sa, varstack, argv, exitcode, 0);
          stralloc_nul(&sa);

          for(i = vlen - 1; i >= 0; i--)
            if(fnmatch(sa.s, str + i, FNM_PERIOD) == 0) break;

          n = expand_cat(v, (i < 0 ? vlen : i), nptr, varstack, flags);
        }
        break;
      }
    }

      /* remove largest matching suffix */
    case S_RLSFX: {
      unsigned int i;
      stralloc sa;

      if(v && vlen) {
        expand_copysa(param->word, &sa, varstack, argv, exitcode, 0);
        stralloc_nul(&sa);

        for(i = 0; i <= vlen; i++)
          if(fnmatch(sa.s,  str + i,  FNM_PERIOD) == 0) break;

        n = expand_cat(v, (i > vlen ? vlen : i), nptr, varstack, flags);
      }

      break;
    }

      /* remove smallest matching prefix */
    case S_RSPFX: {
      unsigned int i;
      stralloc sa;

      if(v && vlen) {
        expand_copysa(param->word, &sa, varstack, argv, exitcode, 0);
        stralloc_nul(&sa);

        for(i = 1; i <= vlen; i++) {
          str_copyn(str, v, i);
          if(fnmatch(sa.s, (char*)v, FNM_PERIOD) == 0) break;
        }

        if(i > vlen) i = 0;

        n = expand_cat(v + i, vlen - i, nptr, varstack, flags);
        str_copy(str, v);
      }
      break;
    }

      /* remove largest matching prefix */
    case S_RLPFX: {
      unsigned int i;
      stralloc sa;

      if(v && vlen) {
        expand_copysa(param->word, &sa, varstack, argv, exitcode, 0);
        stralloc_nul(&sa);

        for(i = vlen; i > 0; i--) {
          str_copyn(str, v, i);
          if(fnmatch(sa.s, (char*)v, FNM_PERIOD) == 0) break;
        }

        if(i == 0) i = vlen;

        n = expand_cat(v + i, vlen - i, nptr, varstack, flags);
        str_copy(str, v);
      }
      break;
    }
  }

  free(str);

  stralloc_free(&value);
  return n;
}