示例#1
0
static size_t atomicio(ssh_socket s, void *buf, size_t n, int do_read) {
  char *b = buf;
  size_t pos = 0;
  ssize_t res;
  ssh_pollfd_t pfd;
  socket_t fd = ssh_socket_get_fd_in(s);

  pfd.fd = fd;
  pfd.events = do_read ? POLLIN : POLLOUT;

  while (n > pos) {
    if (do_read) {
      res = read(fd, b + pos, n - pos);
    } else {
      res = write(fd, b + pos, n - pos);
    }
    switch (res) {
      case -1:
        if (errno == EINTR) {
          continue;
        }
#ifdef EWOULDBLOCK
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
#else
        if (errno == EAGAIN) {
#endif
          (void) ssh_poll(&pfd, 1, -1);
          continue;
        }
        return 0;
    case 0:
      errno = EPIPE;
      return pos;
    default:
      pos += (size_t) res;
    }
  }

  return pos;
}

ssh_agent agent_new(struct ssh_session_struct *session) {
  ssh_agent agent = NULL;

  agent = malloc(sizeof(struct ssh_agent_struct));
  if (agent == NULL) {
    return NULL;
  }
  ZERO_STRUCTP(agent);

  agent->count = 0;
  agent->sock = ssh_socket_new(session);
  if (agent->sock == NULL) {
    SAFE_FREE(agent);
    return NULL;
  }

  return agent;
}
示例#2
0
int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
    int i;

    if (session == NULL){
        ssh_set_error(sshbind, SSH_FATAL,"session is null");
        return SSH_ERROR;
    }

    session->server = 1;
    session->version = 2;

    /* copy options */
    for (i = 0; i < 10; ++i) {
      if (sshbind->wanted_methods[i]) {
        session->wanted_methods[i] = strdup(sshbind->wanted_methods[i]);
        if (session->wanted_methods[i] == NULL) {
          return SSH_ERROR;
        }
      }
    }

    if (sshbind->bindaddr == NULL)
      session->bindaddr = NULL;
    else {
      SAFE_FREE(session->bindaddr);
      session->bindaddr = strdup(sshbind->bindaddr);
      if (session->bindaddr == NULL) {
        return SSH_ERROR;
      }
    }

    session->common.log_verbosity = sshbind->common.log_verbosity;

    ssh_socket_free(session->socket);
    session->socket = ssh_socket_new(session);
    if (session->socket == NULL) {
      /* perhaps it may be better to copy the error from session to sshbind */
      ssh_set_error_oom(sshbind);
      return SSH_ERROR;
    }
    ssh_socket_set_fd(session->socket, fd);
    ssh_socket_get_poll_handle_out(session->socket);

    if (sshbind->dsa) {
        session->srv.dsa_key = ssh_key_dup(sshbind->dsa);
        if (session->srv.dsa_key == NULL) {
          ssh_set_error_oom(sshbind);
          return SSH_ERROR;
        }
    }
    if (sshbind->rsa) {
        session->srv.rsa_key = ssh_key_dup(sshbind->rsa);
        if (session->srv.rsa_key == NULL) {
          ssh_set_error_oom(sshbind);
          return SSH_ERROR;
        }
    }
    return SSH_OK;
}
示例#3
0
/**
 * @brief Create a new ssh session.
 *
 * @returns             A new ssh_session pointer, NULL on error.
 */
