PktOut *ssh2_portfwd_chanopen( struct ssh2_connection_state *s, struct ssh2_channel *c, const char *hostname, int port, const char *description, const SocketPeerInfo *pi) { PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */ PktOut *pktout; /* * In server mode, this function is called by portfwdmgr in * response to PortListeners that were set up by calling * portfwdmgr_listen, which means that the hostname and port * parameters will identify the listening socket on which a * connection just came in. */ if (pi && pi->log_text) ppl_logevent("Forwarding connection to listening port %s:%d from %s", hostname, port, pi->log_text); else ppl_logevent("Forwarding connection to listening port %s:%d", hostname, port); pktout = ssh2_chanopen_init(c, "forwarded-tcpip"); put_stringz(pktout, hostname); put_uint32(pktout, port); put_stringz(pktout, (pi && pi->addr_text ? pi->addr_text : "0.0.0.0")); put_uint32(pktout, (pi && pi->port >= 0 ? pi->port : 0)); return pktout; }
static void ecdsa_public_blob(ssh_key *key, BinarySink *bs) { struct ecdsa_key *ek = container_of(key, struct ecdsa_key, sshk); put_stringz(bs, ek->sshk.vt->ssh_id); put_stringz(bs, ek->curve->name); put_wpoint(bs, ek->publicKey, ek->curve, false); }
struct sftp_request *fxp_rename_send(const char *srcfname, const char *dstfname) { struct sftp_request *req = sftp_alloc_request(); struct sftp_packet *pktout; pktout = sftp_pkt_init(SSH_FXP_RENAME); put_uint32(pktout, req->id); put_stringz(pktout, srcfname); put_stringz(pktout, dstfname); sftp_send(pktout); return req; }
static void ecdsa_openssh_blob(ssh_key *key, BinarySink *bs) { struct ecdsa_key *ek = container_of(key, struct ecdsa_key, sshk); put_stringz(bs, ek->curve->name); put_wpoint(bs, ek->publicKey, ek->curve, false); put_mp_ssh2(bs, ek->privateKey); }
static void rsa2_sign(ssh_key *key, ptrlen data, unsigned flags, BinarySink *bs) { RSAKey *rsa = container_of(key, RSAKey, sshk); unsigned char *bytes; size_t nbytes; mp_int *in, *out; const ssh_hashalg *halg; const char *sign_alg_name; halg = rsa2_hash_alg_for_flags(flags, &sign_alg_name); nbytes = (mp_get_nbits(rsa->modulus) + 7) / 8; bytes = rsa_pkcs1_signature_string(nbytes, halg, data); in = mp_from_bytes_be(make_ptrlen(bytes, nbytes)); smemclr(bytes, nbytes); sfree(bytes); out = rsa_privkey_op(in, rsa); mp_free(in); put_stringz(bs, sign_alg_name); nbytes = (mp_get_nbits(out) + 7) / 8; put_uint32(bs, nbytes); for (size_t i = 0; i < nbytes; i++) put_byte(bs, mp_get_byte(out, nbytes - 1 - i)); mp_free(out); }
static void rsa2_public_blob(ssh_key *key, BinarySink *bs) { RSAKey *rsa = container_of(key, RSAKey, sshk); put_stringz(bs, "ssh-rsa"); put_mp_ssh2(bs, rsa->exponent); put_mp_ssh2(bs, rsa->modulus); }
static void default_reply_ok(SftpReplyBuilder *reply) { DefaultSftpReplyBuilder *d = container_of(reply, DefaultSftpReplyBuilder, rb); d->pkt->type = SSH_FXP_STATUS; put_uint32(d->pkt, SSH_FX_OK); put_stringz(d->pkt, ""); }
static void default_reply_error( SftpReplyBuilder *reply, unsigned code, const char *msg) { DefaultSftpReplyBuilder *d = container_of(reply, DefaultSftpReplyBuilder, rb); d->pkt->type = SSH_FXP_STATUS; put_uint32(d->pkt, code); put_stringz(d->pkt, msg); }
/* * Retrieve the attributes of a file. We have fxp_stat which works * on filenames, and fxp_fstat which works on open file handles. */ struct sftp_request *fxp_stat_send(const char *fname) { struct sftp_request *req = sftp_alloc_request(); struct sftp_packet *pktout; pktout = sftp_pkt_init(SSH_FXP_STAT); put_uint32(pktout, req->id); put_stringz(pktout, fname); sftp_send(pktout); return req; }
struct sftp_request *fxp_rmdir_send(const char *path) { struct sftp_request *req = sftp_alloc_request(); struct sftp_packet *pktout; pktout = sftp_pkt_init(SSH_FXP_RMDIR); put_uint32(pktout, req->id); put_stringz(pktout, path); sftp_send(pktout); return req; }
static void ecdsa_sign(ssh_key *key, ptrlen data, unsigned flags, BinarySink *bs) { struct ecdsa_key *ek = container_of(key, struct ecdsa_key, sshk); const struct ecsign_extra *extra = (const struct ecsign_extra *)ek->sshk.vt->extra; assert(ek->privateKey); mp_int *z = ecdsa_signing_exponent_from_data(ek->curve, extra, data); /* Generate k between 1 and curve->n, using the same deterministic * k generation system we use for conventional DSA. */ mp_int *k; { unsigned char digest[20]; hash_simple(&ssh_sha1, data, digest); k = dss_gen_k( "ECDSA deterministic k generator", ek->curve->w.G_order, ek->privateKey, digest, sizeof(digest)); } WeierstrassPoint *kG = ecc_weierstrass_multiply(ek->curve->w.G, k); mp_int *x; ecc_weierstrass_get_affine(kG, &x, NULL); ecc_weierstrass_point_free(kG); /* r = kG.x mod order(G) */ mp_int *r = mp_mod(x, ek->curve->w.G_order); mp_free(x); /* s = (z + r * priv)/k mod n */ mp_int *rPriv = mp_modmul(r, ek->privateKey, ek->curve->w.G_order); mp_int *numerator = mp_modadd(z, rPriv, ek->curve->w.G_order); mp_free(z); mp_free(rPriv); mp_int *kInv = mp_invert(k, ek->curve->w.G_order); mp_free(k); mp_int *s = mp_modmul(numerator, kInv, ek->curve->w.G_order); mp_free(numerator); mp_free(kInv); /* Format the output */ put_stringz(bs, ek->sshk.vt->ssh_id); strbuf *substr = strbuf_new(); put_mp_ssh2(substr, r); put_mp_ssh2(substr, s); put_stringsb(bs, substr); mp_free(r); mp_free(s); }
void ssh2channel_send_exit_signal_numeric( SshChannel *sc, int signum, bool core_dumped, ptrlen msg) { struct ssh2_channel *c = container_of(sc, struct ssh2_channel, sc); struct ssh2_connection_state *s = c->connlayer; PktOut *pktout = ssh2_chanreq_init(c, "exit-signal", NULL, NULL); put_uint32(pktout, signum); put_bool(pktout, core_dumped); put_stringpl(pktout, msg); put_stringz(pktout, ""); /* language tag */ pq_push(s->ppl.out_pq, pktout); }
struct sftp_request *fxp_mkdir_send(const char *path, const struct fxp_attrs *attrs) { struct sftp_request *req = sftp_alloc_request(); struct sftp_packet *pktout; pktout = sftp_pkt_init(SSH_FXP_MKDIR); put_uint32(pktout, req->id); put_stringz(pktout, path); put_fxp_attrs(pktout, attrs ? *attrs : no_attrs); sftp_send(pktout); return req; }
SshChannel *ssh2_serverside_x11_open( ConnectionLayer *cl, Channel *chan, const SocketPeerInfo *pi) { struct ssh2_connection_state *s = container_of(cl, struct ssh2_connection_state, cl); PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */ struct ssh2_channel *c = snew(struct ssh2_channel); PktOut *pktout; c->connlayer = s; ssh2_channel_init(c); c->halfopen = true; c->chan = chan; ppl_logevent("Forwarding X11 channel to client"); pktout = ssh2_chanopen_init(c, "x11"); put_stringz(pktout, (pi && pi->addr_text ? pi->addr_text : "0.0.0.0")); put_uint32(pktout, (pi && pi->port >= 0 ? pi->port : 0)); pq_push(s->ppl.out_pq, pktout); return &c->sc; }
static void eddsa_sign(ssh_key *key, ptrlen data, unsigned flags, BinarySink *bs) { struct eddsa_key *ek = container_of(key, struct eddsa_key, sshk); const struct ecsign_extra *extra = (const struct ecsign_extra *)ek->sshk.vt->extra; assert(ek->privateKey); /* * EdDSA prescribes a specific method of generating the random * nonce integer for the signature. (A verifier can't tell * whether you followed that method, but it's important to * follow it anyway, because test vectors will want a specific * signature for a given message, and because this preserves * determinism of signatures even if the same signature were * made twice by different software.) */ /* * First, we hash the private key integer (bare, little-endian) * into a hash generating 2*fieldBytes of output. */ unsigned char hash[MAX_HASH_LEN]; ssh_hash *h = ssh_hash_new(extra->hash); for (size_t i = 0; i < ek->curve->fieldBytes; ++i) put_byte(h, mp_get_byte(ek->privateKey, i)); ssh_hash_final(h, hash); /* * The first half of the output hash is converted into an * integer a, by the standard EdDSA transformation. */ mp_int *a = eddsa_exponent_from_hash( make_ptrlen(hash, ek->curve->fieldBytes), ek->curve); /* * The second half of the hash of the private key is hashed again * with the message to be signed, and used as an exponent to * generate the signature point r. */ h = ssh_hash_new(extra->hash); put_data(h, hash + ek->curve->fieldBytes, extra->hash->hlen - ek->curve->fieldBytes); put_datapl(h, data); ssh_hash_final(h, hash); mp_int *log_r_unreduced = mp_from_bytes_le( make_ptrlen(hash, extra->hash->hlen)); mp_int *log_r = mp_mod(log_r_unreduced, ek->curve->e.G_order); mp_free(log_r_unreduced); EdwardsPoint *r = ecc_edwards_multiply(ek->curve->e.G, log_r); /* * Encode r now, because we'll need its encoding for the next * hashing step as well as to write into the actual signature. */ strbuf *r_enc = strbuf_new(); put_epoint(r_enc, r, ek->curve, true); /* omit string header */ ecc_edwards_point_free(r); /* * Compute the hash of (r || public key || message) just as * eddsa_verify does. */ mp_int *H = eddsa_signing_exponent_from_data( ek, extra, ptrlen_from_strbuf(r_enc), data); /* And then s = (log(r) + H*a) mod order(G). */ mp_int *Ha = mp_modmul(H, a, ek->curve->e.G_order); mp_int *s = mp_modadd(log_r, Ha, ek->curve->e.G_order); mp_free(H); mp_free(a); mp_free(Ha); mp_free(log_r); /* Format the output */ put_stringz(bs, ek->sshk.vt->ssh_id); put_uint32(bs, r_enc->len + ek->curve->fieldBytes); put_data(bs, r_enc->u, r_enc->len); strbuf_free(r_enc); for (size_t i = 0; i < ek->curve->fieldBytes; ++i) put_byte(bs, mp_get_byte(s, i)); mp_free(s); }