putty/defs.h

187 строки
5.9 KiB
C
Исходник Обычный вид История

/*
* defs.h: initial definitions for PuTTY.
*
* The rule about this header file is that it can't depend on any
* other header file in this code base. This is where we define
* things, as much as we can, that other headers will want to refer
* to, such as opaque structure types and their associated typedefs,
* or macros that are used by other headers.
*/
#ifndef PUTTY_DEFS_H
#define PUTTY_DEFS_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#if defined _MSC_VER && _MSC_VER < 1800
/* Work around lack of inttypes.h in older MSVC */
#define PRIx32 "x"
#define PRIu64 "I64u"
New test system for mp_int and cryptography. I've written a new standalone test program which incorporates all of PuTTY's crypto code, including the mp_int and low-level elliptic curve layers but also going all the way up to the implementations of the MAC, hash, cipher, public key and kex abstractions. The test program itself, 'testcrypt', speaks a simple line-oriented protocol on standard I/O in which you write the name of a function call followed by some inputs, and it gives you back a list of outputs preceded by a line telling you how many there are. Dynamically allocated objects are assigned string ids in the protocol, and there's a 'free' function that tells testcrypt when it can dispose of one. It's possible to speak that protocol by hand, but cumbersome. I've also provided a Python module that wraps it, by running testcrypt as a persistent subprocess and gatewaying all the function calls into things that look reasonably natural to call from Python. The Python module and testcrypt.c both read a carefully formatted header file testcrypt.h which contains the name and signature of every exported function, so it costs minimal effort to expose a given function through this test API. In a few cases it's necessary to write a wrapper in testcrypt.c that makes the function look more friendly, but mostly you don't even need that. (Though that is one of the motivations between a lot of API cleanups I've done recently!) I considered doing Python integration in the more obvious way, by linking parts of the PuTTY code directly into a native-code .so Python module. I decided against it because this way is more flexible: I can run the testcrypt program on its own, or compile it in a way that Python wouldn't play nicely with (I bet compiling just that .so with Leak Sanitiser wouldn't do what you wanted when Python loaded it!), or attach a debugger to it. I can even recompile testcrypt for a different CPU architecture (32- vs 64-bit, or even running it on a different machine over ssh or under emulation) and still layer the nice API on top of that via the local Python interpreter. All I need is a bidirectional data channel.
2019-01-01 22:08:37 +03:00
#define PRIdMAX "I64d"
#define PRIXMAX "I64X"
#define SCNu64 "I64u"
#else
#include <inttypes.h>
#endif
typedef struct conf_tag Conf;
typedef struct terminal_tag Terminal;
typedef struct Filename Filename;
typedef struct FontSpec FontSpec;
typedef struct bufchain_tag bufchain;
typedef struct strbuf strbuf;
typedef struct RSAKey RSAKey;
New centralised binary-data marshalling system. I've finally got tired of all the code throughout PuTTY that repeats the same logic about how to format the SSH binary primitives like uint32, string, mpint. We've got reasonably organised code in ssh.c that appends things like that to 'struct Packet'; something similar in sftp.c which repeats a lot of the work; utility functions in various places to format an mpint to feed to one or another hash function; and no end of totally ad-hoc stuff in functions like public key blob formatters which actually have to _count up_ the size of data painstakingly, then malloc exactly that much and mess about with PUT_32BIT. It's time to bring all of that into one place, and stop repeating myself in error-prone ways everywhere. The new marshal.h defines a system in which I centralise all the actual marshalling functions, and then layer a touch of C macro trickery on top to allow me to (look as if I) pass a wide range of different types to those functions, as long as the target type has been set up in the right way to have a write() function. This commit adds the new header and source file, and sets up some general centralised types (strbuf and the various hash-function contexts like SHA_State), but doesn't use the new calls for anything yet. (I've also renamed some internal functions in import.c which were using the same names that I've just defined macros over. That won't last long - those functions are going to go away soon, so the changed names are strictly temporary.)
2018-05-24 11:17:13 +03:00
typedef struct BinarySink BinarySink;
typedef struct BinarySource BinarySource;
typedef struct stdio_sink stdio_sink;
typedef struct bufchain_sink bufchain_sink;
typedef struct handle_sink handle_sink;
New centralised binary-data marshalling system. I've finally got tired of all the code throughout PuTTY that repeats the same logic about how to format the SSH binary primitives like uint32, string, mpint. We've got reasonably organised code in ssh.c that appends things like that to 'struct Packet'; something similar in sftp.c which repeats a lot of the work; utility functions in various places to format an mpint to feed to one or another hash function; and no end of totally ad-hoc stuff in functions like public key blob formatters which actually have to _count up_ the size of data painstakingly, then malloc exactly that much and mess about with PUT_32BIT. It's time to bring all of that into one place, and stop repeating myself in error-prone ways everywhere. The new marshal.h defines a system in which I centralise all the actual marshalling functions, and then layer a touch of C macro trickery on top to allow me to (look as if I) pass a wide range of different types to those functions, as long as the target type has been set up in the right way to have a write() function. This commit adds the new header and source file, and sets up some general centralised types (strbuf and the various hash-function contexts like SHA_State), but doesn't use the new calls for anything yet. (I've also renamed some internal functions in import.c which were using the same names that I've just defined macros over. That won't last long - those functions are going to go away soon, so the changed names are strictly temporary.)
2018-05-24 11:17:13 +03:00
typedef struct IdempotentCallback IdempotentCallback;
typedef struct SockAddr SockAddr;
typedef struct Socket Socket;
typedef struct Plug Plug;
typedef struct SocketPeerInfo SocketPeerInfo;
typedef struct Backend Backend;
typedef struct BackendVtable BackendVtable;
typedef struct Ldisc_tag Ldisc;
Refactor the LogContext type. LogContext is now the owner of the logevent() function that back ends and so forth are constantly calling. Previously, logevent was owned by the Frontend, which would store the message into its list for the GUI Event Log dialog (or print it to standard error, or whatever) and then pass it _back_ to LogContext to write to the currently open log file. Now it's the other way round: LogContext gets the message from the back end first, writes it to its log file if it feels so inclined, and communicates it back to the front end. This means that lots of parts of the back end system no longer need to have a pointer to a full-on Frontend; the only thing they needed it for was logging, so now they just have a LogContext (which many of them had to have anyway, e.g. for logging SSH packets or session traffic). LogContext itself also doesn't get a full Frontend pointer any more: it now talks back to the front end via a little vtable of its own called LogPolicy, which contains the method that passes Event Log entries through, the old askappend() function that decides whether to truncate a pre-existing log file, and an emergency function for printing an especially prominent message if the log file can't be created. One minor nice effect of this is that console and GUI apps can implement that last function subtly differently, so that Unix console apps can write it with a plain \n instead of the \r\n (harmless but inelegant) that the old centralised implementation generated. One other consequence of this is that the LogContext has to be provided to backend_init() so that it's available to backends from the instant of creation, rather than being provided via a separate API call a couple of function calls later, because backends have typically started doing things that need logging (like making network connections) before the call to backend_provide_logctx. Fortunately, there's no case in the whole code base where we don't already have logctx by the time we make a backend (so I don't actually remember why I ever delayed providing one). So that shortens the backend API by one function, which is always nice. While I'm tidying up, I've also moved the printf-style logeventf() and the handy logevent_and_free() into logging.c, instead of having copies of them scattered around other places. This has also let me remove some stub functions from a couple of outlying applications like Pageant. Finally, I've removed the pointless "_tag" at the end of LogContext's official struct name.
2018-10-10 21:26:18 +03:00
typedef struct LogContext LogContext;
typedef struct LogPolicy LogPolicy;
typedef struct LogPolicyVtable LogPolicyVtable;
New abstraction 'Seat', to pass to backends. This is a new vtable-based abstraction which is passed to a backend in place of Frontend, and it implements only the subset of the Frontend functions needed by a backend. (Many other Frontend functions still exist, notably the wide range of things called by terminal.c providing platform-independent operations on the GUI terminal window.) The purpose of making it a vtable is that this opens up the possibility of creating a backend as an internal implementation detail of some other activity, by providing just that one backend with a custom Seat that implements the methods differently. For example, this refactoring should make it feasible to directly implement an SSH proxy type, aka the 'jump host' feature supported by OpenSSH, aka 'open a secondary SSH session in MAINCHAN_DIRECT_TCP mode, and then expose the main channel of that as the Socket for the primary connection'. (Which of course you can already do by spawning 'plink -nc' as a separate proxy process, but this would permit it in the _same_ process without anything getting confused.) I've centralised a full set of stub methods in misc.c for the new abstraction, which allows me to get rid of several annoying stubs in the previous code. Also, while I'm here, I've moved a lot of duplicated modalfatalbox() type functions from application main program files into wincons.c / uxcons.c, which I think saves duplication overall. (A minor visible effect is that the prefixes on those console-based fatal error messages will now be more consistent between applications.)
2018-10-11 21:58:42 +03:00
typedef struct Seat Seat;
typedef struct SeatVtable SeatVtable;
Remove the 'Frontend' type and replace it with a vtable. After the recent Seat and LogContext revamps, _nearly_ all the remaining uses of the type 'Frontend' were in terminal.c, which needs all sorts of interactions with the GUI window the terminal lives in, from the obvious (actually drawing text on the window, reading and writing the clipboard) to the obscure (minimising, maximising and moving the window in response to particular escape sequences). All of those functions are now provided by an abstraction called TermWin. The few remaining uses of Frontend after _that_ are internal to a particular platform directory, so as to spread the implementation of that particular kind of Frontend between multiple source files; so I've renamed all of those so that they take a more specifically named type that refers to the particular implementation rather than the general abstraction. So now the name 'Frontend' no longer exists in the code base at all, and everywhere one used to be used, it's completely clear whether it was operating in one of Frontend's three abstract roles (and if so, which), or whether it was specific to a particular implementation. Another type that's disappeared is 'Context', which used to be a typedef defined to something different on each platform, describing whatever short-lived resources were necessary to draw on the terminal window: the front end would provide a ready-made one when calling term_paint, and the terminal could request one with get_ctx/free_ctx if it wanted to do proactive window updates. Now that drawing context lives inside the TermWin itself, because there was never any need to have two of those contexts live at the same time. (Another minor API change is that the window-title functions - both reading and writing - have had a missing 'const' added to their char * parameters / return values.) I don't expect this change to enable any particularly interesting new functionality (in particular, I have no plans that need more than one implementation of TermWin in the same application). But it completes the tidying-up that began with the Seat and LogContext rework.
2018-10-25 20:44:04 +03:00
typedef struct TermWin TermWin;
typedef struct TermWinVtable TermWinVtable;
typedef struct Ssh Ssh;
Complete rewrite of PuTTY's bignum library. The old 'Bignum' data type is gone completely, and so is sshbn.c. In its place is a new thing called 'mp_int', handled by an entirely new library module mpint.c, with API differences both large and small. The main aim of this change is that the new library should be free of timing- and cache-related side channels. I've written the code so that it _should_ - assuming I haven't made any mistakes - do all of its work without either control flow or memory addressing depending on the data words of the input numbers. (Though, being an _arbitrary_ precision library, it does have to at least depend on the sizes of the numbers - but there's a 'formal' size that can vary separately from the actual magnitude of the represented integer, so if you want to keep it secret that your number is actually small, it should work fine to have a very long mp_int and just happen to store 23 in it.) So I've done all my conditionalisation by means of computing both answers and doing bit-masking to swap the right one into place, and all loops over the words of an mp_int go up to the formal size rather than the actual size. I haven't actually tested the constant-time property in any rigorous way yet (I'm still considering the best way to do it). But this code is surely at the very least a big improvement on the old version, even if I later find a few more things to fix. I've also completely rewritten the low-level elliptic curve arithmetic from sshecc.c; the new ecc.c is closer to being an adjunct of mpint.c than it is to the SSH end of the code. The new elliptic curve code keeps all coordinates in Montgomery-multiplication transformed form to speed up all the multiplications mod the same prime, and only converts them back when you ask for the affine coordinates. Also, I adopted extended coordinates for the Edwards curve implementation. sshecc.c has also had a near-total rewrite in the course of switching it over to the new system. While I was there, I've separated ECDSA and EdDSA more completely - they now have separate vtables, instead of a single vtable in which nearly every function had a big if statement in it - and also made the externally exposed types for an ECDSA key and an ECDH context different. A minor new feature: since the new arithmetic code includes a modular square root function, we can now support the compressed point representation for the NIST curves. We seem to have been getting along fine without that so far, but it seemed a shame not to put it in, since it was suddenly easy. In sshrsa.c, one major change is that I've removed the RSA blinding step in rsa_privkey_op, in which we randomise the ciphertext before doing the decryption. The purpose of that was to avoid timing leaks giving away the plaintext - but the new arithmetic code should take that in its stride in the course of also being careful enough to avoid leaking the _private key_, which RSA blinding had no way to do anything about in any case. Apart from those specific points, most of the rest of the changes are more or less mechanical, just changing type names and translating code into the new API.
2018-12-31 16:53:41 +03:00
typedef struct mp_int mp_int;
typedef struct MontyContext MontyContext;
typedef struct WeierstrassCurve WeierstrassCurve;
typedef struct WeierstrassPoint WeierstrassPoint;
typedef struct MontgomeryCurve MontgomeryCurve;
typedef struct MontgomeryPoint MontgomeryPoint;
typedef struct EdwardsCurve EdwardsCurve;
typedef struct EdwardsPoint EdwardsPoint;
Add an SFTP server to the SSH server code. Unlike the traditional Unix SSH server organisation, the SFTP server is built into the same process as all the rest of the code. sesschan.c spots a subsystem request for "sftp", and responds to it by instantiating an SftpServer object and swapping out its own vtable for one that talks to it. (I rather like the idea of an object swapping its own vtable for a different one in the middle of its lifetime! This is one of those tricks that would be absurdly hard to implement in a 'proper' OO language, but when you're doing vtables by hand in C, it's no more difficult than any other piece of ordinary pointer manipulation. As long as the methods in both vtables expect the same physical structure layout, it doesn't cause a problem.) The SftpServer object doesn't deal directly with SFTP packet formats; it implements the SFTP server logic in a more abstract way, by having a vtable method for each SFTP request type with an appropriate parameter list. It sends its replies by calling methods in another vtable called SftpReplyBuilder, which in the normal case will write an SFTP reply packet to send back to the client. So SftpServer can focus more or less completely on the details of a particular filesystem API - and hence, the implementation I've got lives in the unix source directory, and works directly with file descriptors and struct stat and the like. (One purpose of this abstraction layer is that I may well want to write a second dummy implementation, for test-suite purposes, with completely controllable behaviour, and now I have a handy place to plug it in in place of the live filesystem.) In between sesschan's parsing of the byte stream into SFTP packets and the SftpServer object, there's a layer in the new file sftpserver.c which does the actual packet decoding and encoding: each request packet is passed to that, which pulls the fields out of the request packet and calls the appropriate method of SftpServer. It also provides the default SftpReplyBuilder which makes the output packet. I've moved some code out of the previous SFTP client implementation - basic packet construction code, and in particular the BinarySink/ BinarySource marshalling fuinction for fxp_attrs - into sftpcommon.c, so that the two directions can share as much as possible.
2018-10-21 00:10:32 +03:00
typedef struct SftpServer SftpServer;
typedef struct SftpServerVtable SftpServerVtable;
typedef struct Channel Channel;
typedef struct SshChannel SshChannel;
typedef struct mainchan mainchan;
typedef struct ssh_sharing_state ssh_sharing_state;
typedef struct ssh_sharing_connstate ssh_sharing_connstate;
typedef struct share_channel share_channel;
typedef struct PortFwdManager PortFwdManager;
typedef struct PortFwdRecord PortFwdRecord;
typedef struct ConnectionLayer ConnectionLayer;
Replace PuTTY's PRNG with a Fortuna-like system. This tears out the entire previous random-pool system in sshrand.c. In its place is a system pretty close to Ferguson and Schneier's 'Fortuna' generator, with the main difference being that I use SHA-256 instead of AES for the generation side of the system (rationale given in comment). The PRNG implementation lives in sshprng.c, and defines a self- contained data type with no state stored outside the object, so you can instantiate however many of them you like. The old sshrand.c still exists, but in place of the previous random pool system, it's just become a client of sshprng.c, whose job is to hold a single global instance of the PRNG type, and manage its reference count, save file, noise-collection timers and similar administrative business. Advantages of this change include: - Fortuna is designed with a more varied threat model in mind than my old home-grown random pool. For example, after any request for random numbers, it automatically re-seeds itself, so that if the state of the PRNG should be leaked, it won't give enough information to find out what past outputs _were_. - The PRNG type can be instantiated with any hash function; the instance used by the main tools is based on SHA-256, an improvement on the old pool's use of SHA-1. - The new PRNG only uses the completely standard interface to the hash function API, instead of having to have privileged access to the internal SHA-1 block transform function. This will make it easier to revamp the hash code in general, and also it means that hardware-accelerated versions of SHA-256 will automatically be used for the PRNG as well as for everything else. - The new PRNG can be _tested_! Because it has an actual (if not quite explicit) specification for exactly what the output numbers _ought_ to be derived from the hashes of, I can (and have) put tests in cryptsuite that ensure the output really is being derived in the way I think it is. The old pool could have been returning any old nonsense and it would have been very hard to tell for sure.
2019-01-23 01:42:41 +03:00
typedef struct prng prng;
typedef struct ssh_hashalg ssh_hashalg;
typedef struct ssh_hash ssh_hash;
typedef struct ssh_kex ssh_kex;
typedef struct ssh_kexes ssh_kexes;
typedef struct ssh_keyalg ssh_keyalg;
typedef struct ssh_key ssh_key;
typedef struct ssh_compressor ssh_compressor;
typedef struct ssh_decompressor ssh_decompressor;
typedef struct ssh_compression_alg ssh_compression_alg;
typedef struct ssh2_userkey ssh2_userkey;
typedef struct ssh2_macalg ssh2_macalg;
typedef struct ssh2_mac ssh2_mac;
Merge the ssh1_cipher type into ssh2_cipher. The aim of this reorganisation is to make it easier to test all the ciphers in PuTTY in a uniform way. It was inconvenient that there were two separate vtable systems for the ciphers used in SSH-1 and SSH-2 with different functionality. Now there's only one type, called ssh_cipher. But really it's the old ssh2_cipher, just renamed: I haven't made any changes to the API on the SSH-2 side. Instead, I've removed ssh1_cipher completely, and adapted the SSH-1 BPP to use the SSH-2 style API. (The relevant differences are that ssh1_cipher encapsulated both the sending and receiving directions in one object - so now ssh1bpp has to make a separate cipher instance per direction - and that ssh1_cipher automatically initialised the IV to all zeroes, which ssh1bpp now has to do by hand.) The previous ssh1_cipher vtable for single-DES has been removed completely, because when converted into the new API it became identical to the SSH-2 single-DES vtable; so now there's just one vtable for DES-CBC which works in both protocols. The other two SSH-1 ciphers each had to stay separate, because 3DES is completely different between SSH-1 and SSH-2 (three layers of CBC structure versus one), and Blowfish varies in endianness and key length between the two. (Actually, while I'm here, I've only just noticed that the SSH-1 Blowfish cipher mis-describes itself in log messages as Blowfish-128. In fact it passes the whole of the input key buffer, which has length SSH1_SESSION_KEY_LENGTH == 32 bytes == 256 bits. So it's actually Blowfish-256, and has been all along!)
2019-01-17 21:06:08 +03:00
typedef struct ssh_cipheralg ssh_cipheralg;
typedef struct ssh_cipher ssh_cipher;
typedef struct ssh2_ciphers ssh2_ciphers;
typedef struct dh_ctx dh_ctx;
typedef struct ecdh_key ecdh_key;
typedef struct dlgparam dlgparam;
typedef struct settings_w settings_w;
typedef struct settings_r settings_r;
typedef struct settings_e settings_e;
typedef struct SessionSpecial SessionSpecial;
New utility object, StripCtrlChars. This is for sanitising output that's going to be sent to a terminal, if you don't want it to be able to send arbitrary escape sequences and thereby (for example) move the cursor back up to existing text on the screen and overprint it confusingly. It works using the standard C library: we convert to a wide-character string and back, and then use wctype.h to spot control characters in the intermediate form. This means its idea of the conversion character set is locale-based rather than any of our own charset library's fixed settings - which is what you want if the aim is to protect your local terminal (which we assume the system locale represents accurately). This also means that the sanitiser strips things that will _act_ as control characters when sent to the local terminal, whether or not they were intended as control characters by a server that might have had a different character set in mind. Since the main aim is to protect the local terminal rather than to faithfully replicate the server's intention, I think that's the right criterion. It only strips control characters at the charset-independent layer, like backspace, carriage return and the escape character: wctype.h classifies those as control characters, but classifies as printing all of the more Unicode-specific controls like bidirectional overrides. But that's enough to prevent cursor repositioning, for example. stripctrl.c comes with a test main() of its own, which I wasn't able to fold into testcrypt and put in the test suite because of its dependence on the system locale - it wouldn't be guaranteed to work the same way on different test systems anyway. A knock-on build tweak: because you can feed data into this sanitiser in chunks of arbitrary size, including partial multibyte chars, I had to use mbrtowc() for the decoding, and that means that in the 'old' Win32 builds I have to link against the Visual Studio C++ library as well as the C library, because for some reason that's where mbrtowc lived in VS2003.
2019-02-20 09:56:40 +03:00
typedef struct StripCtrlChars StripCtrlChars;
/*
* A small structure wrapping up a (pointer, length) pair so that it
* can be conveniently passed to or from a function.
*/
typedef struct ptrlen {
const void *ptr;
size_t len;
} ptrlen;
typedef struct logblank_t logblank_t;
typedef struct BinaryPacketProtocol BinaryPacketProtocol;
Move most of ssh.c out into separate source files. I've tried to separate out as many individually coherent changes from this work as I could into their own commits, but here's where I run out and have to commit the rest of this major refactoring as a big-bang change. Most of ssh.c is now no longer in ssh.c: all five of the main coroutines that handle layers of the SSH-1 and SSH-2 protocols now each have their own source file to live in, and a lot of the supporting functions have moved into the appropriate one of those too. The new abstraction is a vtable called 'PacketProtocolLayer', which has an input and output packet queue. Each layer's main coroutine is invoked from the method ssh_ppl_process_queue(), which is usually (though not exclusively) triggered automatically when things are pushed on the input queue. In SSH-2, the base layer is the transport protocol, and it contains a pair of subsidiary queues by which it passes some of its packets to the higher SSH-2 layers - first userauth and then connection, which are peers at the same level, with the former abdicating in favour of the latter at the appropriate moment. SSH-1 is simpler: the whole login phase of the protocol (crypto setup and authentication) is all in one module, and since SSH-1 has no repeat key exchange, that setup layer abdicates in favour of the connection phase when it's done. ssh.c itself is now about a tenth of its old size (which all by itself is cause for celebration!). Its main job is to set up all the layers, hook them up to each other and to the BPP, and to funnel data back and forth between that collection of modules and external things such as the network and the terminal. Once it's set up a collection of packet protocol layers, it communicates with them partly by calling methods of the base layer (and if that's ssh2transport then it will delegate some functionality to the corresponding methods of its higher layer), and partly by talking directly to the connection layer no matter where it is in the stack by means of the separate ConnectionLayer vtable which I introduced in commit 8001dd4cb, and to which I've now added quite a few extra methods replacing services that used to be internal function calls within ssh.c. (One effect of this is that the SSH-1 and SSH-2 channel storage is now no longer shared - there are distinct struct types ssh1_channel and ssh2_channel. That means a bit more code duplication, but on the plus side, a lot fewer confusing conditionals in the middle of half-shared functions, and less risk of a piece of SSH-1 escaping into SSH-2 or vice versa, which I remember has happened at least once in the past.) The bulk of this commit introduces the five new source files, their common header sshppl.h and some shared supporting routines in sshcommon.c, and rewrites nearly all of ssh.c itself. But it also includes a couple of other changes that I couldn't separate easily enough: Firstly, there's a new handling for socket EOF, in which ssh.c sets an 'input_eof' flag in the BPP, and that responds by checking a flag that tells it whether to report the EOF as an error or not. (This is the main reason for those new BPP_READ / BPP_WAITFOR macros - they can check the EOF flag every time the coroutine is resumed.) Secondly, the error reporting itself is changed around again. I'd expected to put some data fields in the public PacketProtocolLayer structure that it could set to report errors in the same way as the BPPs have been doing, but in the end, I decided propagating all those data fields around was a pain and that even the BPPs shouldn't have been doing it that way. So I've reverted to a system where everything calls back to functions in ssh.c itself to report any connection- ending condition. But there's a new family of those functions, categorising the possible such conditions by semantics, and each one has a different set of detailed effects (e.g. how rudely to close the network connection, what exit status should be passed back to the whole application, whether to send a disconnect message and/or display a GUI error box). I don't expect this to be immediately perfect: of course, the code has been through a big upheaval, new bugs are expected, and I haven't been able to do a full job of testing (e.g. I haven't tested every auth or kex method). But I've checked that it _basically_ works - both SSH protocols, all the different kinds of forwarding channel, more than one auth method, Windows and Linux, connection sharing - and I think it's now at the point where the easiest way to find further bugs is to let it out into the wild and see what users can spot.
2018-09-24 20:28:16 +03:00
typedef struct PacketProtocolLayer PacketProtocolLayer;
/* Do a compile-time type-check of 'to_check' (without evaluating it),
* as a side effect of returning the value 'to_return'. Note that
* although this macro double-*expands* to_return, it always
* *evaluates* exactly one copy of it, so it's side-effect safe. */
#define TYPECHECK(to_check, to_return) \
(sizeof(to_check) ? (to_return) : (to_return))
/* Return a pointer to the object of structure type 'type' whose field
* with name 'field' is pointed at by 'object'. */
#define container_of(object, type, field) \
TYPECHECK(object == &((type *)0)->field, \
((type *)(((char *)(object)) - offsetof(type, field))))
#if defined __GNUC__ || defined __clang__
#define NORETURN __attribute__((__noreturn__))
#else
#define NORETURN
#endif
/* ----------------------------------------------------------------------
* Platform-specific definitions.
*
* Most of these live in the per-platform header files, of which
* puttyps.h selects the appropriate one. But some of the sources
* (particularly standalone test applications) would prefer not to
* have to include a per-platform header at all, because that makes it
* more portable to platforms not supported by the code base as a
* whole (for example, compiling purely computational parts of the
* code for specialist platforms for test and analysis purposes). So
* any definition that has to affect even _those_ modules will have to
* go here, with the key constraint being that this code has to come
* to _some_ decision even if the compilation platform is not a
* recognised one at all.
*/
/* Purely computational code uses smemclr(), so we have to make the
* decision here about whether that's provided by utils.c or by a
* platform implementation. We define PLATFORM_HAS_SMEMCLR to suppress
* utils.c's definition. */
#ifdef _WINDOWS
/* Windows provides the API function 'SecureZeroMemory', which we use
* unless the user has told us not to by defining NO_SECUREZEROMEMORY. */
#ifndef NO_SECUREZEROMEMORY
#define PLATFORM_HAS_SMEMCLR
#endif
#endif
#endif /* PUTTY_DEFS_H */