ssh_session ssh_new(void) {
  ssh_session session;
  char *id = NULL;
  int rc;

  session = malloc(sizeof (struct ssh_session_struct));
  if (session == NULL) {
    return NULL;
  }
  ZERO_STRUCTP(session);

  session->next_crypto = crypto_new();
  if (session->next_crypto == NULL) {
    goto err;
  }

  session->socket = ssh_socket_new(session);
  if (session->socket == NULL) {
    goto err;
  }

  session->out_buffer = ssh_buffer_new();
  if (session->out_buffer == NULL) {
    goto err;
  }

  session->in_buffer=ssh_buffer_new();
  if (session->in_buffer == NULL) {
    goto err;
  }

  session->alive = 0;
  session->auth_methods = 0;
  ssh_set_blocking(session, 1);
  session->common.log_indent = 0;
  session->maxchannel = FIRST_CHANNEL;

#ifndef _WIN32
    session->agent = agent_new(session);
    if (session->agent == NULL) {
      goto err;
    }
#endif /* _WIN32 */

    /* OPTIONS */
    session->opts.StrictHostKeyChecking = 1;
    session->opts.port = 22;
    session->opts.fd = -1;
    session->opts.ssh2 = 1;
    session->opts.compressionlevel=7;
#ifdef WITH_SSH1
    session->opts.ssh1 = 1;
#else
    session->opts.ssh1 = 0;
#endif

    session->opts.identity = ssh_list_new();
    if (session->opts.identity == NULL) {
      goto err;
    }

    id = strdup("%d/id_rsa");
    if (id == NULL) {
      goto err;
    }
    rc = ssh_list_append(session->opts.identity, id);
    if (rc == SSH_ERROR) {
      goto err;
    }

    id = strdup("%d/id_dsa");
    if (id == NULL) {
      goto err;
    }
    rc = ssh_list_append(session->opts.identity, id);
    if (rc == SSH_ERROR) {
      goto err;
    }

    id = strdup("%d/identity");
    if (id == NULL) {
      goto err;
    }
    rc = ssh_list_append(session->opts.identity, id);
    if (rc == SSH_ERROR) {
      goto err;
    }

    return session;

err:
    free(id);
    ssh_free(session);
    return NULL;
}
示例#4
0
文件: bind.c 项目: Alexey-T/SynFTP
int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
    int i, rc;

    if (session == NULL){
        ssh_set_error(sshbind, SSH_FATAL,"session is null");
        return SSH_ERROR;
    }

    session->server = 1;
    session->version = 2;

    /* copy options */
    for (i = 0; i < 10; i++) {
      if (sshbind->wanted_methods[i]) {
        session->opts.wanted_methods[i] = strdup(sshbind->wanted_methods[i]);
        if (session->opts.wanted_methods[i] == NULL) {
          return SSH_ERROR;
        }
      }
    }

    if (sshbind->bindaddr == NULL)
      session->opts.bindaddr = NULL;
    else {
      SAFE_FREE(session->opts.bindaddr);
      session->opts.bindaddr = strdup(sshbind->bindaddr);
      if (session->opts.bindaddr == NULL) {
        return SSH_ERROR;
      }
    }

    session->common.log_verbosity = sshbind->common.log_verbosity;
    if(sshbind->banner != NULL)
    	session->opts.custombanner = strdup(sshbind->banner);
    ssh_socket_free(session->socket);
    session->socket = ssh_socket_new(session);
    if (session->socket == NULL) {
      /* perhaps it may be better to copy the error from session to sshbind */
      ssh_set_error_oom(sshbind);
      return SSH_ERROR;
    }
    ssh_socket_set_fd(session->socket, fd);
    ssh_socket_get_poll_handle_out(session->socket);

    /* We must try to import any keys that could be imported in case
     * we are not using ssh_bind_listen (which is the other place
     * where keys can be imported) on this ssh_bind and are instead
     * only using ssh_bind_accept_fd to manage sockets ourselves.
     */
    rc = ssh_bind_import_keys(sshbind);
    if (rc != SSH_OK) {
      return SSH_ERROR;
    }

#ifdef HAVE_ECC
    if (sshbind->ecdsa) {
        session->srv.ecdsa_key = ssh_key_dup(sshbind->ecdsa);
        if (session->srv.ecdsa_key == NULL) {
          ssh_set_error_oom(sshbind);
          return SSH_ERROR;
        }
    }
