int mm_answer_bsdauthquery(int sock, struct sshbuf *m) { char *name, *infotxt, **prompts; u_int numprompts, *echo_on, success; int r; success = bsdauth_query(authctxt, &name, &infotxt, &numprompts, &prompts, &echo_on) < 0 ? 0 : 1; sshbuf_reset(m); if ((r = sshbuf_put_u32(m, success)) != 0 || (success && (r = sshbuf_put_cstring(m, prompts[0])) != 0)) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("%s: sending challenge success: %u", __func__, success); mm_request_send(sock, MONITOR_ANS_BSDAUTHQUERY, m); if (success) { free(name); free(infotxt); free(prompts); free(echo_on); } return (0); }
/* helper */ static void chan_shutdown_write(struct ssh *ssh, Channel *c) { sshbuf_reset(c->output); if (c->type == SSH_CHANNEL_LARVAL) return; /* shutdown failure is allowed if write failed already */ debug2("channel %d: %s (i%d o%d sock %d wfd %d efd %d [%s])", c->self, __func__, c->istate, c->ostate, c->sock, c->wfd, c->efd, channel_format_extended_usage(c)); if (c->sock != -1) { if (shutdown(c->sock, SHUT_WR) < 0) { debug2("channel %d: %s: shutdown() failed for " "fd %d [i%d o%d]: %.100s", c->self, __func__, c->sock, c->istate, c->ostate, strerror(errno)); } } else { if (channel_close_fd(ssh, &c->wfd) < 0) { logit("channel %d: %s: close() failed for " "fd %d [i%d o%d]: %.100s", c->self, __func__, c->wfd, c->istate, c->ostate, strerror(errno)); } } }
int mm_answer_authpassword(int sock, struct sshbuf *m) { static int call_count; char *passwd; int r, authenticated; size_t plen; if ((r = sshbuf_get_cstring(m, &passwd, &plen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); /* Only authenticate if the context is valid */ authenticated = options.password_authentication && auth_password(authctxt, passwd); explicit_bzero(passwd, strlen(passwd)); free(passwd); sshbuf_reset(m); if ((r = sshbuf_put_u32(m, authenticated)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_AUTHPASSWORD, m); call_count++; if (plen == 0 && call_count == 1) auth_method = "none"; else auth_method = "password"; /* Causes monitor loop to terminate if authenticated */ return (authenticated); }
/* put algorithm proposal into buffer */ int kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) { u_int i; int r; sshbuf_reset(b); /* * add a dummy cookie, the cookie will be overwritten by * kex_send_kexinit(), each time a kexinit is set */ for (i = 0; i < KEX_COOKIE_LEN; i++) { if ((r = sshbuf_put_u8(b, 0)) != 0) return r; } for (i = 0; i < PROPOSAL_MAX; i++) { if ((r = sshbuf_put_cstring(b, proposal[i])) != 0) return r; } if ((r = sshbuf_put_u8(b, 0)) != 0 || /* first_kex_packet_follows */ (r = sshbuf_put_u32(b, 0)) != 0) /* uint32 reserved */ return r; return 0; }
static int recv_msg(struct sshbuf *m) { u_int l, len; u_char c, buf[1024]; int r; if ((len = atomicio(read, fd, buf, 4)) != 4) { error("read from helper failed: %u", len); return (0); /* XXX */ } len = PEEK_U32(buf); if (len > 256 * 1024) fatal("response too long: %u", len); /* read len bytes into m */ sshbuf_reset(m); while (len > 0) { l = len; if (l > sizeof(buf)) l = sizeof(buf); if (atomicio(read, fd, buf, l) != l) { error("response from helper failed."); return (0); /* XXX */ } if ((r = sshbuf_put(m, buf, l)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); len -= l; } if ((r = sshbuf_get_u8(m, &c)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); return c; }
int mm_answer_gss_accept_ctx(int sock, struct sshbuf *m) { gss_buffer_desc in; gss_buffer_desc out = GSS_C_EMPTY_BUFFER; OM_uint32 major, minor; OM_uint32 flags = 0; /* GSI needs this */ size_t len; u_char *p; int r; if ((r = sshbuf_get_string(m, &p, &len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); in.value = p; in.length = len; major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); free(in.value); sshbuf_reset(m); if ((r = sshbuf_put_u32(m, major)) != 0 || (r = sshbuf_put_string(m, out.value, out.length)) != 0 || (r = sshbuf_put_u32(m, flags)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); mm_request_send(sock, MONITOR_ANS_GSSSTEP, m); gss_release_buffer(&minor, &out); if (major == GSS_S_COMPLETE) { monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); } return 0; }
int mm_answer_gss_checkmic(int sock, struct sshbuf *m) { gss_buffer_desc gssbuf, mic; OM_uint32 ret; size_t len; int r; u_char *p; if ((r = sshbuf_get_string(m, &p, &len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); gssbuf.value = p; gssbuf.length = len; if ((r = sshbuf_get_string(m, &p, &len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); mic.value = p; mic.length = len; ret = ssh_gssapi_checkmic(gsscontext, &gssbuf, &mic); free(gssbuf.value); free(mic.value); sshbuf_reset(m); if ((r = sshbuf_put_u32(m, ret)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); mm_request_send(sock, MONITOR_ANS_GSSCHECKMIC, m); if (!GSS_ERROR(ret)) monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); return 0; }
int kexc25519_shared_key(const u_char key[CURVE25519_SIZE], const u_char pub[CURVE25519_SIZE], struct sshbuf *out) { u_char shared_key[CURVE25519_SIZE]; int r; #ifdef USING_WOLFSSL int ret, ssize = CURVE25519_SIZE; ret = wolfSSL_EC25519_shared_key(shared_key, &ssize, key, CURVE25519_SIZE, pub, CURVE25519_SIZE); if (ret != 1 || ssize != CURVE25519_SIZE) fatal("%s: wolfSSL_EC25519_shared_key failed", __func__); #else /* Check for all-zero public key */ explicit_bzero(shared_key, CURVE25519_SIZE); if (timingsafe_bcmp(pub, shared_key, CURVE25519_SIZE) == 0) return SSH_ERR_KEY_INVALID_EC_VALUE; crypto_scalarmult_curve25519(shared_key, key, pub); #endif /* USING_WOLFSSL */ #ifdef DEBUG_KEXECDH dump_digest("shared secret", shared_key, CURVE25519_SIZE); #endif sshbuf_reset(out); r = sshbuf_put_bignum2_bytes(out, shared_key, CURVE25519_SIZE); explicit_bzero(shared_key, CURVE25519_SIZE); return r; }
int mm_answer_gss_setup_ctx(int sock, struct sshbuf *m) { gss_OID_desc goid; OM_uint32 major; size_t len; u_char *p; int r; if ((r = sshbuf_get_string(m, &p, &len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); goid.elements = p; goid.length = len; major = ssh_gssapi_server_ctx(&gsscontext, &goid); free(goid.elements); sshbuf_reset(m); if ((r = sshbuf_put_u32(m, major)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); mm_request_send(sock, MONITOR_ANS_GSSSETUP, m); /* Now we have a context, enable the step */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1); return (0); }
int mm_answer_sesskey(int sock, struct sshbuf *m) { BIGNUM *p; int r, rsafail; /* Turn off permissions */ monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 0); if ((p = BN_new()) == NULL) fatal("%s: BN_new", __func__); if ((r = sshbuf_get_bignum2(m, p)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); rsafail = ssh1_session_key(p); sshbuf_reset(m); if ((r = sshbuf_put_u32(m, rsafail)) != 0 || (r = sshbuf_put_bignum2(m, p)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); BN_clear_free(p); mm_request_send(sock, MONITOR_ANS_SESSKEY, m); /* Turn on permissions for sessid passing */ monitor_permit(mon_dispatch, MONITOR_REQ_SESSID, 1); return (0); }
int ssh_msg_recv(int fd, struct sshbuf *m) { u_char buf[4], *p; u_int msg_len; int r; debug3("ssh_msg_recv entering"); if (atomicio(read, fd, buf, sizeof(buf)) != sizeof(buf)) { if (errno != EPIPE) error("ssh_msg_recv: read: header"); return (-1); } msg_len = get_u32(buf); if (msg_len > 256 * 1024) { error("ssh_msg_recv: read: bad msg_len %u", msg_len); return (-1); } sshbuf_reset(m); if ((r = sshbuf_reserve(m, msg_len, &p)) != 0) { error("%s: buffer error: %s", __func__, ssh_err(r)); return -1; } if (atomicio(read, fd, p, msg_len) != msg_len) { error("ssh_msg_recv: read: %s", strerror(errno)); return (-1); } return (0); }
int mm_answer_bsdauthrespond(int sock, struct sshbuf *m) { char *response; int r, authok; if (authctxt->as == 0) fatal("%s: no bsd auth session", __func__); if ((r = sshbuf_get_cstring(m, &response, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); authok = options.challenge_response_authentication && auth_userresponse(authctxt->as, response, 0); authctxt->as = NULL; debug3("%s: <%s> = <%d>", __func__, response, authok); free(response); sshbuf_reset(m); if ((r = sshbuf_put_u32(m, authok)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("%s: sending authenticated: %d", __func__, authok); mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m); if (compat20) { auth_method = "keyboard-interactive"; auth_submethod = "bsdauth"; } else auth_method = "bsdauth"; return (authok != 0); }
/* * Caclulate a new key after a reconnect */ void calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge) { int r; const EVP_MD *md = EVP_sha1(); EVP_MD_CTX ctx; char hash[EVP_MAX_MD_SIZE]; struct sshbuf *b; if ((b = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_u64(b, *key)) != 0 || (r = sshbuf_put_u64(b, cookie)) != 0 || (r = sshbuf_put_u64(b, challenge)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); EVP_DigestInit(&ctx, md); EVP_DigestUpdate(&ctx, sshbuf_ptr(b), sshbuf_len(b)); EVP_DigestFinal(&ctx, hash, NULL); sshbuf_reset(b); if ((r = sshbuf_put(b, hash, EVP_MD_size(md))) != 0 || (r = sshbuf_get_u64(b, key)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); sshbuf_free(b); }
void auth_debug_reset(void) { if (auth_debug != NULL) sshbuf_reset(auth_debug); else if ((auth_debug = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); }
static void send_msg(struct sshbuf *m) { int r; if ((r = sshbuf_put_stringb(oqueue, m)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); sshbuf_reset(m); }
static struct sshkey * keygrab_ssh1(con *c) { static struct sshkey *rsa; static struct sshbuf *msg; int r; u_char type; if (rsa == NULL) { if ((rsa = sshkey_new(KEY_RSA1)) == NULL) { error("%s: sshkey_new failed", __func__); return NULL; } if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); } if ((r = sshbuf_put(msg, c->c_data, c->c_plen)) != 0 || (r = sshbuf_consume(msg, 8 - (c->c_plen & 7))) != 0 || /* padding */ (r = sshbuf_get_u8(msg, &type)) != 0) goto buf_err; if (type != (int) SSH_SMSG_PUBLIC_KEY) { error("%s: invalid packet type", c->c_name); sshbuf_reset(msg); return NULL; } if ((r = sshbuf_consume(msg, 8)) != 0 || /* cookie */ /* server key */ (r = sshbuf_get_u32(msg, NULL)) != 0 || (r = sshbuf_get_bignum1(msg, NULL)) != 0 || (r = sshbuf_get_bignum1(msg, NULL)) != 0 || /* host key */ (r = sshbuf_get_u32(msg, NULL)) != 0 || (r = sshbuf_get_bignum1(msg, rsa->rsa->e)) != 0 || (r = sshbuf_get_bignum1(msg, rsa->rsa->n)) != 0) { buf_err: error("%s: buffer error: %s", __func__, ssh_err(r)); sshbuf_reset(msg); return NULL; } sshbuf_reset(msg); return (rsa); }
/* Load a key from a fd into a buffer */ int sshkey_load_file(int fd, struct sshbuf *blob) { u_char buf[1024]; size_t len; struct stat st; int r, dontmax = 0; if (fstat(fd, &st) < 0) return SSH_ERR_SYSTEM_ERROR; if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && st.st_size > MAX_KEY_FILE_SIZE) return SSH_ERR_INVALID_FORMAT; /* * Pre-allocate the buffer used for the key contents and clamp its * maximum size. This ensures that key contents are never leaked via * implicit realloc() in the sshbuf code. */ if ((st.st_mode & S_IFREG) == 0 || st.st_size <= 0) { st.st_size = 64*1024; /* 64k should be enough for anyone :) */ dontmax = 1; } if ((r = sshbuf_allocate(blob, st.st_size)) != 0 || (dontmax && (r = sshbuf_set_max_size(blob, st.st_size)) != 0)) return r; for (;;) { if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) { if (errno == EPIPE) break; r = SSH_ERR_SYSTEM_ERROR; goto out; } if ((r = sshbuf_put(blob, buf, len)) != 0) goto out; if (sshbuf_len(blob) > MAX_KEY_FILE_SIZE) { r = SSH_ERR_INVALID_FORMAT; goto out; } } if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && st.st_size != (off_t)sshbuf_len(blob)) { r = SSH_ERR_FILE_CHANGED; goto out; } r = 0; out: explicit_bzero(buf, sizeof(buf)); if (r != 0) sshbuf_reset(blob); return r; }
static int monitor_read_log(struct monitor *pmonitor) { struct sshbuf *logmsg; u_int len, level; u_char *p; char *msg; int r; if ((logmsg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); /* Read length */ if ((r = sshbuf_reserve(logmsg, 4, &p)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (atomicio(read, pmonitor->m_log_recvfd, p, 4) != 4) { if (errno == EPIPE) { sshbuf_free(logmsg); debug("%s: child log fd closed", __func__); close(pmonitor->m_log_recvfd); pmonitor->m_log_recvfd = -1; return -1; } fatal("%s: log fd read: %s", __func__, strerror(errno)); } if ((r = sshbuf_get_u32(logmsg, &len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (len <= 4 || len > 8192) fatal("%s: invalid log message length %u", __func__, len); /* Read severity, message */ sshbuf_reset(logmsg); if ((r = sshbuf_reserve(logmsg, len, &p)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (atomicio(read, pmonitor->m_log_recvfd, p, len) != len) fatal("%s: log fd read: %s", __func__, strerror(errno)); /* Log it */ if ((r = sshbuf_get_u32(logmsg, &level)) != 0 || (r = sshbuf_get_cstring(logmsg, &msg, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (log_level_name(level) == NULL) fatal("%s: invalid log level %u (corrupted message?)", __func__, level); do_log2(level, "%s [preauth]", msg); sshbuf_free(logmsg); free(msg); return 0; }
int mm_answer_rsa_keyallowed(int sock, struct sshbuf *m) { BIGNUM *client_n; struct sshkey *key = NULL; u_char *blob = NULL; size_t blen = 0; int r, allowed = 0; debug3("%s entering", __func__); auth_method = "rsa"; if (options.rsa_authentication && authctxt->valid) { if ((client_n = BN_new()) == NULL) fatal("%s: BN_new", __func__); if ((r = sshbuf_get_bignum2(m, client_n)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); allowed = auth_rsa_key_allowed(authctxt->pw, client_n, &key); BN_clear_free(client_n); } sshbuf_reset(m); if ((r = sshbuf_put_u32(m, allowed)) != 0 || (r = sshbuf_put_u32(m, forced_command != NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); /* clear temporarily storage (used by generate challenge) */ monitor_reset_key_state(); if (allowed && key != NULL) { key->type = KEY_RSA; /* cheat for key_to_blob */ if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) fatal("%s: key_to_blob failed: %s", __func__, ssh_err(r)); if ((r = sshbuf_put_string(m, blob, blen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); /* Save temporarily for comparison in verify */ key_blob = blob; key_bloblen = blen; key_blobtype = MM_RSAUSERKEY; } if (key != NULL) sshkey_free(key); mm_request_send(sock, MONITOR_ANS_RSAKEYALLOWED, m); monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 0); return (0); }
void ssh_gssapi_buildmic(struct sshbuf *b, const char *user, const char *service, const char *context) { int r; sshbuf_reset(b); if ((r = sshbuf_put_string(b, session_id2, session_id2_len)) != 0 || (r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || (r = sshbuf_put_cstring(b, user)) != 0 || (r = sshbuf_put_cstring(b, service)) != 0 || (r = sshbuf_put_cstring(b, context)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); }
/* * Reassemble an argument vector into a string, quoting and escaping as * necessary. Caller must free returned string. */ static char * assemble_argv(int argc, char **argv) { int i, j, ws, r; char c, *ret; struct sshbuf *buf, *arg; if ((buf = sshbuf_new()) == NULL || (arg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); for (i = 0; i < argc; i++) { ws = 0; sshbuf_reset(arg); for (j = 0; argv[i][j] != '\0'; j++) { r = 0; c = argv[i][j]; switch (c) { case ' ': case '\t': ws = 1; r = sshbuf_put_u8(arg, c); break; case '\\': case '\'': case '"': if ((r = sshbuf_put_u8(arg, '\\')) != 0) break; /* FALLTHROUGH */ default: r = sshbuf_put_u8(arg, c); break; } if (r != 0) fatal("%s: sshbuf_put_u8: %s", __func__, ssh_err(r)); } if ((i != 0 && (r = sshbuf_put_u8(buf, ' ')) != 0) || (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0) || (r = sshbuf_putb(buf, arg)) != 0 || (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0)) fatal("%s: buffer error: %s", __func__, ssh_err(r)); } if ((ret = malloc(sshbuf_len(buf) + 1)) == NULL) fatal("%s: malloc failed", __func__); memcpy(ret, sshbuf_ptr(buf), sshbuf_len(buf)); ret[sshbuf_len(buf)] = '\0'; sshbuf_free(buf); sshbuf_free(arg); return ret; }
int mm_answer_auth2_read_banner(int sock, struct sshbuf *m) { char *banner; int r; sshbuf_reset(m); banner = auth2_read_banner(); if ((r = sshbuf_put_cstring(m, banner != NULL ? banner : "")) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); mm_request_send(sock, MONITOR_ANS_AUTH2_READ_BANNER, m); free(banner); return (0); }
int kexc25519_shared_key(const u_char key[CURVE25519_SIZE], const u_char pub[CURVE25519_SIZE], struct sshbuf *out) { u_char shared_key[CURVE25519_SIZE]; int r; crypto_scalarmult_curve25519(shared_key, key, pub); #ifdef DEBUG_KEXECDH dump_digest("shared secret", shared_key, CURVE25519_SIZE); #endif sshbuf_reset(out); r = sshbuf_put_bignum2_bytes(out, shared_key, CURVE25519_SIZE); explicit_bzero(shared_key, CURVE25519_SIZE); return r; }
int mm_answer_rsa_response(int sock, struct sshbuf *m) { struct sshkey *key = NULL; u_char *blob, *response; size_t blen, len; int r, success; debug3("%s entering", __func__); if (!authctxt->valid) fatal("%s: authctxt not valid", __func__); if (ssh1_challenge == NULL) fatal("%s: no ssh1_challenge", __func__); if ((r = sshbuf_get_string(m, &blob, &blen)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (!monitor_allowed_key(blob, blen)) fatal("%s: bad key, not previously allowed", __func__); if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY) fatal("%s: key type mismatch: %d", __func__, key_blobtype); if ((r = sshkey_from_blob(blob, blen, &key)) != 0) fatal("%s: received bad key: %s", __func__, ssh_err(r)); if ((r = sshbuf_get_string(m, &response, &len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if (len != 16) fatal("%s: received bad response to challenge", __func__); success = auth_rsa_verify_response(key, ssh1_challenge, response); free(blob); sshkey_free(key); free(response); auth_method = key_blobtype == MM_RSAUSERKEY ? "rsa" : "rhosts-rsa"; /* reset state */ BN_clear_free(ssh1_challenge); ssh1_challenge = NULL; monitor_reset_key_state(); sshbuf_reset(m); if ((r = sshbuf_put_u32(m, success)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); mm_request_send(sock, MONITOR_ANS_RSARESPONSE, m); return (success); }
int mm_answer_pty_cleanup(int sock, struct sshbuf *m) { Session *s; char *tty; int r; debug3("%s entering", __func__); if ((r = sshbuf_get_cstring(m, &tty, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if ((s = session_by_tty(tty)) != NULL) mm_session_close(s); sshbuf_reset(m); free(tty); return (0); }
static int kex_input_newkeys(int type, u_int32_t seq, struct ssh *ssh) { struct kex *kex = ssh->kex; int r; debug("SSH2_MSG_NEWKEYS received"); ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_protocol_error); if ((r = sshpkt_get_end(ssh)) != 0) return r; kex->done = 1; sshbuf_reset(kex->peer); /* sshbuf_reset(kex->my); */ kex->flags &= ~KEX_INIT_SENT; free(kex->name); kex->name = NULL; return 0; }
int pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp) { struct sshkey *k; int r; u_char *blob; size_t blen; u_int nkeys, i; struct sshbuf *msg; if (fd < 0 && pkcs11_start_helper() < 0) return (-1); if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_u8(msg, SSH_AGENTC_ADD_SMARTCARD_KEY)) != 0 || (r = sshbuf_put_cstring(msg, name)) != 0 || (r = sshbuf_put_cstring(msg, pin)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(msg); sshbuf_reset(msg); if (recv_msg(msg) == SSH2_AGENT_IDENTITIES_ANSWER) { if ((r = sshbuf_get_u32(msg, &nkeys)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); *keysp = xcalloc(nkeys, sizeof(struct sshkey *)); for (i = 0; i < nkeys; i++) { /* XXX clean up properly instead of fatal() */ if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 || (r = sshbuf_skip_string(msg)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); if ((r = sshkey_from_blob(blob, blen, &k)) != 0) fatal("%s: bad key: %s", __func__, ssh_err(r)); wrap_key(k->rsa); (*keysp)[i] = k; xfree(blob); } } else { nkeys = -1; } sshbuf_free(msg); return (nkeys); }
int mm_answer_gss_userok(int sock, struct sshbuf *m) { int r, authenticated; authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); sshbuf_reset(m); if ((r = sshbuf_put_u32(m, authenticated)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); auth_method = "gssapi-with-mic"; /* Monitor loop will terminate if authenticated */ return (authenticated); }
/* Communicate with agent: send request and read reply */ static int ssh_request_reply(int sock, struct sshbuf *request, struct sshbuf *reply) { int r; size_t l, len; char buf[1024]; /* Get the length of the message, and format it in the buffer. */ len = sshbuf_len(request); put_u32(buf, len); /* Send the length and then the packet to the agent. */ if (atomicio(vwrite, sock, buf, 4) != 4 || atomicio(vwrite, sock, (u_char *)sshbuf_ptr(request), sshbuf_len(request)) != sshbuf_len(request)) return SSH_ERR_AGENT_COMMUNICATION; /* * Wait for response from the agent. First read the length of the * response packet. */ if (atomicio(read, sock, buf, 4) != 4) return SSH_ERR_AGENT_COMMUNICATION; /* Extract the length, and check it for sanity. */ len = get_u32(buf); if (len > MAX_AGENT_REPLY_LEN) return SSH_ERR_INVALID_FORMAT; /* Read the rest of the response in to the buffer. */ sshbuf_reset(reply); while (len > 0) { l = len; if (l > sizeof(buf)) l = sizeof(buf); if (atomicio(read, sock, buf, l) != l) return SSH_ERR_AGENT_COMMUNICATION; if ((r = sshbuf_put(reply, buf, l)) != 0) return r; len -= l; } return 0; }
int pkcs11_del_provider(char *name) { int r, ret = -1; struct sshbuf *msg; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_u8(msg, SSH_AGENTC_REMOVE_SMARTCARD_KEY)) != 0 || (r = sshbuf_put_cstring(msg, name)) != 0 || (r = sshbuf_put_cstring(msg, "")) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); send_msg(msg); sshbuf_reset(msg); if (recv_msg(msg) == SSH_AGENT_SUCCESS) ret = 0; sshbuf_free(msg); return (ret); }