Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mRemoteNG/PuTTYNG.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'ssh/transport2.h')
-rw-r--r--ssh/transport2.h261
1 files changed, 261 insertions, 0 deletions
diff --git a/ssh/transport2.h b/ssh/transport2.h
new file mode 100644
index 00000000..204573fb
--- /dev/null
+++ b/ssh/transport2.h
@@ -0,0 +1,261 @@
+/*
+ * Header connecting the pieces of the SSH-2 transport layer.
+ */
+
+#ifndef PUTTY_SSH2TRANSPORT_H
+#define PUTTY_SSH2TRANSPORT_H
+
+#ifndef NO_GSSAPI
+#include "gssc.h"
+#include "gss.h"
+#define MIN_CTXT_LIFETIME 5 /* Avoid rekey with short lifetime (seconds) */
+#define GSS_KEX_CAPABLE (1<<0) /* Can do GSS KEX */
+#define GSS_CRED_UPDATED (1<<1) /* Cred updated since previous delegation */
+#define GSS_CTXT_EXPIRES (1<<2) /* Context expires before next timer */
+#define GSS_CTXT_MAYFAIL (1<<3) /* Context may expire during handshake */
+#endif
+
+#define DH_MIN_SIZE 1024
+#define DH_MAX_SIZE 8192
+
+struct kexinit_algorithm {
+ ptrlen name;
+ union {
+ struct {
+ const ssh_kex *kex;
+ bool warn;
+ } kex;
+ struct {
+ const ssh_keyalg *hostkey;
+ unsigned hkflags;
+ bool warn;
+ } hk;
+ struct {
+ const ssh_cipheralg *cipher;
+ bool warn;
+ } cipher;
+ struct {
+ const ssh2_macalg *mac;
+ bool etm;
+ } mac;
+ struct {
+ const ssh_compression_alg *comp;
+ bool delayed;
+ } comp;
+ } u;
+};
+struct kexinit_algorithm_list {
+ struct kexinit_algorithm *algs;
+ size_t nalgs, algsize;
+};
+
+#define HOSTKEY_ALGORITHMS(X) \
+ X(HK_ED25519, ssh_ecdsa_ed25519) \
+ X(HK_ED448, ssh_ecdsa_ed448) \
+ X(HK_ECDSA, ssh_ecdsa_nistp256) \
+ X(HK_ECDSA, ssh_ecdsa_nistp384) \
+ X(HK_ECDSA, ssh_ecdsa_nistp521) \
+ X(HK_DSA, ssh_dsa) \
+ X(HK_RSA, ssh_rsa_sha512) \
+ X(HK_RSA, ssh_rsa_sha256) \
+ X(HK_RSA, ssh_rsa) \
+ X(HK_ED25519, opensshcert_ssh_ecdsa_ed25519) \
+ /* OpenSSH defines no certified version of Ed448 */ \
+ X(HK_ECDSA, opensshcert_ssh_ecdsa_nistp256) \
+ X(HK_ECDSA, opensshcert_ssh_ecdsa_nistp384) \
+ X(HK_ECDSA, opensshcert_ssh_ecdsa_nistp521) \
+ X(HK_DSA, opensshcert_ssh_dsa) \
+ X(HK_RSA, opensshcert_ssh_rsa_sha512) \
+ X(HK_RSA, opensshcert_ssh_rsa_sha256) \
+ X(HK_RSA, opensshcert_ssh_rsa) \
+ /* end of list */
+#define COUNT_HOSTKEY_ALGORITHM(type, alg) +1
+#define N_HOSTKEY_ALGORITHMS (0 HOSTKEY_ALGORITHMS(COUNT_HOSTKEY_ALGORITHM))
+
+struct ssh_signkey_with_user_pref_id {
+ const ssh_keyalg *alg;
+ int id;
+};
+extern const struct ssh_signkey_with_user_pref_id
+ ssh2_hostkey_algs[N_HOSTKEY_ALGORITHMS];
+
+/*
+ * Enumeration of high-level classes of reason why we might need to do
+ * a repeat key exchange. A full detailed reason in human-readable
+ * string form for the Event Log is also provided, but this enum type
+ * is used to discriminate between classes of reason that the code
+ * needs to treat differently.
+ *
+ * RK_NONE == 0 is the value indicating that no rekey is currently
+ * needed at all. RK_INITIAL indicates that we haven't even done the
+ * _first_ key exchange yet. RK_SERVER indicates that we're rekeying
+ * because the server asked for it, not because we decided it
+ * ourselves. RK_NORMAL is the usual case. RK_GSS_UPDATE indicates
+ * that we're rekeying because we've just got new GSSAPI credentials
+ * (hence there's no point in doing a preliminary check for new GSS
+ * creds, because we already know the answer); RK_POST_USERAUTH
+ * indicates that _if_ we're going to need a post-userauth immediate
+ * rekey for any reason, this is the moment to do it.
+ *
+ * So RK_POST_USERAUTH only tells the transport layer to _consider_
+ * rekeying, not to definitely do it. Also, that one enum value is
+ * special in that the user-readable reason text is passed in to the
+ * transport layer as NULL, whereas fills in the reason text after it
+ * decides whether it needs a rekey at all. In the other cases,
+ * rekey_reason is passed in to the at the same time as rekey_class.
+ */
+typedef enum RekeyClass {
+ RK_NONE = 0,
+ RK_INITIAL,
+ RK_SERVER,
+ RK_NORMAL,
+ RK_POST_USERAUTH,
+ RK_GSS_UPDATE
+} RekeyClass;
+
+typedef struct transport_direction {
+ const ssh_cipheralg *cipher;
+ const ssh2_macalg *mac;
+ bool etm_mode;
+ const ssh_compression_alg *comp;
+ bool comp_delayed;
+ int mkkey_adjust;
+} transport_direction;
+
+struct ssh2_transport_state {
+ int crState, crStateKex;
+
+ PacketProtocolLayer *higher_layer;
+ PktInQueue pq_in_higher;
+ PktOutQueue pq_out_higher;
+ IdempotentCallback ic_pq_out_higher;
+
+ Conf *conf;
+ char *savedhost;
+ int savedport;
+ const char *rekey_reason;
+ enum RekeyClass rekey_class;
+
+ unsigned long max_data_size;
+
+ const ssh_kex *kex_alg;
+ const ssh_keyalg *hostkey_alg;
+ unsigned char session_id[MAX_HASH_LEN];
+ int session_id_len;
+ int dh_min_size, dh_max_size;
+ bool dh_got_size_bounds;
+ dh_ctx *dh_ctx;
+ ssh_hash *exhash;
+
+ struct DataTransferStats *stats;
+
+ const SshServerConfig *ssc;
+
+ char *client_greeting, *server_greeting;
+
+ bool kex_in_progress, kexinit_delayed;
+ unsigned long next_rekey, last_rekey;
+ const char *deferred_rekey_reason;
+ bool higher_layer_ok;
+
+ /*
+ * Fully qualified host name, which we need if doing GSSAPI.
+ */
+ char *fullhostname;
+
+ /* shgss is outside the ifdef on purpose to keep APIs simple. If
+ * NO_GSSAPI is not defined, then it's just an opaque structure
+ * tag and the pointer will be NULL. */
+ struct ssh_connection_shared_gss_state *shgss;
+#ifndef NO_GSSAPI
+ int gss_status;
+ time_t gss_cred_expiry; /* Re-delegate if newer */
+ unsigned long gss_ctxt_lifetime; /* Re-delegate when short */
+#endif
+ ssh_transient_hostkey_cache *thc;
+
+ bool gss_kex_used;
+
+ tree234 *host_cas;
+
+ int nbits, pbits;
+ bool warn_kex, warn_hk, warn_cscipher, warn_sccipher;
+ mp_int *p, *g, *e, *f;
+ strbuf *ebuf, *fbuf;
+ strbuf *kex_shared_secret;
+ strbuf *outgoing_kexinit, *incoming_kexinit;
+ strbuf *client_kexinit, *server_kexinit; /* aliases to the above */
+ int kex_init_value, kex_reply_value;
+ transport_direction in, out, *cstrans, *sctrans;
+ ptrlen hostkeydata, sigdata;
+ strbuf *hostkeyblob; /* used in server to construct host key to
+ * send to client; in client to check in rekeys */
+ char *keystr;
+ ssh_key *hkey; /* actual host key */
+ unsigned hkflags; /* signing flags, used in server */
+ RSAKey *rsa_kex_key; /* for RSA kex */
+ bool rsa_kex_key_needs_freeing;
+ ecdh_key *ecdh_key; /* for ECDH kex */
+ unsigned char exchange_hash[MAX_HASH_LEN];
+ bool can_gssapi_keyex;
+ bool need_gss_transient_hostkey;
+ bool warned_about_no_gss_transient_hostkey;
+ bool got_session_id;
+ bool can_send_ext_info, post_newkeys_ext_info;
+ SeatPromptResult spr;
+ bool guessok;
+ bool ignorepkt;
+ struct kexinit_algorithm_list kexlists[NKEXLIST];
+#ifndef NO_GSSAPI
+ Ssh_gss_buf gss_buf;
+ Ssh_gss_buf gss_rcvtok, gss_sndtok;
+ Ssh_gss_stat gss_stat;
+ Ssh_gss_buf mic;
+ bool init_token_sent;
+ bool complete_rcvd;
+ bool gss_delegate;
+#endif
+
+ /* List of crypto primitives below the warning threshold that the
+ * user has already clicked OK to, so that we don't keep asking
+ * about them again during rekeys. This directly stores pointers
+ * to the algorithm vtables, compared by pointer value (which is
+ * not a determinism hazard, because we're only using it as a
+ * set). */
+ tree234 *weak_algorithms_consented_to;
+
+ /*
+ * List of host key algorithms for which we _don't_ have a stored
+ * host key. These are indices into the main hostkey_algs[] array
+ */
+ int uncert_hostkeys[N_HOSTKEY_ALGORITHMS];
+ int n_uncert_hostkeys;
+
+ /*
+ * Indicate that the current rekey is intended to finish with a
+ * newly cross-certified host key. To double-check that we
+ * certified the right one, we set this to point to the host key
+ * algorithm we expect it to be.
+ */
+ const ssh_keyalg *cross_certifying;
+
+ ssh_key *const *hostkeys;
+ int nhostkeys;
+
+ PacketProtocolLayer ppl;
+};
+
+/* Helpers shared between transport and kex */
+PktIn *ssh2_transport_pop(struct ssh2_transport_state *s);
+void ssh2_transport_dialog_callback(void *, SeatPromptResult);
+
+/* Provided by transport for use in kex */
+void ssh2transport_finalise_exhash(struct ssh2_transport_state *s);
+
+/* Provided by kex for use in transport. Must set the 'aborted' flag
+ * if it throws a connection-terminating error, so that the caller
+ * won't have to check that by looking inside its state parameter
+ * which might already have been freed. */
+void ssh2kex_coroutine(struct ssh2_transport_state *s, bool *aborted);
+
+#endif /* PUTTY_SSH2TRANSPORT_H */