Example #1
0
static int filestore_verify_host_key(sftp_keystore_t *store, pool *p,
    const char *user, const char *host_fqdn, const char *host_user,
    unsigned char *key_data, uint32_t key_len) {
  struct filestore_key *key = NULL;
  struct filestore_data *store_data = store->keystore_data;

  int res = -1;

  if (!store_data->path) {
    errno = EPERM;
    return -1;
  }

  /* XXX Note that this will scan the file from the beginning, each time.
   * There's room for improvement; perhaps mmap() the file into memory?
   */

  key = filestore_get_key(store, p);
  while (key) {
    int ok;

    pr_signals_handle();

    ok = sftp_keys_compare_keys(p, key_data, key_len, key->key_data,
      key->key_datalen);
    if (ok != TRUE) {
      if (ok == -1) {
        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
          "error comparing keys from '%s': %s", store_data->path,
          strerror(errno));
      }

    } else {

      /* XXX Verify that the user and the host_user match?? */

      res = 0;
      break;
    }

    key = filestore_get_key(store, p);
  }

  if (res == 0) {
    pr_trace_msg(trace_channel, 10, "found matching public key for host '%s' "
      "in '%s'", host_fqdn, store_data->path);
  }

  if (pr_fsio_lseek(store_data->fh, 0, SEEK_SET) < 0) {
    (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
      "error seeking to start of '%s': %s", store_data->path, strerror(errno));
    return -1;
  }

  store_data->lineno = 0;
  return res;
}
static array_header *counter_file_read(pr_fh_t *fh) {
  char buf[PR_TUNABLE_BUFFER_SIZE];
  array_header *ids = make_array(counter_pool, 0, sizeof(int));

  /* Read the list of IDs in the CounterFile into an array. */

  if (counter_file_lock(fh, LOCK_SH) < 0) {
    (void) pr_log_writefile(counter_logfd, MOD_COUNTER_VERSION,
      "error read-locking CounterFile '%s': %s", fh->fh_path, strerror(errno));
  }

  if (pr_fsio_lseek(fh, 0, SEEK_SET) < 0) {
    int xerrno = errno;

    counter_file_lock(fh, LOCK_UN);
    errno = xerrno;

    return NULL;
  }

  memset(buf, '\0', sizeof(buf));
  while (pr_fsio_gets(buf, sizeof(buf), fh) != NULL) {
    int id;

    pr_signals_handle();

    id = atoi(buf);
    if (id < 0) {
      continue;
    }

    *((int *) push_array(ids)) = id;
  }

  if (counter_file_lock(fh, LOCK_UN) < 0) {
    (void) pr_log_writefile(counter_logfd, MOD_COUNTER_VERSION,
      "error unlocking CounterFile '%s': %s", fh->fh_path, strerror(errno));
  }

  return ids;
}
Example #3
0
static int filestore_verify_user_key(sftp_keystore_t *store, pool *p,
    const char *user, unsigned char *key_data, uint32_t key_len) {
  struct filestore_key *key = NULL;
  struct filestore_data *store_data = store->keystore_data;
  unsigned int count = 0;

  int res = -1;

  if (!store_data->path) {
    errno = EPERM;
    return -1;
  }

  /* XXX Note that this will scan the file from the beginning, each time.
   * There's room for improvement; perhaps mmap() the file into memory?
   */

  key = filestore_get_key(store, p);
  while (key) {
    int ok;

    pr_signals_handle();
    count++;

    ok = sftp_keys_compare_keys(p, key_data, key_len, key->key_data,
      key->key_datalen);
    if (ok != TRUE) {
      if (ok == -1) {
        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
          "error comparing keys from '%s': %s", store_data->path,
          strerror(errno));

      } else {
        pr_trace_msg(trace_channel, 10,
          "failed to match key #%u from file '%s'", count, store_data->path);
      }

    } else {
      /* If we are configured to check for Subject headers, and if the file key
       * has a Subject header, and that header value does not match the
       * logging in user, then continue looking.
       */
      if ((sftp_opts & SFTP_OPT_MATCH_KEY_SUBJECT) &&
          key->subject != NULL) {
        if (strcmp(key->subject, user) != 0) {
          (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
            "found matching key for user '%s' in '%s', but Subject "
            "header ('%s') does not match, skipping key", user,
            store_data->path, key->subject);

        } else {
          res = 0;
          break;
        }

      } else {
        res = 0;
        break;
      }
    }

    key = filestore_get_key(store, p);
  }

  if (res == 0) {
    pr_trace_msg(trace_channel, 10, "found matching public key for user '%s' "
      "in '%s'", user, store_data->path);
  }

  if (pr_fsio_lseek(store_data->fh, 0, SEEK_SET) < 0) {
    (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
      "error seeking to start of '%s': %s", store_data->path, strerror(errno));
    return -1;
  }

  store_data->lineno = 0;
  return res;
}
static int counter_file_write(pr_fh_t *fh, array_header *ids) {
  register unsigned int i;
  int *elts;

  /* Write the list of IDs in the given array to the CounterFile,
   * overwriting any previous values.
   */

  if (counter_file_lock(fh, LOCK_EX) < 0) {
    (void) pr_log_writefile(counter_logfd, MOD_COUNTER_VERSION,
      "error write-locking CounterFile '%s': %s", fh->fh_path, strerror(errno));
  }

  if (pr_fsio_lseek(fh, 0, SEEK_SET) < 0) {
    int xerrno = errno;

    counter_file_lock(fh, LOCK_UN);
    errno = xerrno;

    return -1;
  }

  elts = (int *) ids->elts;
  for (i = 0; i < ids->nelts; i++) {
    char buf[32];

    pr_signals_handle();

    /* Skip any negative IDs.  This small hack allows for IDs to be
     * effectively removed from the list.
     */
    if (elts[i] < 0) {
      continue;
    }

    memset(buf, '\0', sizeof(buf));
    snprintf(buf, sizeof(buf), "%d\n", elts[i]); 
    buf[sizeof(buf)-1] = '\0';
    buf[strlen(buf)-1] = '\0';

    if (pr_fsio_puts(buf, fh) < 0) {
      int xerrno = errno;

      counter_file_lock(fh, LOCK_UN);
      errno = xerrno;

      return -1;
    }
  }

  if (pr_fsio_ftruncate(fh, 0) < 0) {
    int xerrno = errno;

    counter_file_lock(fh, LOCK_UN);
    errno = xerrno;

    return -1;
  }

  if (counter_file_lock(fh, LOCK_SH) < 0) {
    (void) pr_log_writefile(counter_logfd, MOD_COUNTER_VERSION,
      "error unlocking CounterFile '%s': %s", fh->fh_path, strerror(errno));
  }

  return 0;
}