/* * 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); }
int sshauthopt_deserialise(struct sshbuf *m, struct sshauthopt **optsp) { struct sshauthopt *opts = NULL; int r = SSH_ERR_INTERNAL_ERROR; u_char f; u_int tmp; if ((opts = calloc(1, sizeof(*opts))) == NULL) return SSH_ERR_ALLOC_FAIL; #define OPT_FLAG(x) \ do { \ if ((r = sshbuf_get_u8(m, &f)) != 0) \ goto out; \ opts->x = f; \ } while (0) OPT_FLAG(permit_port_forwarding_flag); OPT_FLAG(permit_agent_forwarding_flag); OPT_FLAG(permit_x11_forwarding_flag); OPT_FLAG(permit_pty_flag); OPT_FLAG(permit_user_rc); OPT_FLAG(restricted); OPT_FLAG(cert_authority); #undef OPT_FLAG if ((r = sshbuf_get_u64(m, &opts->valid_before)) != 0) goto out; /* tunnel number can be negative to indicate "unset" */ if ((r = sshbuf_get_u8(m, &f)) != 0 || (r = sshbuf_get_u32(m, &tmp)) != 0) goto out; opts->force_tun_device = f ? -1 : (int)tmp; /* String options may be NULL */ if ((r = deserialise_nullable_string(m, &opts->cert_principals)) != 0 || (r = deserialise_nullable_string(m, &opts->force_command)) != 0 || (r = deserialise_nullable_string(m, &opts->required_from_host_cert)) != 0 || (r = deserialise_nullable_string(m, &opts->required_from_host_keys)) != 0) goto out; /* Array options */ if ((r = deserialise_array(m, &opts->env, &opts->nenv)) != 0 || (r = deserialise_array(m, &opts->permitopen, &opts->npermitopen)) != 0) goto out; /* success */ r = 0; *optsp = opts; opts = NULL; out: sshauthopt_free(opts); return r; }
int buffer_get_int64_ret(u_int64_t *v, Buffer *buffer) { int ret; if ((ret = sshbuf_get_u64(buffer, v)) != 0) { error("%s: %s", __func__, ssh_err(ret)); return -1; } return 0; }
/* Decode attributes in buffer */ int decode_attrib(struct sshbuf *b, Attrib *a) { int r; attrib_clear(a); if ((r = sshbuf_get_u32(b, &a->flags)) != 0) return r; if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { if ((r = sshbuf_get_u64(b, &a->size)) != 0) return r; } if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { if ((r = sshbuf_get_u32(b, &a->uid)) != 0 || (r = sshbuf_get_u32(b, &a->gid)) != 0) return r; } if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { if ((r = sshbuf_get_u32(b, &a->perm)) != 0) return r; } if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { if ((r = sshbuf_get_u32(b, &a->atime)) != 0 || (r = sshbuf_get_u32(b, &a->mtime)) != 0) return r; } /* vendor-specific extensions */ if (a->flags & SSH2_FILEXFER_ATTR_EXTENDED) { char *type; u_char *data; size_t dlen; u_int i, count; if ((r = sshbuf_get_u32(b, &count)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); for (i = 0; i < count; i++) { if ((r = sshbuf_get_cstring(b, &type, NULL)) != 0 || (r = sshbuf_get_string(b, &data, &dlen)) != 0) return r; debug3("Got file attribute \"%.100s\" len %zu", type, dlen); free(type); free(data); } } return 0; }
static void process_write(u_int32_t id) { u_int64_t off; size_t len; int r, handle, fd, ret, status; u_char *data; if ((r = get_handle(iqueue, &handle)) != 0 || (r = sshbuf_get_u64(iqueue, &off)) != 0 || (r = sshbuf_get_string(iqueue, &data, &len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: write \"%s\" (handle %d) off %llu len %zu", id, handle_to_name(handle), handle, (unsigned long long)off, len); fd = handle_to_fd(handle); if (fd < 0) status = SSH2_FX_FAILURE; else { if (!(handle_to_flags(handle) & O_APPEND) && lseek(fd, off, SEEK_SET) < 0) { status = errno_to_portable(errno); error("process_write: seek failed"); } else { /* XXX ATOMICIO ? */ ret = write(fd, data, len); if (ret < 0) { error("process_write: write failed"); status = errno_to_portable(errno); } else if ((size_t)ret == len) { status = SSH2_FX_OK; handle_update_write(handle, ret); } else { debug2("nothing at all written"); status = SSH2_FX_FAILURE; } } } send_status(id, status); free(data); }
static void process_read(u_int32_t id) { u_char buf[64*1024]; u_int32_t len; int r, handle, fd, ret, status = SSH2_FX_FAILURE; u_int64_t off; if ((r = get_handle(iqueue, &handle)) != 0 || (r = sshbuf_get_u64(iqueue, &off)) != 0 || (r = sshbuf_get_u32(iqueue, &len)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); debug("request %u: read \"%s\" (handle %d) off %llu len %d", id, handle_to_name(handle), handle, (unsigned long long)off, len); if (len > sizeof buf) { len = sizeof buf; debug2("read change len %d", len); } fd = handle_to_fd(handle); if (fd >= 0) { if (lseek(fd, off, SEEK_SET) < 0) { error("process_read: seek failed"); status = errno_to_portable(errno); } else { ret = read(fd, buf, len); if (ret < 0) { status = errno_to_portable(errno); } else if (ret == 0) { status = SSH2_FX_EOF; } else { send_data(id, buf, ret); status = SSH2_FX_OK; handle_update_read(handle, ret); } } } if (status != SSH2_FX_OK) send_status(id, status); }
static void attempt_parse_blob(u_char *blob, size_t len) { struct sshbuf *p1; BIGNUM *bn; #ifdef OPENSSL_HAS_NISTP256 EC_KEY *eck; #endif u_char *s; size_t l; u_int8_t u8; u_int16_t u16; u_int32_t u32; u_int64_t u64; p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); ASSERT_INT_EQ(sshbuf_put(p1, blob, len), 0); sshbuf_get_u8(p1, &u8); sshbuf_get_u16(p1, &u16); sshbuf_get_u32(p1, &u32); sshbuf_get_u64(p1, &u64); if (sshbuf_get_string(p1, &s, &l) == 0) { bzero(s, l); free(s); } bn = BN_new(); sshbuf_get_bignum1(p1, bn); BN_clear_free(bn); bn = BN_new(); sshbuf_get_bignum2(p1, bn); BN_clear_free(bn); #ifdef OPENSSL_HAS_NISTP256 eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); ASSERT_PTR_NE(eck, NULL); sshbuf_get_eckey(p1, eck); EC_KEY_free(eck); #endif sshbuf_free(p1); }
/* * Caclulate a new key after a reconnect */ void calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge) { u_char hash[SSH_DIGEST_MAX_LENGTH]; struct sshbuf *b; int r; 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)); if (ssh_digest_buffer(SSH_DIGEST_SHA1, b, hash, sizeof(hash)) != 0) fatal("%s: digest_buffer failed", __func__); sshbuf_reset(b); if ((r = sshbuf_put(b, hash, ssh_digest_bytes(SSH_DIGEST_SHA1))) != 0 || (r = sshbuf_get_u64(b, key)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); sshbuf_free(b); }