sk_startup and sk_nextaddr are entirely internal to winnet.c; nearly
all of import.c and minibidi.c's internal routines should have been
static and weren't; {read,write}_utf8 are internal to charset/utf8.c
(and didn't even need separate declarations at all); do_sftp_cleanup
is internal to psftp.c, and get_listitemheight to gtkdlg.c.
While I was editing those prototypes anyway, I've also added missing
'const' to the 'char *' passphrase parameters in import,c.
For a start, they now have different names on Windows and Unix,
reflecting their different roles: on Windows they apply escaping to
any string that's going to be used as a registry key (be it a session
name, or a host name for host key storage), whereas on Unix they're
for constructing saved-session file names in particular (and also
handle the special case of filling in "Default Settings" for NULL).
Also, they now produce output by writing to a strbuf, which simplifies
a lot of the call sites. In particular, the strbuf output idiom is
passed on to enum_settings_next, which is especially nice because its
only actual caller was doing an ad-hoc realloc loop that I can now get
rid of completely.
Thirdly, on Windows they're centralised into winmisc.c instead of
living in winstore.c, because that way Pageant can use the unescape
function too. (It was spotting the duplication there that made me
think of doing this in the first place, but once I'd started, I had to
keep unravelling the thread...)
There's one of these centralised in win_strerror() in winmisc.c, and
it doesn't seem worth keeping an earlier iteration of the same idea
entirely separate in winsock_error_string.
This removal means that non-network-specific error codes received in a
network context will no longer have "Network error:" prefixed to them.
But I think that's OK, because it seems unlikely to be critically
important that such an error was received from a network function - if
anything like that comes up then it's probably some kind of systemwide
chaos.
Jumped out at me in my trawl of the whole code base:
set_explicit_app_user_model_id is declared and defined as () rather
than (void), but this isn't C++.
I came across this unexplained static variable in my boolification
trawl. It seems clearly unintentional that it has only one instance
instead of one per terminal window - the code in question closely
resembles the Windows front end, and I think this must just be a
variable that I never swept up into 'inst' in the very early days when
I was making gtkwin.c out of a cloned-and-hacked window.c in the first
place.
These days it's even a bug, now that the OS X port actually does run
multiple terminal windows in the same process: if one goes into mouse
reporting mode, I'm pretty sure this would have done confusing things
to the effects of mouse actions in the other.
Notably toint(), which ought to compile down to the identity function
in any case so you don't really want to put in a pointless call
overhead, and make_ptrlen() (and a couple of its wrappers) which is
standing in for what ought to be a struct-literal syntax.
My normal habit these days, in new code, is to treat int and bool as
_almost_ completely separate types. I'm still willing to use C's
implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine,
no need to spell it out as blob.len != 0), but generally, if a
variable is going to be conceptually a boolean, I like to declare it
bool and assign to it using 'true' or 'false' rather than 0 or 1.
PuTTY is an exception, because it predates the C99 bool, and I've
stuck to its existing coding style even when adding new code to it.
But it's been annoying me more and more, so now that I've decided C99
bool is an acceptable thing to require from our toolchain in the first
place, here's a quite thorough trawl through the source doing
'boolification'. Many variables and function parameters are now typed
as bool rather than int; many assignments of 0 or 1 to those variables
are now spelled 'true' or 'false'.
I managed this thorough conversion with the help of a custom clang
plugin that I wrote to trawl the AST and apply heuristics to point out
where things might want changing. So I've even managed to do a decent
job on parts of the code I haven't looked at in years!
To make the plugin's work easier, I pushed platform front ends
generally in the direction of using standard 'bool' in preference to
platform-specific boolean types like Windows BOOL or GTK's gboolean;
I've left the platform booleans in places they _have_ to be for the
platform APIs to work right, but variables only used by my own code
have been converted wherever I found them.
In a few places there are int values that look very like booleans in
_most_ of the places they're used, but have a rarely-used third value,
or a distinction between different nonzero values that most users
don't care about. In these cases, I've _removed_ uses of 'true' and
'false' for the return values, to emphasise that there's something
more subtle going on than a simple boolean answer:
- the 'multisel' field in dialog.h's list box structure, for which
the GTK front end in particular recognises a difference between 1
and 2 but nearly everything else treats as boolean
- the 'urgent' parameter to plug_receive, where 1 vs 2 tells you
something about the specific location of the urgent pointer, but
most clients only care about 0 vs 'something nonzero'
- the return value of wc_match, where -1 indicates a syntax error in
the wildcard.
- the return values from SSH-1 RSA-key loading functions, which use
-1 for 'wrong passphrase' and 0 for all other failures (so any
caller which already knows it's not loading an _encrypted private_
key can treat them as boolean)
- term->esc_query, and the 'query' parameter in toggle_mode in
terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h,
but can also hold -1 for some other intervening character that we
don't support.
In a few places there's an integer that I haven't turned into a bool
even though it really _can_ only take values 0 or 1 (and, as above,
tried to make the call sites consistent in not calling those values
true and false), on the grounds that I thought it would make it more
confusing to imply that the 0 value was in some sense 'negative' or
bad and the 1 positive or good:
- the return value of plug_accepting uses the POSIXish convention of
0=success and nonzero=error; I think if I made it bool then I'd
also want to reverse its sense, and that's a job for a separate
piece of work.
- the 'screen' parameter to lineptr() in terminal.c, where 0 and 1
represent the default and alternate screens. There's no obvious
reason why one of those should be considered 'true' or 'positive'
or 'success' - they're just indices - so I've left it as int.
ssh_scp_recv had particularly confusing semantics for its previous int
return value: its call sites used '<= 0' to check for error, but it
never actually returned a negative number, just 0 or 1. Now the
function and its call sites agree that it's a bool.
In a couple of places I've renamed variables called 'ret', because I
don't like that name any more - it's unclear whether it means the
return value (in preparation) for the _containing_ function or the
return value received from a subroutine call, and occasionally I've
accidentally used the same variable for both and introduced a bug. So
where one of those got in my way, I've renamed it to 'toret' or 'retd'
(the latter short for 'returned') in line with my usual modern
practice, but I haven't done a thorough job of finding all of them.
Finally, one amusing side effect of doing this is that I've had to
separate quite a few chained assignments. It used to be perfectly fine
to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a
the 'true' defined by stdbool.h, that idiom provokes a warning from
gcc: 'suggest parentheses around assignment used as truth value'!
I think this is the full set of things that ought logically to be
boolean.
One annoyance is that quite a few radio-button controls in config.c
address Conf fields that are now bool rather than int, which means
that the shared handler function can't just access them all with
conf_{get,set}_int. Rather than back out the rigorous separation of
int and bool in conf.c itself, I've just added a similar alternative
handler function for the bool-typed ones.
It's not actually used anywhere yet, though. This is just adding the
accessor functions, which will enforce a rigorous separation between
conf keys typed as int and as bool.
This commit includes <stdbool.h> from defs.h and deletes my
traditional definitions of TRUE and FALSE, but other than that, it's a
100% mechanical search-and-replace transforming all uses of TRUE and
FALSE into the C99-standardised lowercase spellings.
No actual types are changed in this commit; that will come next. This
is just getting the noise out of the way, so that subsequent commits
can have a higher proportion of signal.
The annoying int64.h is completely retired, since C99 guarantees a
64-bit integer type that you can actually treat like an ordinary
integer. Also, I've replaced the local typedefs uint32 and word32
(scattered through different parts of the crypto code) with the
standard uint32_t.
If values are boolean, it's confusing to use & and | in place of &&
and ||. In two of these three cases it was simply a typo and I've used
the other one; in the third, it was a deliberate avoidance of short-
circuit evaluation (and commented as such), but having seen how easy
it is to make the same typo by accident, I've decided it's clearer to
just move the LHS and RHS evaluations outside the expression.
In some compiler modes - notably the one that gtk-config selects when
GTK PuTTY is built for GTK 1 - it's an error to typedef the same thing
twice. 'mainchan' is defined in defs.h, so it doesn't need defining
again where the structure contents are specified.
x11_char_struct returns a pointer or NULL, so while returning FALSE
would have ended up doing the right thing after macro expansion and
integer->pointer conversion, it wasn't actually how I _meant_ to spell
a failure return.
In GTK 2, this function was a new and convenient way to override the
order in which the Tab key cycled through the sub-widgets of a
container, replacing the more verbose mechanism in GTK 1 where you had
to provide a custom implementation of the "focus" method in
GtkContainerClass.
GTK 3.24 has now deprecated gtk_container_set_focus_chain(),
apparently on the grounds that that old system is what they think you
_ought_ to be doing. So I've abandoned set_focus_chain completely, and
switched back to doing it by a custom focus method for _all_ versions
of GTK, with the only slight wrinkle being that between GTK 1 and 2
the method in question moved from GtkContainer to GtkWidget (my guess
is so that an individual non-container widget can still have multiple
separately focusable UI components).
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.
In the very old days, when PuTTY was new and computers were slow, I
tried to implement a feature where scrolling the window would be
implemented using a fast rectangle-copy GDI operation, rather than an
expensive character-by-character redraw of all the changed areas.
It never quite worked right, and I ended up conditioning it out on
Windows, and never even tried to implement it on GTK. It's now been
sitting around unused for so long that I think it's no longer worth
keeping in the code at all - if I tried to put it back in, it surely
wouldn't even compile, and would need rewriting from scratch anyway.
Disturbingly, it looks as if I _tried_ to re-enable it at one point,
in that there was a '#define OPTIMISE_IS_SCROLL 1' in putty.h - but
that never had any effect, because the macro name is misspelled. All
the #ifdefs are for 'OPTIMISE_SCROLL', without the 'IS'. So despite
appearances, it really _has_ been conditioned out all along!
Colin Harrison points out that commit c31e3cd43 was less cautious than
it should have been: when delete_callbacks_for_context nulls out the
'next' pointer in the new tail element of the callbacks list, it
should only do so if there _is_ a new tail element. If the list has
just become empty, that won't work very well!
A function containing assert(FALSE && "Should never be called")
doesn't _really_ need to return a value, but it makes compilers
happier if it pretends to.
Like the SFTP server, this is implemented in-process rather than by
invoking a separate scp server binary.
It also uses the internal SftpServer abstraction for access to the
server's filesystem, which means that when (or if) I implement an
alternative SftpServer implementing a dummy file system for test suite
purposes, this scp server should automatically start using it too.
As a bonus, the new scpserver.c contains a large comment documenting
my understanding of the SCP protocol, which I previously didn't have
even a de-facto or post-hoc spec for. I don't claim it's authoritative
- it's all reverse-engineered from my own code and observing other
implementations in action - but at least it'll make it easier to
refresh my own memory of what's going on the next time I need to do
something to either this code or PSCP.
When you don't specify -r, we now check whether the server is sending
a whole subdirectory in place of a single file, and abort if it does.
Previously we'd accept the subdirectory download regardless.
The new error message labels this as a security violation, just on the
grounds that it involves the server doing something other than what
the implicit contract suggested it ought to, but I don't think it's a
really serious violation in the same sense as letting the server cd
into ".." or overwrite files of arbitrary name would be. In this case
it can only leave a downloaded thing in the specific place you already
authorised it to put _some_ downloaded thing - it's just returned you
a directory in place of a file.
throttled_by_backlog is quite new, so it's not too surprising that I
hadn't already noticed it wasn't initialised. But the failure to null
out the final 'next' pointer in the callbacks list when it's rewritten
as a result of delete_callbacks_for_context is a great deal older, so
I'm a lot more puzzled about how it hasn't come up until now!
The main wildcard matching code now doesn't depend on having a NUL
terminator in the string to be matched; instead it works with a pair
of pointers, one working along the string as we match, and the other
identifying the end of the string, and tests that p < target_end
before dereferencing p. User-facing entry points now allow you to pass
either an ordinary ASCIZ const char * or a ptrlen, and set up
target_end accordingly.
For the moment, the _wildcard_ parameter still has to be an ordinary
null-terminated string, but who knows, maybe that will have to change
too at some later point.
Firstly, these protocols had a display heuristic - credited to OpenSSH
in the comments - in which, if the challenge string contained a
newline, it was supposed to be printed with "Response: " on the next
line, whereas if it didn't, it would be taken as a prompt in its own
right. In fact, I had got the sense of memchr backwards, so each
behaviour was applying in the opposite case.
Secondly, apparently I'd never before tested against a server that
offered _both_ those methods, because when I tried it against Uppity
just now, I found that the setup and challenge phases for both methods
ran in immediate succession before prompting the user, which confused
the server completely. This is exactly why I wanted to have a server
implementation of everything PuTTY is supposed to speak the client
side of!
This adds the server side of the SSH-2 keyboard-interactive protocol,
and the pair of very similar SSH-1 methods AUTH_TIS and AUTH_CCARD
(which basically differ only in message numbers, and each involve a
single challenge from the server and a response from the user).
We now show the --help output if invoked with no arguments, and the
help text also includes a big safety warning in the hope of stopping
anyone from mistaking this for a _secure_ SSH server implementation.
While I'm here, the errors now all use appname[] in place of
constantly repeating the program name. (Not because I anticipate a
change right now, but if nothing else, it makes things easier moving
errors out into shared source files or between applications.)
Naturally, there's one really glaring goof I find out instants after
'git push'! If Pageant starts a watchdog subprocess which will wait
until the main process terminates and then clean up the socket, then
it had better not have that subprocess keep the standard I/O handles
open, or else commands like eval $(pageant -X) won't terminate.
I've applied the same fix in the X11 socket creation, though I think
it's less critical there.
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.
This server is NOT SECURE! If anyone is reading this commit message,
DO NOT DEPLOY IT IN A HOSTILE-FACING ENVIRONMENT! Its purpose is to
speak the server end of everything PuTTY speaks on the client side, so
that I can test that I haven't broken PuTTY when I reorganise its
code, even things like RSA key exchange or chained auth methods which
it's hard to find a server that speaks at all.
(For this reason, it's declared with [UT] in the Recipe file, so that
it falls into the same category as programs like testbn, which won't
be installed by 'make install'.)
Working title is 'Uppity', partly for 'Universal PuTTY Protocol
Interaction Test Yoke', but mostly because it looks quite like the
word 'PuTTY' with part of it reversed. (Apparently 'test yoke' is a
very rarely used term meaning something not altogether unlike 'test
harness', which is a bit of a stretch, but it'll do.)
It doesn't actually _support_ everything I want yet. At the moment,
it's a proof of concept only. But it has most of the machinery
present, and the parts it's missing - such as chained auth methods -
should be easy enough to add because I've built in the required
flexibility, in the form of an AuthPolicy object which can request
them if it wants to. However, the current AuthPolicy object is
entirely trivial, and will let in any user with the password "weasel".
(Another way in which this is not a production-ready server is that it
also has no interaction with the OS's authentication system. In
particular, it will not only let in any user with the same password,
but it won't even change uid - it will open shells and forwardings
under whatever user id you started it up as.)
Currently, the program can only speak the SSH protocol on its standard
I/O channels (using the new FdSocket facility), so if you want it to
listen on a network port, you'll have to run it from some kind of
separate listening program similar to inetd. For my own tests, I'm not
even doing that: I'm just having PuTTY spawn it as a local proxy
process, which also conveniently eliminates the risk of anyone hostile
connecting to it.
The bulk of the actual code reorganisation is already done by previous
commits, so this change is _mostly_ just dropping in a new set of
server-specific source files alongside the client-specific ones I
created recently. The remaining changes in the shared SSH code are
numerous, but all minor:
- a few extra parameters to BPP and PPL constructors (e.g. 'are you
in server mode?'), and pass both sets of SSH-1 protocol flags from
the login to the connection layer
- in server mode, unconditionally send our version string _before_
waiting for the remote one
- a new hook in the SSH-1 BPP to handle enabling compression in
server mode, where the message exchange works the other way round
- new code in the SSH-2 BPP to do _deferred_ compression the other
way round (the non-deferred version is still nicely symmetric)
- in the SSH-2 transport layer, some adjustments to do key derivation
either way round (swapping round the identifying letters in the
various hash preimages, and making sure to list the KEXINITs in the
right order)
- also in the SSH-2 transport layer, an if statement that controls
whether we send SERVICE_REQUEST and wait for SERVICE_ACCEPT, or
vice versa
- new ConnectionLayer methods for opening outgoing channels for X and
agent forwardings
- new functions in portfwd.c to establish listening sockets suitable
for remote-to-local port forwarding (i.e. not under the direction
of a Conf the way it's done on the client side).
If the child process's standard input is provided by a pipe that's
separate from its output channels, we can - and should - honour a
request to cause that process to receive input EOF, by closing the
output end of that pipe.
As usual, we do this by setting a pending-EOF flag and calling
try_write, to ensure that any buffered output data is sent before the
pipe actually closes.
Not every "session" channel in SSH allocates a pty at all, of course,
and so I'll need a way to run a subprocess without doing so. The
simplest approach seems to be to expand uxpty's remit so that the pty
is optional: now it can open either a pty or a set of pipes for
stdin/out/err, according to an option provided to pty_backend_create.
(It amuses me that without this option I'd have an SSH server which is
incapable of _not_ honouring the "pty-req" channel request. That's
normally the easy part!)
This breaks the previous one-to-one coupling between pty backend
instances and file descriptors passed to uxsel, which I was using to
look up the Pty structure in a tree234 indexed by fd when an uxsel
notification came back. So now each Pty structure contains a
collection of subobjects of a new type PtyFd, and _those_ are what's
stored in the fd-indexed tree.
Another awkward part is that uxsel_set is not incremental: the rwx
flags you pass to it completely supersede the previous set for that
file descriptor, so I had to set up the logic that decides whether
we're trying to read or write each fd in a way that can cope equally
well with the fd aliasing another one (if it's the pty master) or not
(if there are three completely separate pipes).
The SS_SIGFOO family are implemented by sending a signal directly to
the pid of the immediate child process.
I had had the vague idea that it might be more desirable to send the
specified signal to the foreground process group in the tty. That way,
you'd be able to SIGINT (say) the foreground job in a shell session,
and return to the shell _prompt_ without terminating the whole
session, and you could do this in an emergency even if the job was a
full-screen application which had configured termios so that no
keystroke generated SIGINT.
But as far as I can see there's no actual way to do that. I wasn't
able to find any ioctl or termios call to send a signal to a pty's
foreground pgrp, and you can't even do it manually via kill(2) because
first you'd have to find out what the pgrp id _is_, and according to
the man pages, you can only call tcgetpgrp on the slave end of the pty
and even then only if it's your controlling terminal.
So SS_SIGFOO goes to the child process, because that's the only place
I can find that I _can_ send it to sensibly.
SS_BRK translates to tcsendbreak, of course (though I haven't actually
seen any effect of calling this on a pty master, not even if I set
PARMRK on the slave end which by my understanding _ought_ to show me
when break events occur).
This will be applied to the pty's termios settings at creation time,
superseding the default settings uxpty has always used. It works by
including the new sshttymodes.h with TTYMODES_LOCAL_ONLY defined, so
that modes not supported by a particular Unix system are automatically
quietly ignored.
Of course, a struct ssh_ttymodes always has the option of representing
"please make no change to the defaults", and of course, that's
precisely what is done by the one that pty_init constructs for clients
that aren't calling pty_backend_create directly.
The function that does the main pty setup is now called
pty_backend_create(), and has an API better suited to uxpty in
particular than the standard backend_init() virtual constructor. It
leaves off a load of standard parameters to backend_init() which
aren't really relevant to this backend, and it adds the 'argv'
parameter to pass in a split-up command line, which is unique to it.
The old creation function still exists, as a tiny wrapper that calls
the new pty_backend_create. And that version still gets the argv
parameter from the process-global variable pty_argv[], so the call
sites in pterm haven't had to change for this.
This will make it possible to instantiate a pty backend directly from
the SSH server code, without having to do anything really excessively
cumbersome to pass in a subcommand in the form of pre-split argv. (And
I'll add a few more specialist parameters to the new function shortly.)
There was a bit of a race condition depending on whether uxpty spotted
the EOF/EIO on the process's output first, or the SIGCHLD for its
actual termination: if the former came first, it would never bother to
reap the exit code at all.
It still doesn't bother if it's closing the session immediately and
the process genuinely _hasn't_ died (say, if it detaches itself
completely from the controlling tty to run in the background like a
weird parody of an old DOS TSR). But now when we see EOF, we make an
immediate (but nonblocking) attempt to wait for the child process, in
case its exit code was already available and we just hadn't noticed
yet.
The uxpty backend is going to be reused to implement the "session"
channel type in the upcoming SSH server implementation, which puts
quite a few new requirements on it. The first of them is that when we
get EOF from the subprocess's output channel (or rather, EIO from the
pty), we should actually notify the Seat of this.
In principle we should have been doing this all along, I'm pretty
sure. It hasn't happened to matter until now because the receiving
Seats haven't done much with that notification. But it will matter
when that's what controls the sending of SSH_MSG_CHANNEL_EOF.
The word 'PuTTY' in the outgoing SSH version string has always
represented the name of the *SSH implementation* as opposed to the
name of the specific program containing it (for example, PSCP and
PSFTP don't announce themselves with a different banner). But I think
that a change from client to server merits a change in that
implementation name, so I'm removing the prefix "PuTTY" from the
constant string sshver[], and moving it to a parameter passed in
separately to ssh_verstring_new, so that the upcoming server can pass
in a different one.
This new function contains the core setup for a PortForwarding
structure, and should be reusable for any kind of forwarding that will
simply be passing data between a local socket and an SSH channel
without any tricky modifications. On the server side, X11 and agent
forwarding both work exactly like this, so they will find this
refactored function useful during setup.
The contents of the function was originally part of pfl_accepting,
which now does all that by calling the new function. pfl_accepting is
not _quite_ doing a simple unmodified forwarding, because it might
have to prefix it with a SOCKS exchange; in that situation it rewrites
a few fields of the PortForwarding to some less generic values once
portfwd_raw_new() has returned.
I've written the decryption side of the PKCS#1 encryption used in
SSH-1, and also the RSAES-OAEP system used by SSH-2 RSA kex. Also, the
RSA kex structures now each come with an 'extra' pointer giving the
minimum key length.
Lots of user-facing messages that claim that the 'server' just did
something or other unexpected will now need to be issued _by_ the
server, when the client does the same unexpected thing. So I've
reworded them all to talk about the 'remote side' instead of the
'server', and the SSH-2 key setup messages talk about initialising
inbound and outbound crypto primitives rather than client->server and
server->client.
ssh2connection.c now knows how to unmarshal the message formats for
all the channel requests we'll need to handle when we're the server
and a client sends them. Each one is translated into a call to a new
method in the Channel vtable, which is implemented by a trivial
'always fail' routine in every channel type we know about so far.
The vtable method underneath sshfwd_write now takes an is_stderr
parameter, and in SSH-2, this is implemented by having separate stdout
and stderr bufchains in each outgoing channel, and counting the size
of both for the purposes of measuring backlog and so forth.
To avoid making _most_ call sites more verbose, the usual macro
wrapper hasn't changed its API; it just sets is_stderr=FALSE. To use
the new feature, there's an sshfwd_write_ext macro that exposes the
extra parameter.