1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00
putty-source/sshbpp.h

127 lines
4.8 KiB
C
Raw Normal View History

Move binary packet protocols and censoring out of ssh.c. sshbpp.h now defines a classoid that encapsulates both directions of an SSH binary packet protocol - that is, a system for reading a bufchain of incoming data and turning it into a stream of PktIn, and another system for taking a PktOut and turning it into data on an outgoing bufchain. The state structure in each of those files contains everything that used to be in the 'rdpkt2_state' structure and its friends, and also quite a lot of bits and pieces like cipher and MAC states that used to live in the main Ssh structure. One minor effect of this layer separation is that I've had to extend the packet dispatch table by one, because the BPP layer can no longer directly trigger sending of SSH_MSG_UNIMPLEMENTED for a message too short to have a type byte. Instead, I extend the PktIn type field to use an out-of-range value to encode that, and the easiest way to make that trigger an UNIMPLEMENTED message is to have the dispatch table contain an entry for it. (That's a system that may come in useful again - I was also wondering about inventing a fake type code to indicate network EOF, so that that could be propagated through the layers and be handled by whichever one currently knew best how to respond.) I've also moved the packet-censoring code into its own pair of files, partly because I was going to want to do that anyway sooner or later, and mostly because it's called from the BPP code, and the SSH-2 version in particular has to be called from both the main SSH-2 BPP and the bare unencrypted protocol used for connection sharing. While I was at it, I took the opportunity to merge the outgoing and incoming censor functions, so that the parts that were common between them (e.g. CHANNEL_DATA messages look the same in both directions) didn't need to be repeated.
2018-06-09 08:09:10 +00:00
/*
* Abstraction of the binary packet protocols used in SSH.
*/
#ifndef PUTTY_SSHBPP_H
#define PUTTY_SSHBPP_H
struct BinaryPacketProtocolVtable {
void (*free)(BinaryPacketProtocol *);
void (*handle_input)(BinaryPacketProtocol *);
void (*handle_output)(BinaryPacketProtocol *);
Move binary packet protocols and censoring out of ssh.c. sshbpp.h now defines a classoid that encapsulates both directions of an SSH binary packet protocol - that is, a system for reading a bufchain of incoming data and turning it into a stream of PktIn, and another system for taking a PktOut and turning it into data on an outgoing bufchain. The state structure in each of those files contains everything that used to be in the 'rdpkt2_state' structure and its friends, and also quite a lot of bits and pieces like cipher and MAC states that used to live in the main Ssh structure. One minor effect of this layer separation is that I've had to extend the packet dispatch table by one, because the BPP layer can no longer directly trigger sending of SSH_MSG_UNIMPLEMENTED for a message too short to have a type byte. Instead, I extend the PktIn type field to use an out-of-range value to encode that, and the easiest way to make that trigger an UNIMPLEMENTED message is to have the dispatch table contain an entry for it. (That's a system that may come in useful again - I was also wondering about inventing a fake type code to indicate network EOF, so that that could be propagated through the layers and be handled by whichever one currently knew best how to respond.) I've also moved the packet-censoring code into its own pair of files, partly because I was going to want to do that anyway sooner or later, and mostly because it's called from the BPP code, and the SSH-2 version in particular has to be called from both the main SSH-2 BPP and the bare unencrypted protocol used for connection sharing. While I was at it, I took the opportunity to merge the outgoing and incoming censor functions, so that the parts that were common between them (e.g. CHANNEL_DATA messages look the same in both directions) didn't need to be repeated.
2018-06-09 08:09:10 +00:00
PktOut *(*new_pktout)(int type);
void (*queue_disconnect)(BinaryPacketProtocol *,
const char *msg, int category);
Move binary packet protocols and censoring out of ssh.c. sshbpp.h now defines a classoid that encapsulates both directions of an SSH binary packet protocol - that is, a system for reading a bufchain of incoming data and turning it into a stream of PktIn, and another system for taking a PktOut and turning it into data on an outgoing bufchain. The state structure in each of those files contains everything that used to be in the 'rdpkt2_state' structure and its friends, and also quite a lot of bits and pieces like cipher and MAC states that used to live in the main Ssh structure. One minor effect of this layer separation is that I've had to extend the packet dispatch table by one, because the BPP layer can no longer directly trigger sending of SSH_MSG_UNIMPLEMENTED for a message too short to have a type byte. Instead, I extend the PktIn type field to use an out-of-range value to encode that, and the easiest way to make that trigger an UNIMPLEMENTED message is to have the dispatch table contain an entry for it. (That's a system that may come in useful again - I was also wondering about inventing a fake type code to indicate network EOF, so that that could be propagated through the layers and be handled by whichever one currently knew best how to respond.) I've also moved the packet-censoring code into its own pair of files, partly because I was going to want to do that anyway sooner or later, and mostly because it's called from the BPP code, and the SSH-2 version in particular has to be called from both the main SSH-2 BPP and the bare unencrypted protocol used for connection sharing. While I was at it, I took the opportunity to merge the outgoing and incoming censor functions, so that the parts that were common between them (e.g. CHANNEL_DATA messages look the same in both directions) didn't need to be repeated.
2018-06-09 08:09:10 +00:00
};
struct BinaryPacketProtocol {
const struct BinaryPacketProtocolVtable *vt;
bufchain *in_raw, *out_raw;
PktInQueue in_pq;
PktOutQueue out_pq;
Move binary packet protocols and censoring out of ssh.c. sshbpp.h now defines a classoid that encapsulates both directions of an SSH binary packet protocol - that is, a system for reading a bufchain of incoming data and turning it into a stream of PktIn, and another system for taking a PktOut and turning it into data on an outgoing bufchain. The state structure in each of those files contains everything that used to be in the 'rdpkt2_state' structure and its friends, and also quite a lot of bits and pieces like cipher and MAC states that used to live in the main Ssh structure. One minor effect of this layer separation is that I've had to extend the packet dispatch table by one, because the BPP layer can no longer directly trigger sending of SSH_MSG_UNIMPLEMENTED for a message too short to have a type byte. Instead, I extend the PktIn type field to use an out-of-range value to encode that, and the easiest way to make that trigger an UNIMPLEMENTED message is to have the dispatch table contain an entry for it. (That's a system that may come in useful again - I was also wondering about inventing a fake type code to indicate network EOF, so that that could be propagated through the layers and be handled by whichever one currently knew best how to respond.) I've also moved the packet-censoring code into its own pair of files, partly because I was going to want to do that anyway sooner or later, and mostly because it's called from the BPP code, and the SSH-2 version in particular has to be called from both the main SSH-2 BPP and the bare unencrypted protocol used for connection sharing. While I was at it, I took the opportunity to merge the outgoing and incoming censor functions, so that the parts that were common between them (e.g. CHANNEL_DATA messages look the same in both directions) didn't need to be repeated.
2018-06-09 08:09:10 +00:00
PacketLogSettings *pls;
LogContext *logctx;
Ssh ssh;
/* ic_in_raw is filled in by the BPP (probably by calling
* ssh_bpp_common_setup). The BPP's owner triggers it when data is
* added to in_raw, and also when the BPP is newly created. */
IdempotentCallback ic_in_raw;
/* ic_out_pq is entirely internal to the BPP itself; it's used as
* the callback on out_pq. */
IdempotentCallback ic_out_pq;
int remote_bugs;
Move binary packet protocols and censoring out of ssh.c. sshbpp.h now defines a classoid that encapsulates both directions of an SSH binary packet protocol - that is, a system for reading a bufchain of incoming data and turning it into a stream of PktIn, and another system for taking a PktOut and turning it into data on an outgoing bufchain. The state structure in each of those files contains everything that used to be in the 'rdpkt2_state' structure and its friends, and also quite a lot of bits and pieces like cipher and MAC states that used to live in the main Ssh structure. One minor effect of this layer separation is that I've had to extend the packet dispatch table by one, because the BPP layer can no longer directly trigger sending of SSH_MSG_UNIMPLEMENTED for a message too short to have a type byte. Instead, I extend the PktIn type field to use an out-of-range value to encode that, and the easiest way to make that trigger an UNIMPLEMENTED message is to have the dispatch table contain an entry for it. (That's a system that may come in useful again - I was also wondering about inventing a fake type code to indicate network EOF, so that that could be propagated through the layers and be handled by whichever one currently knew best how to respond.) I've also moved the packet-censoring code into its own pair of files, partly because I was going to want to do that anyway sooner or later, and mostly because it's called from the BPP code, and the SSH-2 version in particular has to be called from both the main SSH-2 BPP and the bare unencrypted protocol used for connection sharing. While I was at it, I took the opportunity to merge the outgoing and incoming censor functions, so that the parts that were common between them (e.g. CHANNEL_DATA messages look the same in both directions) didn't need to be repeated.
2018-06-09 08:09:10 +00:00
int seen_disconnect;
char *error;
};
#define ssh_bpp_handle_input(bpp) ((bpp)->vt->handle_input(bpp))
#define ssh_bpp_handle_output(bpp) ((bpp)->vt->handle_output(bpp))
Move binary packet protocols and censoring out of ssh.c. sshbpp.h now defines a classoid that encapsulates both directions of an SSH binary packet protocol - that is, a system for reading a bufchain of incoming data and turning it into a stream of PktIn, and another system for taking a PktOut and turning it into data on an outgoing bufchain. The state structure in each of those files contains everything that used to be in the 'rdpkt2_state' structure and its friends, and also quite a lot of bits and pieces like cipher and MAC states that used to live in the main Ssh structure. One minor effect of this layer separation is that I've had to extend the packet dispatch table by one, because the BPP layer can no longer directly trigger sending of SSH_MSG_UNIMPLEMENTED for a message too short to have a type byte. Instead, I extend the PktIn type field to use an out-of-range value to encode that, and the easiest way to make that trigger an UNIMPLEMENTED message is to have the dispatch table contain an entry for it. (That's a system that may come in useful again - I was also wondering about inventing a fake type code to indicate network EOF, so that that could be propagated through the layers and be handled by whichever one currently knew best how to respond.) I've also moved the packet-censoring code into its own pair of files, partly because I was going to want to do that anyway sooner or later, and mostly because it's called from the BPP code, and the SSH-2 version in particular has to be called from both the main SSH-2 BPP and the bare unencrypted protocol used for connection sharing. While I was at it, I took the opportunity to merge the outgoing and incoming censor functions, so that the parts that were common between them (e.g. CHANNEL_DATA messages look the same in both directions) didn't need to be repeated.
2018-06-09 08:09:10 +00:00
#define ssh_bpp_new_pktout(bpp, type) ((bpp)->vt->new_pktout(type))
#define ssh_bpp_queue_disconnect(bpp, msg, cat) \
((bpp)->vt->queue_disconnect(bpp, msg, cat))
/* ssh_bpp_free is more than just a macro wrapper on the vtable; it
* does centralised parts of the freeing too. */
void ssh_bpp_free(BinaryPacketProtocol *bpp);
Move binary packet protocols and censoring out of ssh.c. sshbpp.h now defines a classoid that encapsulates both directions of an SSH binary packet protocol - that is, a system for reading a bufchain of incoming data and turning it into a stream of PktIn, and another system for taking a PktOut and turning it into data on an outgoing bufchain. The state structure in each of those files contains everything that used to be in the 'rdpkt2_state' structure and its friends, and also quite a lot of bits and pieces like cipher and MAC states that used to live in the main Ssh structure. One minor effect of this layer separation is that I've had to extend the packet dispatch table by one, because the BPP layer can no longer directly trigger sending of SSH_MSG_UNIMPLEMENTED for a message too short to have a type byte. Instead, I extend the PktIn type field to use an out-of-range value to encode that, and the easiest way to make that trigger an UNIMPLEMENTED message is to have the dispatch table contain an entry for it. (That's a system that may come in useful again - I was also wondering about inventing a fake type code to indicate network EOF, so that that could be propagated through the layers and be handled by whichever one currently knew best how to respond.) I've also moved the packet-censoring code into its own pair of files, partly because I was going to want to do that anyway sooner or later, and mostly because it's called from the BPP code, and the SSH-2 version in particular has to be called from both the main SSH-2 BPP and the bare unencrypted protocol used for connection sharing. While I was at it, I took the opportunity to merge the outgoing and incoming censor functions, so that the parts that were common between them (e.g. CHANNEL_DATA messages look the same in both directions) didn't need to be repeated.
2018-06-09 08:09:10 +00:00
BinaryPacketProtocol *ssh1_bpp_new(void);
void ssh1_bpp_new_cipher(BinaryPacketProtocol *bpp,
const struct ssh1_cipheralg *cipher,
Move binary packet protocols and censoring out of ssh.c. sshbpp.h now defines a classoid that encapsulates both directions of an SSH binary packet protocol - that is, a system for reading a bufchain of incoming data and turning it into a stream of PktIn, and another system for taking a PktOut and turning it into data on an outgoing bufchain. The state structure in each of those files contains everything that used to be in the 'rdpkt2_state' structure and its friends, and also quite a lot of bits and pieces like cipher and MAC states that used to live in the main Ssh structure. One minor effect of this layer separation is that I've had to extend the packet dispatch table by one, because the BPP layer can no longer directly trigger sending of SSH_MSG_UNIMPLEMENTED for a message too short to have a type byte. Instead, I extend the PktIn type field to use an out-of-range value to encode that, and the easiest way to make that trigger an UNIMPLEMENTED message is to have the dispatch table contain an entry for it. (That's a system that may come in useful again - I was also wondering about inventing a fake type code to indicate network EOF, so that that could be propagated through the layers and be handled by whichever one currently knew best how to respond.) I've also moved the packet-censoring code into its own pair of files, partly because I was going to want to do that anyway sooner or later, and mostly because it's called from the BPP code, and the SSH-2 version in particular has to be called from both the main SSH-2 BPP and the bare unencrypted protocol used for connection sharing. While I was at it, I took the opportunity to merge the outgoing and incoming censor functions, so that the parts that were common between them (e.g. CHANNEL_DATA messages look the same in both directions) didn't need to be repeated.
2018-06-09 08:09:10 +00:00
const void *session_key);
/* requested_compression() notifies the SSH-1 BPP that we've just sent
* a request to enable compression, which means that on receiving the
* next SSH1_SMSG_SUCCESS or SSH1_SMSG_FAILURE message, it should set
* up zlib compression if it was SUCCESS. */
void ssh1_bpp_requested_compression(BinaryPacketProtocol *bpp);
Move binary packet protocols and censoring out of ssh.c. sshbpp.h now defines a classoid that encapsulates both directions of an SSH binary packet protocol - that is, a system for reading a bufchain of incoming data and turning it into a stream of PktIn, and another system for taking a PktOut and turning it into data on an outgoing bufchain. The state structure in each of those files contains everything that used to be in the 'rdpkt2_state' structure and its friends, and also quite a lot of bits and pieces like cipher and MAC states that used to live in the main Ssh structure. One minor effect of this layer separation is that I've had to extend the packet dispatch table by one, because the BPP layer can no longer directly trigger sending of SSH_MSG_UNIMPLEMENTED for a message too short to have a type byte. Instead, I extend the PktIn type field to use an out-of-range value to encode that, and the easiest way to make that trigger an UNIMPLEMENTED message is to have the dispatch table contain an entry for it. (That's a system that may come in useful again - I was also wondering about inventing a fake type code to indicate network EOF, so that that could be propagated through the layers and be handled by whichever one currently knew best how to respond.) I've also moved the packet-censoring code into its own pair of files, partly because I was going to want to do that anyway sooner or later, and mostly because it's called from the BPP code, and the SSH-2 version in particular has to be called from both the main SSH-2 BPP and the bare unencrypted protocol used for connection sharing. While I was at it, I took the opportunity to merge the outgoing and incoming censor functions, so that the parts that were common between them (e.g. CHANNEL_DATA messages look the same in both directions) didn't need to be repeated.
2018-06-09 08:09:10 +00:00
/* Helper routine which does common BPP initialisation, e.g. setting
* up in_pq and out_pq, and initialising input_consumer. */
void ssh_bpp_common_setup(BinaryPacketProtocol *);
/* Common helper functions between the SSH-2 full and bare BPPs */
void ssh2_bpp_queue_disconnect(BinaryPacketProtocol *bpp,
const char *msg, int category);
int ssh2_bpp_check_unimplemented(BinaryPacketProtocol *bpp, PktIn *pktin);
/*
* Structure that tracks how much data is sent and received, for
* purposes of triggering an SSH-2 rekey when either one gets over a
* configured limit. In each direction, the flag 'running' indicates
* that we haven't hit the limit yet, and 'remaining' tracks how much
* longer until we do. The macro DTS_CONSUME subtracts a given amount
* from the counter in a particular direction, and evaluates to a
* boolean indicating whether the limit has been hit.
*
* The limit is sticky: once 'running' has flipped to false,
* 'remaining' is no longer decremented, so it shouldn't dangerously
* wrap round.
*/
struct DataTransferStats {
struct {
int running;
unsigned long remaining;
} in, out;
};
#define DTS_CONSUME(stats, direction, size) \
((stats)->direction.running && \
(stats)->direction.remaining <= (size) ? \
((stats)->direction.running = FALSE, TRUE) : \
((stats)->direction.remaining -= (size), FALSE))
BinaryPacketProtocol *ssh2_bpp_new(struct DataTransferStats *stats);
Move binary packet protocols and censoring out of ssh.c. sshbpp.h now defines a classoid that encapsulates both directions of an SSH binary packet protocol - that is, a system for reading a bufchain of incoming data and turning it into a stream of PktIn, and another system for taking a PktOut and turning it into data on an outgoing bufchain. The state structure in each of those files contains everything that used to be in the 'rdpkt2_state' structure and its friends, and also quite a lot of bits and pieces like cipher and MAC states that used to live in the main Ssh structure. One minor effect of this layer separation is that I've had to extend the packet dispatch table by one, because the BPP layer can no longer directly trigger sending of SSH_MSG_UNIMPLEMENTED for a message too short to have a type byte. Instead, I extend the PktIn type field to use an out-of-range value to encode that, and the easiest way to make that trigger an UNIMPLEMENTED message is to have the dispatch table contain an entry for it. (That's a system that may come in useful again - I was also wondering about inventing a fake type code to indicate network EOF, so that that could be propagated through the layers and be handled by whichever one currently knew best how to respond.) I've also moved the packet-censoring code into its own pair of files, partly because I was going to want to do that anyway sooner or later, and mostly because it's called from the BPP code, and the SSH-2 version in particular has to be called from both the main SSH-2 BPP and the bare unencrypted protocol used for connection sharing. While I was at it, I took the opportunity to merge the outgoing and incoming censor functions, so that the parts that were common between them (e.g. CHANNEL_DATA messages look the same in both directions) didn't need to be repeated.
2018-06-09 08:09:10 +00:00
void ssh2_bpp_new_outgoing_crypto(
BinaryPacketProtocol *bpp,
const struct ssh2_cipheralg *cipher, const void *ckey, const void *iv,
const struct ssh2_macalg *mac, int etm_mode, const void *mac_key,
const struct ssh_compression_alg *compression);
Move binary packet protocols and censoring out of ssh.c. sshbpp.h now defines a classoid that encapsulates both directions of an SSH binary packet protocol - that is, a system for reading a bufchain of incoming data and turning it into a stream of PktIn, and another system for taking a PktOut and turning it into data on an outgoing bufchain. The state structure in each of those files contains everything that used to be in the 'rdpkt2_state' structure and its friends, and also quite a lot of bits and pieces like cipher and MAC states that used to live in the main Ssh structure. One minor effect of this layer separation is that I've had to extend the packet dispatch table by one, because the BPP layer can no longer directly trigger sending of SSH_MSG_UNIMPLEMENTED for a message too short to have a type byte. Instead, I extend the PktIn type field to use an out-of-range value to encode that, and the easiest way to make that trigger an UNIMPLEMENTED message is to have the dispatch table contain an entry for it. (That's a system that may come in useful again - I was also wondering about inventing a fake type code to indicate network EOF, so that that could be propagated through the layers and be handled by whichever one currently knew best how to respond.) I've also moved the packet-censoring code into its own pair of files, partly because I was going to want to do that anyway sooner or later, and mostly because it's called from the BPP code, and the SSH-2 version in particular has to be called from both the main SSH-2 BPP and the bare unencrypted protocol used for connection sharing. While I was at it, I took the opportunity to merge the outgoing and incoming censor functions, so that the parts that were common between them (e.g. CHANNEL_DATA messages look the same in both directions) didn't need to be repeated.
2018-06-09 08:09:10 +00:00
void ssh2_bpp_new_incoming_crypto(
BinaryPacketProtocol *bpp,
const struct ssh2_cipheralg *cipher, const void *ckey, const void *iv,
const struct ssh2_macalg *mac, int etm_mode, const void *mac_key,
const struct ssh_compression_alg *compression);
Move binary packet protocols and censoring out of ssh.c. sshbpp.h now defines a classoid that encapsulates both directions of an SSH binary packet protocol - that is, a system for reading a bufchain of incoming data and turning it into a stream of PktIn, and another system for taking a PktOut and turning it into data on an outgoing bufchain. The state structure in each of those files contains everything that used to be in the 'rdpkt2_state' structure and its friends, and also quite a lot of bits and pieces like cipher and MAC states that used to live in the main Ssh structure. One minor effect of this layer separation is that I've had to extend the packet dispatch table by one, because the BPP layer can no longer directly trigger sending of SSH_MSG_UNIMPLEMENTED for a message too short to have a type byte. Instead, I extend the PktIn type field to use an out-of-range value to encode that, and the easiest way to make that trigger an UNIMPLEMENTED message is to have the dispatch table contain an entry for it. (That's a system that may come in useful again - I was also wondering about inventing a fake type code to indicate network EOF, so that that could be propagated through the layers and be handled by whichever one currently knew best how to respond.) I've also moved the packet-censoring code into its own pair of files, partly because I was going to want to do that anyway sooner or later, and mostly because it's called from the BPP code, and the SSH-2 version in particular has to be called from both the main SSH-2 BPP and the bare unencrypted protocol used for connection sharing. While I was at it, I took the opportunity to merge the outgoing and incoming censor functions, so that the parts that were common between them (e.g. CHANNEL_DATA messages look the same in both directions) didn't need to be repeated.
2018-06-09 08:09:10 +00:00
BinaryPacketProtocol *ssh2_bare_bpp_new(void);
/*
* The initial code to handle the SSH version exchange is also
* structured as an implementation of BinaryPacketProtocol, because
* that makes it easy to switch from that to the next BPP once it
* tells us which one we're using.
*/
struct ssh_version_receiver {
void (*got_ssh_version)(struct ssh_version_receiver *rcv,
int major_version);
};
BinaryPacketProtocol *ssh_verstring_new(
Conf *conf, Frontend *frontend, int bare_connection_mode,
const char *protoversion, struct ssh_version_receiver *rcv);
const char *ssh_verstring_get_remote(BinaryPacketProtocol *);
const char *ssh_verstring_get_local(BinaryPacketProtocol *);
int ssh_verstring_get_bugs(BinaryPacketProtocol *);
Move binary packet protocols and censoring out of ssh.c. sshbpp.h now defines a classoid that encapsulates both directions of an SSH binary packet protocol - that is, a system for reading a bufchain of incoming data and turning it into a stream of PktIn, and another system for taking a PktOut and turning it into data on an outgoing bufchain. The state structure in each of those files contains everything that used to be in the 'rdpkt2_state' structure and its friends, and also quite a lot of bits and pieces like cipher and MAC states that used to live in the main Ssh structure. One minor effect of this layer separation is that I've had to extend the packet dispatch table by one, because the BPP layer can no longer directly trigger sending of SSH_MSG_UNIMPLEMENTED for a message too short to have a type byte. Instead, I extend the PktIn type field to use an out-of-range value to encode that, and the easiest way to make that trigger an UNIMPLEMENTED message is to have the dispatch table contain an entry for it. (That's a system that may come in useful again - I was also wondering about inventing a fake type code to indicate network EOF, so that that could be propagated through the layers and be handled by whichever one currently knew best how to respond.) I've also moved the packet-censoring code into its own pair of files, partly because I was going to want to do that anyway sooner or later, and mostly because it's called from the BPP code, and the SSH-2 version in particular has to be called from both the main SSH-2 BPP and the bare unencrypted protocol used for connection sharing. While I was at it, I took the opportunity to merge the outgoing and incoming censor functions, so that the parts that were common between them (e.g. CHANNEL_DATA messages look the same in both directions) didn't need to be repeated.
2018-06-09 08:09:10 +00:00
#endif /* PUTTY_SSHBPP_H */