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; }
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; }
/** * @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; }
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; }
/** * @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; }
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; }
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; }