#endif
    if (sshbind->dsa) {
        session->srv.dsa_key = ssh_key_dup(sshbind->dsa);
        if (session->srv.dsa_key == NULL) {
          ssh_set_error_oom(sshbind);
          return SSH_ERROR;
        }
    }
    if (sshbind->rsa) {
        session->srv.rsa_key = ssh_key_dup(sshbind->rsa);
        if (session->srv.rsa_key == NULL) {
          ssh_set_error_oom(sshbind);
          return SSH_ERROR;
        }
    }
    if (sshbind->ed25519 != NULL) {
        session->srv.ed25519_key = ssh_key_dup(sshbind->ed25519);
        if (session->srv.ed25519_key == NULL){
            ssh_set_error_oom(sshbind);
            return SSH_ERROR;
        }
    }

    /* force PRNG to change state in case we fork after ssh_bind_accept */
    ssh_reseed();
    return SSH_OK;
}
示例#5
0
文件: session.c 项目: Paxxi/libssh
/**
 * @brief Create a new ssh session.
 *
 * @returns             A new ssh_session pointer, NULL on error.
 */
ssh_session ssh_new(void) {
  ssh_session session;
  char *id = NULL;
  int rc;

  session = malloc(sizeof (struct ssh_session_struct));
  if (session == NULL) {
    return NULL;
  }
  ZERO_STRUCTP(session);

  session->next_crypto = crypto_new();
  if (session->next_crypto == NULL) {
    goto err;
  }

  session->socket = ssh_socket_new(session);
  if (session->socket == NULL) {
    goto err;
  }

  session->out_buffer = ssh_buffer_new();
  if (session->out_buffer == NULL) {
    goto err;
  }

  session->in_buffer=ssh_buffer_new();
  if (session->in_buffer == NULL) {
    goto err;
  }

  session->alive = 0;
  session->auth_methods = 0;
  ssh_set_blocking(session, 1);
  session->maxchannel = FIRST_CHANNEL;

#ifndef _WIN32
    session->agent = ssh_agent_new(session);
    if (session->agent == NULL) {
      goto err;
    }
#endif /* _WIN32 */

    /* OPTIONS */
    session->opts.StrictHostKeyChecking = 1;
    session->opts.port = 0;
    session->opts.fd = -1;
    session->opts.compressionlevel=7;
    session->opts.nodelay = 0;
    session->opts.flags = SSH_OPT_FLAG_PASSWORD_AUTH | SSH_OPT_FLAG_PUBKEY_AUTH |
            SSH_OPT_FLAG_KBDINT_AUTH | SSH_OPT_FLAG_GSSAPI_AUTH;
    session->opts.identity = ssh_list_new();
    if (session->opts.identity == NULL) {
      goto err;
    }

    id = strdup("%d/id_ed25519");
    if (id == NULL) {
      goto err;
    }
    rc = ssh_list_append(session->opts.identity, id);
    if (rc == SSH_ERROR) {
      goto err;
    }

#ifdef HAVE_ECC
    id = strdup("%d/id_ecdsa");
    if (id == NULL) {
      goto err;
    }
    rc = ssh_list_append(session->opts.identity, id);
    if (rc == SSH_ERROR) {
      goto err;
    }
#endif

    id = strdup("%d/id_rsa");
    if (id == NULL) {
      goto err;
    }
    rc = ssh_list_append(session->opts.identity, id);
    if (rc == SSH_ERROR) {
      goto err;
    }

#ifdef HAVE_DSA
    id = strdup("%d/id_dsa");
    if (id == NULL) {
      goto err;
    }
    rc = ssh_list_append(session->opts.identity, id);
    if (rc == SSH_ERROR) {
      goto err;
    }
#endif

    return session;

err:
    free(id);
    ssh_free(session);
    return NULL;
}
示例#6
0
SSH_SESSION *ssh_bind_accept(SSH_BIND *ssh_bind) {
  SSH_SESSION *session;
  PRIVATE_KEY *dsa = NULL;
  PRIVATE_KEY *rsa = NULL;
  int fd = -1;

  if (ssh_bind->bindfd < 0) {
    ssh_set_error(ssh_bind, SSH_FATAL,
        "Can't accept new clients on a not bound socket.");
    return NULL;
  }

  if (ssh_bind->options->dsakey == NULL || ssh_bind->options->rsakey == NULL) {
    ssh_set_error(ssh_bind, SSH_FATAL,
        "DSA or RSA host key file must be set before accept()");
    return NULL;
  }

  if (ssh_bind->options->dsakey) {
    dsa = _privatekey_from_file(ssh_bind, ssh_bind->options->dsakey, TYPE_DSS);
    if (dsa == NULL) {
      return NULL;
    }
  }

  if (ssh_bind->options->rsakey) {
    rsa = _privatekey_from_file(ssh_bind, ssh_bind->options->rsakey, TYPE_RSA);
    if (rsa == NULL) {
      privatekey_free(dsa);
      return NULL;
    }
  }

  fd = accept(ssh_bind->bindfd, NULL, NULL);
  if (fd < 0) {
    ssh_set_error(ssh_bind, SSH_FATAL,
        "Accepting a new connection: %s",
        strerror(errno));
    privatekey_free(dsa);
    privatekey_free(rsa);
    return NULL;
  }

  session = ssh_new();
  if (session == NULL) {
    ssh_set_error(ssh_bind, SSH_FATAL, "Not enough space");
    privatekey_free(dsa);
    privatekey_free(rsa);
    return NULL;
  }
  session->server = 1;
  session->version = 2;
  session->options = ssh_options_copy(ssh_bind->options);
  if (session->options == NULL) {
    ssh_set_error(ssh_bind, SSH_FATAL, "No space left");
    privatekey_free(dsa);
    privatekey_free(rsa);
    ssh_cleanup(session);
    return NULL;
  }

  ssh_socket_free(session->socket);
  session->socket = ssh_socket_new(session);
  if (session->socket == NULL) {
    privatekey_free(dsa);
    privatekey_free(rsa);
    ssh_cleanup(session);
    return NULL;
  }
  ssh_socket_set_fd(session->socket,fd);
  session->dsa_key = dsa;
  session->rsa_key = rsa;

  return session;
}
示例#7
0
int ssh_bind_accept(ssh_bind sshbind, ssh_session session) {
  socket_t fd = SSH_INVALID_SOCKET;
  int i;

  if (sshbind->bindfd == SSH_INVALID_SOCKET) {
    ssh_set_error(sshbind, SSH_FATAL,
        "Can't accept new clients on a not bound socket.");
    return SSH_ERROR;
  }
  if(session == NULL){
  	ssh_set_error(sshbind, SSH_FATAL,"session is null");
  	return SSH_ERROR;
  }

  fd = accept(sshbind->bindfd, NULL, NULL);
  if (fd == SSH_INVALID_SOCKET) {
    ssh_set_error(sshbind, SSH_FATAL,
        "Accepting a new connection: %s",
        strerror(errno));
    return SSH_ERROR;
  }

  session->server = 1;
  session->version = 2;

  /* copy options */
  for (i = 0; i < 10; ++i) {
    if (sshbind->wanted_methods[i]) {
      session->wanted_methods[i] = strdup(sshbind->wanted_methods[i]);
      if (session->wanted_methods[i] == NULL) {
        return SSH_ERROR;
      }
    }
  }

  if (sshbind->bindaddr == NULL)
    session->bindaddr = NULL;
  else {
    SAFE_FREE(session->bindaddr);
    session->bindaddr = strdup(sshbind->bindaddr);
    if (session->bindaddr == NULL) {
      return SSH_ERROR;
    }
  }

  session->log_verbosity = sshbind->log_verbosity;

  ssh_socket_free(session->socket);
  session->socket = ssh_socket_new(session);
  if (session->socket == NULL) {
    /* perhaps it may be better to copy the error from session to sshbind */
    ssh_set_error_oom(sshbind);
    return SSH_ERROR;
  }
  ssh_socket_set_fd(session->socket, fd);
  ssh_socket_get_poll_handle_out(session->socket);
  session->dsa_key = sshbind->dsa;
  session->rsa_key = sshbind->rsa;

return SSH_OK;
}