Merge out from trunk, to keep this branch viable. We are now up to

date as of r7913.

[originally from svn r7914]
[r7913 == d7eda6d99c]
This commit is contained in:
Simon Tatham 2008-03-10 18:48:36 +00:00
Родитель 12e019bafc d7eda6d99c
Коммит 822628246e
81 изменённых файлов: 2085 добавлений и 933 удалений

113
Buildscr Normal file
Просмотреть файл

@ -0,0 +1,113 @@
# -*- sh -*-
# Build script to construct a full distribution directory of PuTTY.
module putty
# Set up the arguments for the main make command.
set Makever -DSVN_REV=$(revision)
ifneq "$(!numeric $(revision))" "yes" set Makever $(Makever) -DMODIFIED
ifneq "$(RELEASE)" "" set Makever $(Makever) -DRELEASE=$(RELEASE)
ifneq "$(date)" "" set Makever $(Makever) -DSNAPSHOT=$(date)
set Makeargs VER="$(Makever)"
ifneq "$(XFLAGS)" "" set Makeargs $(Makeargs) XFLAGS="$(XFLAGS)"
ifneq "$(MAKEARGS)" "" set Makeargs $(Makeargs) $(MAKEARGS)
# Set up the version string for the docs build.
set Docmakeargs VERSION="PuTTY revision $(revision)"
ifneq "$(RELEASE)" "" set Docmakeargs VERSION="PuTTY release $(RELEASE)"
ifneq "$(date)" "" set Docmakeargs VERSION="PuTTY development snapshot $(date)"
# Set up the version string for the Unix source archive.
set Unxver r$(revision)
ifneq "$(RELEASE)" "" set Unxver $(RELEASE)
ifneq "$(date)" "" set Unxver $(date)
# Set up the various version strings for the installer.
set Iversion r$(revision)
set Iname PuTTY revision $(revision)
set Ivertext Revision $(revision)
set Irev $(revision)
set Ifilename putty-$(Iversion)-installer.exe
ifneq "$(RELEASE)" "" set Iversion $(RELEASE)
ifneq "$(RELEASE)" "" set Iname PuTTY version $(RELEASE)
ifneq "$(RELEASE)" "" set Ivertext Release $(RELEASE)
ifneq "$(RELEASE)" "" set Irev 0
ifneq "$(RELEASE)" "" set Ifilename putty-$(RELEASE)-installer.exe
ifneq "$(date)" "" set Iversion $(date):r$(revision)
ifneq "$(date)" "" set Iname PuTTY development snapshot $(date):r$(revision)
ifneq "$(date)" "" set Ivertext Development snapshot $(date):r$(revision)
ifneq "$(date)" "" set Ifilename putty-$(date)-installer.exe
# Set up the version string for the installer.
set Iversion r$(revision)
ifneq "$(RELEASE)" "" set Iversion $(RELEASE)
ifneq "$(date)" "" set Iversion $(date):r$(revision)
in putty do ./mksrcarc.sh
in putty do ./mkunxarc.sh $(Unxver)
in putty do perl mkfiles.pl
in putty/doc do make $(Docmakeargs) putty.hlp
in putty/doc do make $(Docmakeargs) chm
# Munge the installer script locally so that it reports the version
# we're really building.
in putty/windows do perl -i~ -pe 'BEGIN{$$a=shift@ARGV;}s/^(AppVerName=).*$$/$$1$$a/' '$(Iname)' putty.iss
in putty/windows do perl -i~ -pe 'BEGIN{$$a=shift@ARGV;}s/^(VersionInfoTextVersion=).*$$/$$1$$a/' '$(Ivertext)' putty.iss
in putty/windows do perl -i~ -pe 'BEGIN{$$a=shift@ARGV;}s/^(AppVersion=).*$$/$$1$$a/' '$(Iversion)' putty.iss
in putty/windows do perl -i~ -pe 'BEGIN{$$a=shift@ARGV;$$a=~s/M//;}s/^(VersionInfoVersion=\d+\.\d+\.)\d+(\.\d+)\r?$$/$$1$$a$$2/' '$(Irev)' putty.iss
# Windowsify LICENCE, since it's going in the Windows installer.
in putty do perl -i~ -pe 'y/\015//d;s/$$/\015/' LICENCE
delegate windows
# FIXME: Cygwin alternative?
in putty/windows do cmd /c vcvars32 \& nmake -f Makefile.vc $(Makeargs)
# Ignore exit code from hhc, in favour of seeing whether the .chm
# file was created. (Yuck; but hhc appears to return non-zero
# exit codes on whim.)
in putty/doc do hhc putty.hhp; test -f putty.chm
in putty/windows do iscc putty.iss
return putty/windows/*.exe
return putty/windows/*.map
return putty/doc/putty.chm
return putty/windows/Output/setup.exe
enddelegate
in putty/doc do make mostlyclean
in putty/doc do make $(Docmakeargs)
in putty/windows do zip -k -j putty.zip `ls *.exe | grep -v puttytel` ../doc/putty.chm ../doc/putty.hlp ../doc/putty.cnt
in putty/doc do zip puttydoc.zip *.html
# Deliver the actual PuTTY release directory into a subdir `putty'.
deliver putty/windows/*.exe putty/x86/$@
deliver putty/windows/putty.zip putty/x86/$@
deliver putty/windows/Output/setup.exe putty/x86/$(Ifilename)
deliver putty/doc/puttydoc.zip putty/$@
deliver putty/doc/putty.chm putty/$@
deliver putty/doc/putty.hlp putty/$@
deliver putty/doc/putty.cnt putty/$@
deliver putty/doc/puttydoc.txt putty/$@
deliver putty/doc/*.html putty/htmldoc/$@
deliver putty/putty-src.zip putty/$@
deliver putty/*.tar.gz putty/$@
# Deliver the map files alongside the `proper' release deliverables.
deliver putty/windows/*.map maps-x86/$@
# Deliver sign.sh, so that whoever has just built PuTTY (the
# snapshot scripts or me, depending) can conveniently sign it with
# whatever key they want.
deliver putty/sign.sh $@
# Building the md5sums file is most easily done in the destination
# directory.
in-dest putty do md5sum `\find * -type f -print` > md5sums
# And construct .htaccess files. One in the top-level directory,
# setting the MIME types for Windows help files and providing an
# appropriate link to the source archive:
in-dest putty do echo "AddType application/octet-stream .chm" >> .htaccess
in-dest putty do echo "AddType application/octet-stream .hlp" >> .htaccess
in-dest putty do echo "AddType application/octet-stream .cnt" >> .htaccess
in-dest putty do set -- putty*.tar.gz; for k in '' .DSA .RSA; do echo RedirectMatch temp '(.*/)'putty.tar.gz$$k\$$ '$$1'"$$1$$k" >> .htaccess; done
# And one in the x86 directory, providing a link for the installer.
in-dest putty/x86 do set -- putty*installer.exe; for k in '' .DSA .RSA; do echo RedirectMatch temp '(.*/)'putty-installer.exe$$k\$$ '$$1'"$$1$$k" >> .htaccess; done

Просмотреть файл

@ -53,6 +53,11 @@ Before tagging a release
containing the word XXX-REVIEW-BEFORE-RELEASE.
(Any such comments should state clearly what needs to be done.)
- Also, do some testing of the Windows version with Minefield, and
of the Unix version with valgrind or efence or both. In
particular, any headline features for the release should get a
workout with memory checking enabled!
For a long time we got away with never checking the current version
number in at all - all version numbers were passed into the build
system on the compiler command line, and the _only_ place version
@ -109,83 +114,27 @@ of the tag.
ixion:src/putty/local/announce-<ver> in case it's needed again
within days of the release going out.
- On my local machines, check out the release-tagged version of the
sources. Do this in a _clean_ directory; don't depend on my usual
source dir.
+ Make sure to run mkfiles.pl _after_ this checkout, just in
case.
- Build the release: `bob putty-0.XX RELEASE=0.XX'. This should
generate a basically valid release directory as
`build.out/putty', and provide link maps and sign.sh alongside
that in build.out.
- Build the source archives now, while the directory is still
pristine.
+ run ./mksrcarc.sh to build the Windows source zip.
+ run `./mkunxarc.sh X.YZ' to build the Unix tarball.
- Do a bit of checking that the release binaries basically work,
report their version numbers accurately, and so on. Test the
installer and the Unix source tarball.
- Build the Windows/x86 release binaries. Don't forget to supply
VER=/DRELEASE=<ver>. Run them, or at least one or two of them, to
ensure that they really do report their version number correctly,
and sanity-check the version info reported on the files by Windows.
+ Save the release link maps. Currently I keep these on ixion,
in src/putty/local/maps-<version>.
- Save the link maps. Currently I keep these on ixion, in
src/putty/local/maps-<version>.
- Run Halibut to build the docs. Define VERSION on the make command
line to override the version strings, since Subversion revision
numbers are less meaningful on a tag.
+ change into the doc subdir
+ run `make VERSION="PuTTY release 0.XX" chm', then run `hhc
putty.hhp' to build the .CHM
+ then run `make mostlyclean' (destroys the hhc input files but
_not_ the .CHM)
+ then `make VERSION="PuTTY release 0.XX"'
- Build the binary archive putty.zip: all the .exe files except
PuTTYtel, and the .hlp, .cnt and .chm files.
+ zip -k putty.zip `ls *.exe | grep -v puttytel` putty.hlp putty.cnt putty.chm
- Build the docs archive puttydoc.zip: it contains all the HTML
files output from Halibut.
+ zip puttydoc.zip *.html
- Build the installer.
- Sign the release (gpg --detach-sign).
+ Sign the locally built x86 binaries, the locally built x86
binary zipfile, and the locally built x86 installer, with the
release keys.
+ The source archive should be signed with the release keys.
+ Don't forget to sign with both DSA and RSA keys for absolutely
everything.
for i in <filenames>; do for t in DSA RSA; do gpg --load-extension=idea --detach-sign -u "Releases ($t)" -o $i.$t $i; done; done
- Begin to pull together the release directory structure.
+ subdir `x86' containing the x86 binaries, x86 binary zip, x86
installer, and all signatures on the above.
+ top-level dir contains the Windows source zip (plus
signatures), the Unix source tarball (plus signatures),
puttydoc.txt, the .hlp, .cnt and .chm files, and puttydoc.zip.
- Create subdir `htmldoc' in the release directory, which should
contain exactly the same set of HTML files that went into
puttydoc.zip.
+ It also needs a copy of sitestyle.css, because the online
versions of the HTML docs will link to this (although the
zipped form should be self-contained).
- Create and sign an md5sums file in the top-level directory.
+ The md5sums files need not list the .DSA and .RSA signatures.
Easiest thing is to run this command:
md5sum `\find * -name '*SA' -o -type f -print` > md5sums
+ Sign the md5sums file (gpg --clearsign).
for t in DSA RSA; do gpg --load-extension=idea --clearsign -u "Releases ($t)" -o md5sums.$t md5sums; done
- Now double-check by verifying all the signatures on all the
files, and running md5sum -c on the md5sums file.
- Sign the release: in the `build.out' directory, type `./sign.sh
putty Releases', and enter the passphrases a lot of times.
- Now the whole release directory should be present and correct.
Upload to ixion:www/putty/<ver>.
Upload it to ixion:www/putty/<ver>.
- Do final checks on the release directory:
+ verify all the signatures. In each directory:
for i in *.*SA; do case $i in md5sums*) gpg --verify $i;; *) gpg --verify $i `echo $i | sed 's/\..SA$//'`;; esac; done
+ verify all the signatures:
for i in `find . -name '*.*SA'`; do case $i in *md5sums*) gpg --verify $i;; *) gpg --verify $i ${i%%.?SA};; esac; done
+ check the md5sums:
md5sum -c md5sums

Просмотреть файл

@ -1 +1 @@
0.59
0.60

Просмотреть файл

@ -1,4 +1,4 @@
PuTTY is copyright 1997-2007 Simon Tatham.
PuTTY is copyright 1997-2008 Simon Tatham.
Portions copyright Robert de Bath, Joris van Rantwijk, Delian
Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,

18
Recipe
Просмотреть файл

@ -81,7 +81,8 @@
#
# Note that this definition is always enabled in the Cygwin
# build, since at the time of writing this <htmlhelp.h> is
# known not to be available in Cygwin.
# known not to be available in Cygwin (although you can use
# the htmlhelp.h supplied with HTML Help Workshop).
#
# - RCFL=/DNO_MANIFESTS (Windows only)
# Disables inclusion of XML application manifests in the PuTTY
@ -189,6 +190,7 @@ RCFLAGS += $(VER)
# `make install' target for Unix.
!begin gtk
install:
mkdir -p $(DESTDIR)$(bindir) $(DESTDIR)$(man1dir)
$(INSTALL_PROGRAM) -m 755 plink $(DESTDIR)$(bindir)/plink
$(INSTALL_PROGRAM) -m 755 pscp $(DESTDIR)$(bindir)/pscp
$(INSTALL_PROGRAM) -m 755 psftp $(DESTDIR)$(bindir)/psftp
@ -305,13 +307,13 @@ psftp : [C] psftp winsftp wincons WINSSH BE_SSH SFTP wildcard WINMISC
+ psftp.res LIBS
pageant : [G] winpgnt sshrsa sshpubk sshdes sshbn sshmd5 version tree234
+ misc sshaes sshsha winpgntc sshdss sshsh512 winutils winmisc
+ winhelp pageant.res LIBS
+ misc sshaes sshsha winpgntc sshdss sshsh256 sshsh512 winutils
+ winmisc winhelp pageant.res LIBS
puttygen : [G] winpgen sshrsag sshdssg sshprime sshdes sshbn sshmd5 version
+ sshrand winnoise sshsha winstore misc winctrls sshrsa sshdss winmisc
+ sshpubk sshaes sshsh512 import winutils puttygen.res tree234
+ notiming winhelp LIBS wintime
+ sshpubk sshaes sshsh256 sshsh512 import winutils puttygen.res
+ tree234 notiming winhelp LIBS wintime
pterm : [X] GTKTERM uxmisc misc ldisc settings uxpty uxsel BE_NONE uxstore
+ uxsignal CHARSET cmdline uxpterm version time xpmpterm xpmptcfg
@ -326,8 +328,8 @@ plink : [U] uxplink uxcons NONSSH UXSSH U_BE_ALL logging UXMISC uxsignal
puttygen : [U] cmdgen sshrsag sshdssg sshprime sshdes sshbn sshmd5 version
+ sshrand uxnoise sshsha misc sshrsa sshdss uxcons uxstore uxmisc
+ sshpubk sshaes sshsh512 import puttygen.res time tree234 uxgen
+ notiming
+ sshpubk sshaes sshsh256 sshsh512 import puttygen.res time tree234
+ uxgen notiming
pscp : [U] pscp uxsftp uxcons UXSSH BE_SSH SFTP wildcard UXMISC
psftp : [U] psftp uxsftp uxcons UXSSH BE_SSH SFTP wildcard UXMISC
@ -340,7 +342,7 @@ PuTTYtel : [M] terminal wcwidth ldiscucs logging BE_NOSSH mac macdlg
+ CHARSET stricmp vsnprint dialog config macctrls minibidi
PuTTYgen : [M] macpgen sshrsag sshdssg sshprime sshdes sshbn sshmd5 version
+ sshrand macnoise sshsha macstore misc sshrsa sshdss macmisc sshpubk
+ sshaes sshsh512 import macpgen.rsrc macpgkey macabout
+ sshaes sshsh256 sshsh512 import macpgen.rsrc macpgkey macabout
PuTTY : [MX] osxmain OSXTERM OSXMISC CHARSET U_BE_ALL NONSSH UXSSH
+ ux_x11 uxpty uxsignal testback putty.icns info.plist

Просмотреть файл

@ -22,10 +22,10 @@ const int be_default_protocol = PROT_TELNET;
const int be_default_protocol = PROT_SSH;
#endif
struct backend_list backends[] = {
{PROT_SSH, "ssh", &ssh_backend},
{PROT_TELNET, "telnet", &telnet_backend},
{PROT_RLOGIN, "rlogin", &rlogin_backend},
{PROT_RAW, "raw", &raw_backend},
{0, NULL}
Backend *backends[] = {
&ssh_backend,
&telnet_backend,
&rlogin_backend,
&raw_backend,
NULL
};

Просмотреть файл

@ -22,11 +22,11 @@ const int be_default_protocol = PROT_TELNET;
const int be_default_protocol = PROT_SSH;
#endif
struct backend_list backends[] = {
{PROT_SSH, "ssh", &ssh_backend},
{PROT_TELNET, "telnet", &telnet_backend},
{PROT_RLOGIN, "rlogin", &rlogin_backend},
{PROT_RAW, "raw", &raw_backend},
{PROT_SERIAL, "serial", &serial_backend},
{0, NULL}
Backend *backends[] = {
&ssh_backend,
&telnet_backend,
&rlogin_backend,
&raw_backend,
&serial_backend,
NULL
};

Просмотреть файл

@ -1,16 +1,11 @@
/*
* Linking module for PSCP: list the available backends, but
* without accompanying function suites. Used only for name
* lookups.
* Linking module for programs that do not support selection of backend
* (such as pscp or pterm).
*/
#include <stdio.h>
#include "putty.h"
struct backend_list backends[] = {
{PROT_SSH, "ssh", NULL},
{PROT_TELNET, "telnet", NULL},
{PROT_RLOGIN, "rlogin", NULL},
{PROT_RAW, "raw", NULL},
{0, NULL}
Backend *backends[] = {
NULL
};

Просмотреть файл

@ -10,12 +10,12 @@ const int be_default_protocol = PROT_TELNET;
const char *const appname = "PuTTYtel";
struct backend_list backends[] = {
{PROT_TELNET, "telnet", &telnet_backend},
{PROT_RLOGIN, "rlogin", &rlogin_backend},
{PROT_RAW, "raw", &raw_backend},
{PROT_SERIAL, "serial", &serial_backend},
{0, NULL}
Backend *backends[] = {
&telnet_backend,
&rlogin_backend,
&raw_backend,
&serial_backend,
NULL
};
/*

Просмотреть файл

@ -10,11 +10,11 @@ const int be_default_protocol = PROT_TELNET;
const char *const appname = "PuTTYtel";
struct backend_list backends[] = {
{PROT_TELNET, "telnet", &telnet_backend},
{PROT_RLOGIN, "rlogin", &rlogin_backend},
{PROT_RAW, "raw", &raw_backend},
{0, NULL}
Backend *backends[] = {
&telnet_backend,
&rlogin_backend,
&raw_backend,
NULL
};
/*

Просмотреть файл

@ -640,6 +640,11 @@ int main(int argc, char **argv)
random_ref();
entropy = get_random_data(bits / 8);
if (!entropy) {
fprintf(stderr, "puttygen: failed to collect entropy, "
"could not generate key\n");
return 1;
}
random_add_heavynoise(entropy, bits / 8);
memset(entropy, 0, bits/8);
sfree(entropy);

Просмотреть файл

@ -263,8 +263,8 @@ int cmdline_process_param(char *p, char *value, int need_save, Config *cfg)
unsigned len = portp - host;
if (len >= sizeof(cfg->ssh_nc_host))
len = sizeof(cfg->ssh_nc_host) - 1;
strncpy(cfg->ssh_nc_host, value, len);
cfg->ssh_nc_host[sizeof(cfg->ssh_nc_host) - 1] = '\0';
memcpy(cfg->ssh_nc_host, value, len);
cfg->ssh_nc_host[len] = '\0';
cfg->ssh_nc_port = atoi(portp+1);
} else {
cmdline_error("-nc expects argument of form 'host:port'");
@ -315,19 +315,33 @@ int cmdline_process_param(char *p, char *value, int need_save, Config *cfg)
if (!strcmp(p, "-pw")) {
RETURN(2);
UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
cmdline_password = value;
SAVEABLE(1);
/* We delay evaluating this until after the protocol is decided,
* so that we can warn if it's of no use with the selected protocol */
if (cfg->protocol != PROT_SSH)
cmdline_error("the -pw option can only be used with the "
"SSH protocol");
else {
cmdline_password = dupstr(value);
/* Assuming that `value' is directly from argv, make a good faith
* attempt to trample it, to stop it showing up in `ps' output
* on Unix-like systems. Not guaranteed, of course. */
memset(value, 0, strlen(value));
}
}
if (!strcmp(p, "-agent") || !strcmp(p, "-pagent") ||
!strcmp(p, "-pageant")) {
RETURN(1);
UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
SAVEABLE(0);
cfg->tryagent = TRUE;
}
if (!strcmp(p, "-noagent") || !strcmp(p, "-nopagent") ||
!strcmp(p, "-nopageant")) {
RETURN(1);
UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
SAVEABLE(0);
cfg->tryagent = FALSE;
}
@ -360,13 +374,13 @@ int cmdline_process_param(char *p, char *value, int need_save, Config *cfg)
if (!strcmp(p, "-t")) {
RETURN(1);
UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
SAVEABLE(0);
SAVEABLE(1); /* lower priority than -m */
cfg->nopty = 0;
}
if (!strcmp(p, "-T")) {
RETURN(1);
UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
SAVEABLE(0);
SAVEABLE(1);
cfg->nopty = 1;
}

164
config.c
Просмотреть файл

@ -15,20 +15,6 @@
#define HOST_BOX_TITLE "Host Name (or IP address)"
#define PORT_BOX_TITLE "Port"
/*
* Convenience function: determine whether this binary supports a
* given backend.
*/
static int have_backend(int protocol)
{
struct backend_list *p = backends;
for (p = backends; p->name; p++) {
if (p->protocol == protocol)
return 1;
}
return 0;
}
static void config_host_handler(union control *ctrl, void *dlg,
void *data, int event)
{
@ -104,7 +90,7 @@ struct hostport {
void config_protocolbuttons_handler(union control *ctrl, void *dlg,
void *data, int event)
{
int button, defport;
int button;
Config *cfg = (Config *)data;
struct hostport *hp = (struct hostport *)ctrl->radio.context.p;
@ -128,15 +114,20 @@ void config_protocolbuttons_handler(union control *ctrl, void *dlg,
assert(button >= 0 && button < ctrl->radio.nbuttons);
cfg->protocol = ctrl->radio.buttondata[button].i;
if (oldproto != cfg->protocol) {
defport = -1;
switch (cfg->protocol) {
case PROT_SSH: defport = 22; break;
case PROT_TELNET: defport = 23; break;
case PROT_RLOGIN: defport = 513; break;
}
if (defport > 0 && cfg->port != defport) {
cfg->port = defport;
}
Backend *ob = backend_from_proto(oldproto);
Backend *nb = backend_from_proto(cfg->protocol);
assert(ob);
assert(nb);
/* Iff the user hasn't changed the port from the protocol
* default (if any), update it with the new protocol's
* default.
* (XXX: this isn't perfect; a default can become permanent
* by going via the serial backend. However, it helps with
* the common case of tabbing through the controls in order
* and setting a non-default port.) */
if (cfg->port == ob->default_port &&
cfg->port > 0 && nb->default_port > 0)
cfg->port = nb->default_port;
}
dlg_refresh(hp->host, dlg);
dlg_refresh(hp->port, dlg);
@ -256,6 +247,7 @@ static void kexlist_handler(union control *ctrl, void *dlg,
{ "Diffie-Hellman group 1", KEX_DHGROUP1 },
{ "Diffie-Hellman group 14", KEX_DHGROUP14 },
{ "Diffie-Hellman group exchange", KEX_DHGEX },
{ "RSA-based key exchange", KEX_RSA },
{ "-- warn below here --", KEX_WARN }
};
@ -383,7 +375,7 @@ struct sessionsaver_data {
*/
static int load_selected_session(struct sessionsaver_data *ssd,
char *savedsession,
void *dlg, Config *cfg)
void *dlg, Config *cfg, int *maybe_launch)
{
int i = dlg_listbox_index(ssd->listbox, dlg);
int isdef;
@ -392,13 +384,17 @@ static int load_selected_session(struct sessionsaver_data *ssd,
return 0;
}
isdef = !strcmp(ssd->sesslist.sessions[i], "Default Settings");
load_settings(ssd->sesslist.sessions[i], !isdef, cfg);
load_settings(ssd->sesslist.sessions[i], cfg);
if (!isdef) {
strncpy(savedsession, ssd->sesslist.sessions[i],
SAVEDSESSION_LEN);
savedsession[SAVEDSESSION_LEN-1] = '\0';
if (maybe_launch)
*maybe_launch = TRUE;
} else {
savedsession[0] = '\0';
if (maybe_launch)
*maybe_launch = FALSE;
}
dlg_refresh(NULL, dlg);
/* Restore the selection, which might have been clobbered by
@ -464,6 +460,7 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
dlg_listbox_select(ssd->listbox, dlg, top);
}
} else if (event == EVENT_ACTION) {
int mbl = FALSE;
if (!ssd->midsession &&
(ctrl == ssd->listbox ||
(ssd->loadbutton && ctrl == ssd->loadbutton))) {
@ -474,8 +471,8 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
* double-click on the list box _and_ that session
* contains a hostname.
*/
if (load_selected_session(ssd, savedsession, dlg, cfg) &&
(ctrl == ssd->listbox && cfg_launchable(cfg))) {
if (load_selected_session(ssd, savedsession, dlg, cfg, &mbl) &&
(mbl && ctrl == ssd->listbox && cfg_launchable(cfg))) {
dlg_end(dlg, 1); /* it's all over, and succeeded */
}
} else if (ctrl == ssd->savebutton) {
@ -496,7 +493,7 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
}
}
{
char *errmsg = save_settings(savedsession, !isdef, cfg);
char *errmsg = save_settings(savedsession, cfg);
if (errmsg) {
dlg_error_msg(dlg, errmsg);
sfree(errmsg);
@ -533,12 +530,14 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
if (dlg_last_focused(ctrl, dlg) == ssd->listbox &&
!cfg_launchable(cfg)) {
Config cfg2;
if (!load_selected_session(ssd, savedsession, dlg, &cfg2)) {
int mbl = FALSE;
if (!load_selected_session(ssd, savedsession, dlg,
&cfg2, &mbl)) {
dlg_beep(dlg);
return;
}
/* If at this point we have a valid session, go! */
if (*cfg2.host) {
if (mbl && cfg_launchable(&cfg2)) {
*cfg = cfg2; /* structure copy */
cfg->remote_cmd_ptr = NULL;
dlg_end(dlg, 1);
@ -792,7 +791,29 @@ static void ttymodes_handler(union control *ctrl, void *dlg,
char *p = cfg->ttymodes;
int i = 0, len = lenof(cfg->ttymodes);
while (*p) {
int multisel = dlg_listbox_index(td->listbox, dlg) < 0;
if (dlg_listbox_issel(td->listbox, dlg, i)) {
if (!multisel) {
/* Populate controls with entry we're about to
* delete, for ease of editing.
* (If multiple entries were selected, don't
* touch the controls.) */
char *val = strchr(p, '\t');
if (val) {
int ind = 0;
val++;
while (ttymodes[ind]) {
if (strlen(ttymodes[ind]) == val-p-1 &&
!strncmp(ttymodes[ind], p, val-p-1))
break;
ind++;
}
dlg_listbox_select(td->modelist, dlg, ind);
dlg_radiobutton_set(td->valradio, dlg,
(*val == 'V'));
dlg_editbox_set(td->valbox, dlg, val+1);
}
}
memmove(p, p+strlen(p)+1, len - (strlen(p)+1));
i++;
continue;
@ -866,7 +887,7 @@ static void environ_handler(union control *ctrl, void *dlg,
if (i < 0) {
dlg_beep(dlg);
} else {
char *p, *q;
char *p, *q, *str;
dlg_listbox_del(ed->listbox, dlg, i);
p = cfg->environmt;
@ -881,8 +902,20 @@ static void environ_handler(union control *ctrl, void *dlg,
q = p;
if (!*p)
goto disaster;
while (*p)
p++;
/* Populate controls with the entry we're about to delete
* for ease of editing */
str = p;
p = strchr(p, '\t');
if (!p)
goto disaster;
*p = '\0';
dlg_editbox_set(ed->varbox, dlg, str);
p++;
str = p;
dlg_editbox_set(ed->valbox, dlg, str);
p = strchr(p, '\0');
if (!p)
goto disaster;
p++;
while (*p) {
while (*p)
@ -995,7 +1028,8 @@ static void portfwd_handler(union control *ctrl, void *dlg,
if (i < 0)
dlg_beep(dlg);
else {
char *p, *q;
char *p, *q, *src, *dst;
char dir;
dlg_listbox_del(pfd->listbox, dlg, i);
p = cfg->portfwd;
@ -1010,8 +1044,44 @@ static void portfwd_handler(union control *ctrl, void *dlg,
q = p;
if (!*p)
goto disaster2;
while (*p)
/* Populate the controls with the entry we're about to
* delete, for ease of editing. */
{
static const char *const afs = "A46";
char *afp = strchr(afs, *p);
#ifndef NO_IPV6
int idx = afp ? afp-afs : 0;
#endif
if (afp)
p++;
#ifndef NO_IPV6
dlg_radiobutton_set(pfd->addressfamily, dlg, idx);
#endif
}
{
static const char *const dirs = "LRD";
dir = *p;
dlg_radiobutton_set(pfd->direction, dlg,
strchr(dirs, dir) - dirs);
}
p++;
if (dir != 'D') {
src = p;
p = strchr(p, '\t');
if (!p)
goto disaster2;
*p = '\0';
p++;
dst = p;
} else {
src = p;
dst = "";
}
p = strchr(p, '\0');
if (!p)
goto disaster2;
dlg_editbox_set(pfd->sourcebox, dlg, src);
dlg_editbox_set(pfd->destbox, dlg, dst);
p++;
while (*p) {
while (*p)
@ -1089,7 +1159,7 @@ void setup_config_box(struct controlbox *b, int midsession,
hp->port = c;
ctrl_columns(s, 1, 100);
if (!have_backend(PROT_SSH)) {
if (!backend_from_proto(PROT_SSH)) {
ctrl_radiobuttons(s, "Connection type:", NO_SHORTCUT, 3,
HELPCTX(session_hostname),
config_protocolbuttons_handler, P(hp),
@ -1180,7 +1250,7 @@ void setup_config_box(struct controlbox *b, int midsession,
{
char *sshlogname, *sshrawlogname;
if ((midsession && protocol == PROT_SSH) ||
(!midsession && have_backend(PROT_SSH))) {
(!midsession && backend_from_proto(PROT_SSH))) {
sshlogname = "SSH packets";
sshrawlogname = "SSH packets and raw data";
} else {
@ -1216,7 +1286,7 @@ void setup_config_box(struct controlbox *b, int midsession,
dlg_stdcheckbox_handler, I(offsetof(Config,logflush)));
if ((midsession && protocol == PROT_SSH) ||
(!midsession && have_backend(PROT_SSH))) {
(!midsession && backend_from_proto(PROT_SSH))) {
s = ctrl_getset(b, "Session/Logging", "ssh",
"Options specific to SSH packet logging");
ctrl_checkbox(s, "Omit known password fields", 'k',
@ -1242,6 +1312,9 @@ void setup_config_box(struct controlbox *b, int midsession,
ctrl_checkbox(s, "Implicit CR in every LF", 'r',
HELPCTX(terminal_lfhascr),
dlg_stdcheckbox_handler, I(offsetof(Config,lfhascr)));
ctrl_checkbox(s, "Implicit LF in every CR", 'f',
HELPCTX(terminal_crhaslf),
dlg_stdcheckbox_handler, I(offsetof(Config,crhaslf)));
ctrl_checkbox(s, "Use background colour to erase screen", 'e',
HELPCTX(terminal_bce),
dlg_stdcheckbox_handler, I(offsetof(Config,bce)));
@ -1399,13 +1472,13 @@ void setup_config_box(struct controlbox *b, int midsession,
s = ctrl_getset(b, "Window", "size", "Set the size of the window");
ctrl_columns(s, 2, 50, 50);
c = ctrl_editbox(s, "Rows", 'r', 100,
HELPCTX(window_size),
dlg_stdeditbox_handler, I(offsetof(Config,height)),I(-1));
c->generic.column = 0;
c = ctrl_editbox(s, "Columns", 'm', 100,
HELPCTX(window_size),
dlg_stdeditbox_handler, I(offsetof(Config,width)), I(-1));
c->generic.column = 0;
c = ctrl_editbox(s, "Rows", 'r', 100,
HELPCTX(window_size),
dlg_stdeditbox_handler, I(offsetof(Config,height)),I(-1));
c->generic.column = 1;
ctrl_columns(s, 1, 100);
@ -1835,7 +1908,7 @@ void setup_config_box(struct controlbox *b, int midsession,
* when we're not doing SSH.
*/
if (have_backend(PROT_SSH) && (!midsession || protocol == PROT_SSH)) {
if (backend_from_proto(PROT_SSH) && (!midsession || protocol == PROT_SSH)) {
/*
* The Connection/SSH panel.
@ -2172,6 +2245,9 @@ void setup_config_box(struct controlbox *b, int midsession,
ctrl_droplist(s, "Handles SSH-2 key re-exchange badly", 'k', 20,
HELPCTX(ssh_bugs_rekey2),
sshbug_handler, I(offsetof(Config,sshbug_rekey2)));
ctrl_droplist(s, "Ignores SSH-2 maximum packet size", 'x', 20,
HELPCTX(ssh_bugs_maxpkt2),
sshbug_handler, I(offsetof(Config,sshbug_maxpkt2)));
}
}
}

Просмотреть файл

@ -35,7 +35,7 @@ VERSIONIDS=vids
endif
CHAPTERS := $(SITE) blurb intro gs using config pscp psftp plink pubkey
CHAPTERS += pageant errors faq feedback licence udp pgpkeys
CHAPTERS += pageant errors faq feedback licence udp pgpkeys sshnames
CHAPTERS += index $(VERSIONIDS)
INPUTS = $(patsubst %,%.but,$(CHAPTERS))
@ -46,6 +46,10 @@ HALIBUT = halibut
index.html: $(INPUTS)
$(HALIBUT) --text --html --winhelp $(INPUTS)
# During formal builds it's useful to be able to build this one alone.
putty.hlp: $(INPUTS)
$(HALIBUT) --winhelp $(INPUTS)
putty.info: $(INPUTS)
$(HALIBUT) --info $(INPUTS)

Просмотреть файл

@ -31,6 +31,6 @@ features not described here; and the \i\cw{pterm} and command-line
Unix-specific documentation that currently exists is the
\I{man pages for PuTTY tools}man pages.
\copyright This manual is copyright 2001-2007 Simon Tatham. All
\copyright This manual is copyright 2001-2008 Simon Tatham. All
rights reserved. You may distribute this documentation under the MIT
licence. See \k{licence} for the licence text in full.

Просмотреть файл

@ -61,13 +61,6 @@ you want them saved. Then come back to the Session panel. Select the
\q{\i{Default Settings}} entry in the saved sessions list, with a single
click. Then press the \q{Save} button.
\lcont{
Note that PuTTY does not allow you to save a host name into the
Default Settings entry. This ensures that when PuTTY is started up,
the host name box is always empty, so a user can always just type in
a host name and connect.
}
If there is a specific host you want to store the details of how to
connect to, you should create a saved session, which will be
separate from the Default Settings.
@ -375,6 +368,19 @@ option, and things might go back to normal:
\c Second line
\c Third line
\S{config-lfcr} \q{Implicit LF in every CR}
\cfg{winhelp-topic}{terminal.crhaslf}
Most servers send two control characters, \i{CR} and \i{LF}, to start a
\i{new line} of the screen. The CR character makes the cursor return to the
left-hand side of the screen. The LF character makes the cursor move
one line down (and might make the screen scroll).
Some servers only send CR, and so the newly
written line is overwritten by the following line. This option causes
a line feed so that all lines are displayed.
\S{config-erase} \q{Use \i{background colour} to erase screen}
\cfg{winhelp-topic}{terminal.bce}
@ -1003,7 +1009,7 @@ The Window configuration panel allows you to control aspects of the
\cfg{winhelp-topic}{window.size}
The \q{\ii{Rows}} and \q{\ii{Columns}} boxes let you set the PuTTY
The \q{\ii{Columns}} and \q{\ii{Rows}} boxes let you set the PuTTY
window to a precise size. Of course you can also \I{window resizing}drag
the window to a new size while a session is running.
@ -1694,8 +1700,13 @@ TCP keepalives are disabled by default.
\cfg{winhelp-topic}{connection.ipversion}
This option allows the user to select between the old and new
Internet protocols and addressing schemes (\i{IPv4} and \i{IPv6}). The
default setting is \q{Auto}, which means PuTTY will do something
Internet protocols and addressing schemes (\i{IPv4} and \i{IPv6}).
The selected protocol will be used for most outgoing network
connections (including connections to \I{proxy}proxies); however,
tunnels have their own configuration, for which see
\k{config-ssh-portfwd-address-family}.
The default setting is \q{Auto}, which means PuTTY will do something
sensible and try to guess which protocol you wanted. (If you specify
a literal \i{Internet address}, it will use whichever protocol that
address implies. If you provide a \i{hostname}, it will see what kinds
@ -1808,6 +1819,11 @@ this panel affect the primary network connection forming your PuTTY
session, and also any extra connections made as a result of SSH \i{port
forwarding} (see \k{using-port-forwarding}).
Note that unlike some software (such as web browsers), PuTTY does not
attempt to automatically determine whether to use a proxy and (if so)
which one to use for a given destination. If you need to use a proxy,
it must always be explicitly configured.
\S{config-proxy-type} Setting the proxy type
\cfg{winhelp-topic}{proxy.type}
@ -2282,6 +2298,10 @@ exchange; the server can avoid groups known to be weak, and possibly
invent new ones over time, without any changes required to PuTTY's
configuration. We recommend use of this method, if possible.
In addition, PuTTY supports \i{RSA key exchange}, which requires much less
computational effort on the part of the client, and somewhat less on
the part of the server, than Diffie-Hellman key exchange.
If the first algorithm PuTTY finds is below the \q{warn below here}
line, you will see a warning box when you make the connection, similar
to that for cipher selection (see \k{config-ssh-encryption}).
@ -2404,11 +2424,12 @@ forms of simple \I{challenge/response authentication}challenge/response
authentication available in SSH protocol version 1 only. You might use
them if you were using \i{S/Key} \i{one-time passwords}, for example,
or if you had a physical \i{security token} that generated responses
to authentication challenges.
to authentication challenges. They can even be used to prompt for
simple passwords.
With this switch enabled, PuTTY will attempt these forms of
authentication if the server is willing to try them. You will be
presented with a challenge string (which will be different every
presented with a challenge string (which may be different every
time) and must supply the correct response in order to log in. If
your server supports this, you should talk to your system
administrator about precisely what form these challenges and
@ -2772,6 +2793,9 @@ incoming connections in both IPv4 and (if available) IPv6
\b for a remote-to-local port forwarding, PuTTY will choose a
sensible protocol for the outgoing connection.
This overrides the general Internet protocol version preference
on the Connection panel (see \k{config-address-family}).
Note that some operating systems may listen for incoming connections
in IPv4 even if you specifically asked for IPv6, because their IPv4
and IPv6 protocol stacks are linked together. Apparently \i{Linux} does
@ -2962,6 +2986,22 @@ would expect.
This is an SSH-2-specific bug.
\S{config-ssh-bug-maxpkt2} \q{Ignores SSH-2 \i{maximum packet size}}
\cfg{winhelp-topic}{ssh.bugs.maxpkt2}
When an SSH-2 channel is set up, each end announces the maximum size
of data packet that it is willing to receive for that channel. Some
servers ignore PuTTY's announcement and send packets larger than PuTTY
is willing to accept, causing it to report \q{Incoming packet was
garbled on decryption}.
If this bug is detected, PuTTY never allows the channel's
\i{flow-control window} to grow large enough to allow the server to
send an over-sized packet. If this bug is enabled when talking to a
correct server, the session will work correctly, but download
performance will be less than it could be.
\H{config-serial} The Serial panel
The \i{Serial} panel allows you to configure options that only apply
@ -2975,7 +3015,7 @@ The \q{Serial line to connect to} box allows you to choose which
serial line you want PuTTY to talk to, if your computer has more
than one serial port.
On Windows, the first serial line is called \cw{COM1}, and if there
On Windows, the first serial line is called \i\cw{COM1}, and if there
is a second it is called \cw{COM2}, and so on.
This configuration setting is also visible on the Session panel,

Просмотреть файл

@ -200,8 +200,15 @@ the various strategies we use for camouflaging passwords in transit.
Upgrade your server, or use the workarounds described in
\k{config-ssh-bug-ignore1} and possibly \k{config-ssh-bug-plainpw1}.
\H{errors-no-auth} \q{No supported authentication methods available}
This error indicates that PuTTY has run out of ways to authenticate
you to an SSH server. This may be because PuTTY has TIS or
keyboard-interactive authentication disabled, in which case
\k{config-ssh-tis} and \k{config-ssh-ki}.
\H{errors-crc} \q{Incorrect \i{CRC} received on packet} or \q{Incorrect
MAC received on packet}
\i{MAC} received on packet}
This error occurs when PuTTY decrypts an SSH packet and its checksum
is not correct. This probably means something has gone wrong in the
@ -209,6 +216,14 @@ encryption or decryption process. It's difficult to tell from this
error message whether the problem is in the client, in the server,
or in between.
In particular, if the network is corrupting data at the TCP level, it
may only be obvious with cryptographic protocols such as SSH, which
explicitly check the integrity of the transferred data and complain
loudly if the checks fail. Corruption of protocols without integrity
protection (such as HTTP) will manifest in more subtle failures (such
as misdisplayed text or images in a web browser) which may not be
noticed.
A known server problem which can cause this error is described in
\k{faq-openssh-bad-openssl} in the FAQ.
@ -220,9 +235,10 @@ gone wrong in the encryption or decryption process. It's difficult
to tell from this error message whether the problem is in the client,
in the server, or in between.
If you get this error, one thing you could try would be to fiddle
with the setting of \q{Miscomputes SSH-2 encryption keys} on the Bugs
panel (see \k{config-ssh-bug-derivekey2}).
If you get this error, one thing you could try would be to fiddle with
the setting of \q{Miscomputes SSH-2 encryption keys} (see
\k{config-ssh-bug-derivekey2}) or \q{Ignores SSH-2 maximum packet
size} (see \k{config-ssh-bug-maxpkt2}) on the Bugs panel .
Another known server problem which can cause this error is described
in \k{faq-openssh-bad-openssl} in the FAQ.

Просмотреть файл

@ -161,7 +161,7 @@ completely is the wrong solution and we will not do it.
If you have host keys available in the common \i\c{known_hosts} format,
we have a script called
\W{http://www.tartarus.org/~simon-anonsvn/viewcvs.cgi/putty/contrib/kh2reg.py?view=markup}\c{kh2reg.py}
\W{http://svn.tartarus.org/putty/contrib/kh2reg.py?view=markup}\c{kh2reg.py}
to convert them to a Windows .REG file, which can be installed ahead of
time by double-clicking or using \c{REGEDIT}.
@ -1133,8 +1133,9 @@ link to you at all.
If you have software based on PuTTY, or specifically designed to
interoperate with PuTTY, or in some other way of genuine interest to
PuTTY users, then we will probably be happy to add a link to you on
our Links page. And if you're running a mirror of the PuTTY web
site, we're \e{definitely} interested.
our Links page. And if you're running a particularly valuable mirror
of the PuTTY web site, we might be interested in linking to you from
our Mirrors page.
\S{faq-sourceforge}{Question} Why don't you move PuTTY to
SourceForge?
@ -1191,11 +1192,8 @@ asking for any.
Having said all that, if you still really \e{want} to give us money,
we won't argue :-) The easiest way for us to accept donations is if
you send money to \cw{<anakin@pobox.com>} using PayPal
(\W{http://www.paypal.com/}\cw{www.paypal.com}). Alternatively, if
you don't trust PayPal, you could donate through e-gold
(\W{http://www.e-gold.com}\cw{www.e-gold.com}): deposit your
donation in account number 174769, then send us e-mail to let us
know you've done so (otherwise we might not notice for months!).
(\W{http://www.paypal.com/}\cw{www.paypal.com}). If you don't like
PayPal, talk to us; we can probably arrange some alternative means.
Small donations (tens of dollars or tens of euros) will probably be
spent on beer or curry, which helps motivate our volunteer team to

Просмотреть файл

@ -375,18 +375,27 @@ clear that we \e{could} stop you doing this, even if we wanted to!)
\H{feedback-mirrors} Mirroring the PuTTY web site
\#{This paragraph also in putty-website/mirrors.html}
Mirrors of the PuTTY web site are welcome, especially in regions not
well covered by existing mirrors. (However, if you're in a region that is
already well served by mirrors, you should consider whether yet another one
will be worth the effort.) Please don't bother asking us for permission before
\# the next two paragraphs also on the Mirrors page itself, with
\# minor context changes
If you want to set up a mirror of the PuTTY website, go ahead and
set one up. Please don't bother asking us for permission before
setting up a mirror. You already have permission.
If you mail us \e{after} you have set up the mirror and checked that
it works, and remember to let us know which country your mirror is in,
then we'll add it to the
\W{http://www.chiark.greenend.org.uk/~sgtatham/putty/mirrors.html}{Mirrors
page} on the PuTTY website.
If the mirror is in a country where we don't already have plenty of
mirrors, we may be willing to add it to the list on our
\W{http://www.chiark.greenend.org.uk/~sgtatham/putty/mirrors.html}{mirrors
page}. Read the guidelines on that page, make sure your mirror
works, and email us the information listed at the bottom of the
page.
Note that we do not \e{promise} to list your mirror: we get a lot of
mirror notifications and yours may not happen to find its way to the
top of the list.
Also note that we link to all our mirror sites using the
\c{rel="nofollow"} attribute. Running a PuTTY mirror is not intended
to be a cheap way to gain search rankings.
If you have technical questions about the process of mirroring, then
you might want to mail us before setting up the mirror (see also the

Просмотреть файл

@ -672,8 +672,8 @@ saved sessions from
\IM{ignore message} SSH \q{ignore} messages
\IM{ignore message} \q{ignore} messages, in SSH
\IM{message authentication code} message authentication code
\IM{message authentication code} MAC (message authentication code)
\IM{message authentication code}{MAC} message authentication code (MAC)
\IM{message authentication code}{MAC} MAC (message authentication code)
\IM{signatures} signature
\IM{signatures} digital signature

Просмотреть файл

@ -2,7 +2,7 @@
\A{licence} PuTTY \ii{Licence}
PuTTY is \i{copyright} 1997-2007 Simon Tatham.
PuTTY is \i{copyright} 1997-2008 Simon Tatham.
Portions copyright Robert de Bath, Joris van Rantwijk, Delian
Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,

Просмотреть файл

@ -43,7 +43,7 @@ use Plink:
\c Z:\sysosd>plink
\c PuTTY Link: command-line connection utility
\c Release 0.59
\c Release 0.60
\c Usage: plink [options] [user@]host [command]
\c ("host" can also be a PuTTY saved session name)
\c Options:

Просмотреть файл

@ -41,7 +41,7 @@ use PSCP:
\c Z:\owendadmin>pscp
\c PuTTY Secure Copy client
\c Release 0.59
\c Release 0.60
\c Usage: pscp [options] [user@]host:source target
\c pscp [options] source [source...] [user@]host:target
\c pscp [options] -ls [user@]host:filespec

77
doc/sshnames.but Normal file
Просмотреть файл

@ -0,0 +1,77 @@
\define{versionidsshnames} \versionid $Id$
\A{sshnames} SSH-2 names specified for PuTTY
There are various parts of the SSH-2 protocol where things are specified
using a textual name. Names ending in \cw{@putty.projects.tartarus.org}
are reserved for allocation by the PuTTY team. Allocated names are
documented here.
\H{sshnames-global} Connection protocol global request name
This name can be sent in a \cw{SSH_MSG_GLOBAL_REQUEST} message.
\dt \cw{simple@putty.projects.tartarus.org}
\dd This is sent by a client to announce that it will not have more that
one channel open at a time in the current connection. The intention
is that the server, knowing this, can set the window on that one
channel to something very large, and leave flow control to TCP. The
format of the request is:
\lcont{
\c byte SSH_MSG_GLOBAL_REQUEST
\c uint32 recipient channel
\c string "simple@putty.projects.tartarus.org"
\c boolean want reply
}
\H{sshnames-channel} Connection protocol channel request name
This name can be sent in a \cw{SSH_MSG_CHANNEL_REQUEST} message.
\dt \cw{winadj@putty.projects.tartarus.org}
\dd PuTTY sends this request along with some
\cw{SSH_MSG_CHANNEL_WINDOW_ADJUST} messages as part of its window-size
tuning. It can be sent on any type of channel. Servers MUST treat it
as an unrecognised request and respond with
\cw{SSH_MSG_CHANNEL_FAILURE}.
\H{sshnames-kex} Key exchange method names
\dt \cw{rsa-sha1-draft-00@putty.projects.tartarus.org}
\dt \cw{rsa-sha256-draft-00@putty.projects.tartarus.org}
\dt \cw{rsa1024-sha1-draft-01@putty.projects.tartarus.org}
\dt \cw{rsa1024-sha256-draft-01@putty.projects.tartarus.org}
\dt \cw{rsa2048-sha256-draft-01@putty.projects.tartarus.org}
\dt \cw{rsa1024-sha1-draft-02@putty.projects.tartarus.org}
\dt \cw{rsa2048-sha512-draft-02@putty.projects.tartarus.org}
\dt \cw{rsa1024-sha1-draft-03@putty.projects.tartarus.org}
\dt \cw{rsa2048-sha256-draft-03@putty.projects.tartarus.org}
\dt \cw{rsa1024-sha1-draft-04@putty.projects.tartarus.org}
\dt \cw{rsa2048-sha256-draft-04@putty.projects.tartarus.org}
\dd These appeared in various drafts of what eventually became RFC\_4432.
They have been superseded by \cw{rsa1024-sha1} and \cw{rsa2048-sha256}.
\H{sshnames-encrypt} Encryption algorithm names
\dt \cw{arcfour128-draft-00@putty.projects.tartarus.org}
\dt \cw{arcfour256-draft-00@putty.projects.tartarus.org}
\dd These were used in drafts of what eventually became RFC\_4345.
They have been superseded by \cw{arcfour128} and \cw{arcfour256}.

Просмотреть файл

@ -128,6 +128,9 @@ connection in addition to normal data. Their precise effect is usually
up to the server. Currently only Telnet, SSH, and serial connections
have special commands.
The \q{break} signal can also be invoked from the keyboard with
\i{Ctrl-Break}.
The following \I{Telnet special commands}special commands are
available in Telnet:
@ -335,7 +338,7 @@ doesn't, the manual for the \i{X server} should tell you what it
does do.
You should then tick the \q{Enable X11 forwarding} box in the
Tunnels panel (see \k{config-ssh-x11}) before starting your SSH
X11 panel (see \k{config-ssh-x11}) before starting your SSH
session. The \i{\q{X display location}} box is blank by default, which
means that PuTTY will try to use a sensible default such as \c{:0},
which is the usual display location where your X server will be
@ -464,6 +467,9 @@ theory but servers will not necessarily cooperate.
to obtain a fix from Microsoft in order to use addresses like
\cw{127.0.0.5} - see \k{faq-alternate-localhost}.)
For more options relating to port forwarding, see
\k{config-ssh-portfwd}.
\H{using-rawprot} Making \i{raw TCP connections}
A lot of \I{debugging Internet protocols}Internet protocols are
@ -762,8 +768,7 @@ it off. These options are only meaningful if you are using SSH.
For information on X11 forwarding, see \k{using-x-forwarding}.
These options are equivalent to the X11 forwarding checkbox in the
Tunnels panel of the PuTTY configuration box (see
\k{config-ssh-x11}).
X11 panel of the PuTTY configuration box (see \k{config-ssh-x11}).
These options are not available in the file transfer tools PSCP and
PSFTP.
@ -865,7 +870,8 @@ PuTTY configuration box (see \k{config-ssh-prot}).
\i{Internet protocol version}
The \c{-4} and \c{-6} options force PuTTY to use the older Internet
protocol \i{IPv4} or the newer \i{IPv6}.
protocol \i{IPv4} or the newer \i{IPv6} for most outgoing
connections.
These options are equivalent to selecting your preferred Internet
protocol version as \q{IPv4} or \q{IPv6} in the Connection panel of

Просмотреть файл

@ -1,6 +1,6 @@
# Makefile for the PuTTY icon suite.
ICONS = putty puttycfg puttygen pscp pageant pterm ptermcfg installer
ICONS = putty puttycfg puttygen pscp pageant pterm ptermcfg puttyins
SIZES = 16 32 48
MODE = # override to -it on command line for opaque testing
@ -10,7 +10,7 @@ MONOPNGS = $(foreach I,$(ICONS),$(foreach S,$(SIZES),$(I)-$(S)-mono.png))
TRUEPNGS = $(foreach I,$(ICONS),$(foreach S,$(SIZES),$(I)-$(S)-true.png))
ICOS = putty.ico puttygen.ico pscp.ico pageant.ico pageants.ico puttycfg.ico \
installer.ico
puttyins.ico
CICONS = xpmputty.c xpmpucfg.c xpmpterm.c xpmptcfg.c
base: icos cicons
@ -63,11 +63,11 @@ pscp.ico: pscp-16.png pscp-32.png pscp-48.png \
# Because the installer icon makes heavy use of brown when drawing
# the cardboard box, it's worth having 8-bit versions of it in
# addition to the 4- and 1-bit ones.
installer.ico: installer-16.png installer-32.png installer-48.png \
installer-16-mono.png installer-32-mono.png \
installer-48-mono.png \
installer-16-true.png installer-32-true.png \
installer-48-true.png
puttyins.ico: puttyins-16.png puttyins-32.png puttyins-48.png \
puttyins-16-mono.png puttyins-32-mono.png \
puttyins-48-mono.png \
puttyins-16-true.png puttyins-32-true.png \
puttyins-48-true.png
./icon.pl -8 $(filter %-true.png, $^) \
-4 $(filter-out %-true.png, $(filter-out %-mono.png, $^)) \
-1 $(filter %-mono.png, $^) > $@

Просмотреть файл

@ -795,7 +795,7 @@ def puttygen_icon(size):
def pscp_icon(size):
return xybolt(document(size), computer(size), size)
def installer_icon(size):
def puttyins_icon(size):
aret = {}
# The box back goes behind the lightning bolt.
canvas = xybolt(boxback(size), computer(size), size, boltoffx=-2, boltoffy=+1, aux=aret)

Просмотреть файл

@ -210,13 +210,10 @@ static void mac_startup(void) {
default_protocol = be_default_protocol;
/* Find the appropriate default port. */
{
int i;
Backend *b = backend_from_proto(default_protocol);
default_port = 0; /* illegal */
for (i = 0; backends[i].backend != NULL; i++)
if (backends[i].protocol == default_protocol) {
default_port = backends[i].backend->default_port;
break;
}
if (b)
default_port = b->default_port;
}
flags = FLAG_INTERACTIVE;

Просмотреть файл

@ -1221,7 +1221,7 @@ resource 'DITL' (wAbout, "about", purgeable) {
StaticText { disabled, "PuTTY"},
{ 42, 13, 74, 227 },
StaticText { disabled, "Some version or other\n"
"Copyright © 1997-2007 Simon Tatham"},
"Copyright © 1997-2008 Simon Tatham"},
}
};
@ -1242,7 +1242,7 @@ type 'TEXT' {
};
resource 'TEXT' (wLicence, "licence", purgeable) {
"PuTTY is copyright 1997-2007 Simon Tatham.\n"
"PuTTY is copyright 1997-2008 Simon Tatham.\n"
"\n"
"Portions copyright Robert de Bath, Joris van Rantwijk, Delian "
"Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry, "

Просмотреть файл

@ -237,7 +237,7 @@ static OSErr mac_opensessionfrom(FSSpec *fss)
err = -9999;
goto fail;
}
load_open_settings(sesshandle, TRUE, &s->cfg);
load_open_settings(sesshandle, &s->cfg);
close_settings_r(sesshandle);
mac_startsession(s);
@ -321,7 +321,7 @@ void mac_savesession(void)
assert(s->hasfile);
sesshandle = open_settings_w_fsp(&s->savefile);
if (sesshandle == NULL) return; /* XXX report error */
save_open_settings(sesshandle, TRUE, &s->cfg);
save_open_settings(sesshandle, &s->cfg);
close_settings_w(sesshandle);
}
@ -342,7 +342,7 @@ void mac_savesessionas(void)
}
sesshandle = open_settings_w_fsp(&sfr.sfFile);
if (sesshandle == NULL) return; /* XXX report error */
save_open_settings(sesshandle, TRUE, &s->cfg);
save_open_settings(sesshandle, &s->cfg);
close_settings_w(sesshandle);
s->hasfile = TRUE;
s->savefile = sfr.sfFile;

Просмотреть файл

@ -422,7 +422,7 @@ resource 'DITL' (wAbout, "about", purgeable) {
StaticText { disabled, "PuTTYgen"},
{ 42, 13, 74, 227 },
StaticText { disabled, "Some version or other\n"
"Copyright © 1997-2007 Simon Tatham"},
"Copyright © 1997-2008 Simon Tatham"},
}
};
@ -443,7 +443,7 @@ type 'TEXT' {
};
resource 'TEXT' (wLicence, "licence", purgeable) {
"Copyright 1997-2007 Simon Tatham.\n"
"Copyright 1997-2008 Simon Tatham.\n"
"\n"
"Portions copyright Robert de Bath, Joris van Rantwijk, Delian "
"Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry, "

Просмотреть файл

@ -115,12 +115,7 @@ void mac_startsession(Session *s)
* Select protocol. This is farmed out into a table in a
* separate file to enable an ssh-free variant.
*/
s->back = NULL;
for (i = 0; backends[i].backend != NULL; i++)
if (backends[i].protocol == s->cfg.protocol) {
s->back = backends[i].backend;
break;
}
s->back = backend_from_proto(s->cfg.protocol);
if (s->back == NULL)
fatalbox("Unsupported protocol number found");

Просмотреть файл

@ -2,7 +2,7 @@
* Current PuTTY version number. Minor is in BCD
*/
#define VERSION_MAJOR 0x00
#define VERSION_MINOR 0x59
#define VERSION_MINOR 0x60
resource 'vers' (1, purgeable) {
#ifdef RELEASE

Просмотреть файл

@ -64,10 +64,12 @@ struct alert_queue {
- (void)doText:(wchar_t *)text len:(int)len x:(int)x y:(int)y
attr:(unsigned long)attr lattr:(int)lattr;
- (int)fromBackend:(const char *)data len:(int)len isStderr:(int)is_stderr;
- (int)fromBackendUntrusted:(const char *)data len:(int)len;
- (void)startAlert:(NSAlert *)alert
withCallback:(void (*)(void *, int))callback andCtx:(void *)ctx;
- (void)endSession:(int)clean;
- (void)notifyRemoteExit;
- (Terminal *)term;
@end
/*

Просмотреть файл

@ -126,7 +126,7 @@
ctrlbox = ctrl_new_box();
setup_config_box(ctrlbox, FALSE /*midsession*/, aCfg.protocol,
0 /* protcfginfo */);
unix_setup_config_box(ctrlbox, FALSE /*midsession*/);
unix_setup_config_box(ctrlbox, FALSE /*midsession*/, aCfg.protocol);
cfg = aCfg; /* structure copy */

Просмотреть файл

@ -232,15 +232,9 @@
/*
* Set up a backend.
*/
{
int i;
back = backend_from_proto(cfg.protocol);
if (!back)
back = &pty_backend;
for (i = 0; backends[i].backend != NULL; i++)
if (backends[i].protocol == cfg.protocol) {
back = backends[i].backend;
break;
}
}
{
const char *error;
@ -794,6 +788,11 @@
return term_data(term, is_stderr, data, len);
}
- (int)fromBackendUntrusted:(const char *)data len:(int)len
{
return term_data_untrusted(term, data, len);
}
- (void)startAlert:(NSAlert *)alert
withCallback:(void (*)(void *, int))callback andCtx:(void *)ctx
{
@ -885,6 +884,11 @@
// FIXME: else show restart menu item
}
- (Terminal *)term
{
return term;
}
@end
int from_backend(void *frontend, int is_stderr, const char *data, int len)
@ -893,6 +897,12 @@ int from_backend(void *frontend, int is_stderr, const char *data, int len)
return [win fromBackend:data len:len isStderr:is_stderr];
}
int from_backend_untrusted(void *frontend, const char *data, int len)
{
SessionWindow *win = (SessionWindow *)frontend;
return [win fromBackendUntrusted:data len:len];
}
int get_userpass_input(prompts_t *p, unsigned char *in, int inlen)
{
SessionWindow *win = (SessionWindow *)p->frontend;
@ -922,7 +932,7 @@ void ldisc_update(void *frontend, int echo, int edit)
char *get_ttymode(void *frontend, const char *mode)
{
SessionWindow *win = (SessionWindow *)ctx;
SessionWindow *win = (SessionWindow *)frontend;
Terminal *term = [win term];
return term_get_ttymode(term, mode);
}

Просмотреть файл

@ -429,7 +429,7 @@ if (defined $makefiles{'cygwin'}) {
if ($d->{obj} =~ /\.res\.o$/) {
print "\t\$(RC) \$(RCFL) \$(RCFLAGS) ".$d->{deps}->[0]." ".$d->{obj}."\n\n";
} else {
print "\t\$(CC) \$(COMPAT) \$(XFLAGS) \$(CFLAGS) -c ".$d->{deps}->[0]."\n\n";
print "\t\$(CC) \$(COMPAT) \$(CFLAGS) \$(XFLAGS) -c ".$d->{deps}->[0]."\n\n";
}
}
print "\n";
@ -486,7 +486,7 @@ if (defined $makefiles{'borland'}) {
"\n".
".c.obj:\n".
&splitline("\tbcc32 -w-aus -w-ccc -w-par -w-pia \$(COMPAT)".
" \$(XFLAGS) \$(CFLAGS) ".
" \$(CFLAGS) \$(XFLAGS) ".
(join " ", map {"-I$dirpfx$_"} @srcdirs) .
" /c \$*.c",69)."\n".
".rc.res:\n".
@ -615,7 +615,7 @@ if (defined $makefiles{'vc'}) {
print &splitline(sprintf("%s: %s", $d->{obj},
join " ", @$extradeps, @{$d->{deps}})), "\n";
if ($d->{obj} =~ /.obj$/) {
print "\tcl \$(COMPAT) \$(XFLAGS) \$(CFLAGS) /c ".$d->{deps}->[0],"\n\n";
print "\tcl \$(COMPAT) \$(CFLAGS) \$(XFLAGS) /c ".$d->{deps}->[0],"\n\n";
} else {
print "\trc \$(RCFL) -r \$(RCFLAGS) ".$d->{deps}->[0],"\n\n";
}
@ -935,8 +935,8 @@ if (defined $makefiles{'gtk'}) {
(join " ", map {"-I$dirpfx$_"} @srcdirs) .
" `\$(GTK_CONFIG) --cflags`").
" -D _FILE_OFFSET_BITS=64\n".
"XLDFLAGS = `\$(GTK_CONFIG) --libs`\n".
"ULDFLAGS =#\n".
"XLDFLAGS = \$(LDFLAGS) `\$(GTK_CONFIG) --libs`\n".
"ULDFLAGS = \$(LDFLAGS)\n".
"INSTALL=install\n",
"INSTALL_PROGRAM=\$(INSTALL)\n",
"INSTALL_DATA=\$(INSTALL)\n",
@ -958,8 +958,8 @@ if (defined $makefiles{'gtk'}) {
$objstr = &objects($p, "X.o", undef, undef);
print &splitline($prog . ": " . $objstr), "\n";
$libstr = &objects($p, undef, undef, "-lX");
print &splitline("\t\$(CC)" . $mw . " \$(${type}LDFLAGS) -o \$@ " .
$objstr . " $libstr", 69), "\n\n";
print &splitline("\t\$(CC)" . $mw . " -o \$@ " .
$objstr . " \$(${type}LDFLAGS) $libstr", 69), "\n\n";
}
foreach $d (&deps("X.o", undef, $dirpfx, "/", "gtk")) {
if ($forceobj{$d->{obj_orig}}) {
@ -968,7 +968,7 @@ if (defined $makefiles{'gtk'}) {
print &splitline(sprintf("%s: %s", $d->{obj},
join " ", @{$d->{deps}})), "\n";
}
print &splitline("\t\$(CC) \$(COMPAT) \$(XFLAGS) \$(CFLAGS) -c $d->{deps}->[0]\n");
print &splitline("\t\$(CC) \$(COMPAT) \$(CFLAGS) \$(XFLAGS) -c $d->{deps}->[0]\n");
}
print "\n";
print $makefile_extra{'gtk'}->{'end'};
@ -1021,8 +1021,8 @@ if (defined $makefiles{'ac'}) {
$objstr = &objects($p, "X.o", undef, undef);
print &splitline($prog . ": " . $objstr), "\n";
$libstr = &objects($p, undef, undef, "-lX");
print &splitline("\t\$(CC)" . $mw . " \$(${type}LDFLAGS) -o \$@ " .
$objstr . " $libstr", 69), "\n\n";
print &splitline("\t\$(CC)" . $mw . " -o \$@ " .
$objstr . " \$(${type}LDFLAGS) $libstr", 69), "\n\n";
}
foreach $d (&deps("X.o", undef, $dirpfx, "/", "gtk")) {
if ($forceobj{$d->{obj_orig}}) {
@ -1031,7 +1031,7 @@ if (defined $makefiles{'ac'}) {
print &splitline(sprintf("%s: %s", $d->{obj},
join " ", @{$d->{deps}})), "\n";
}
print &splitline("\t\$(CC) \$(COMPAT) \$(XFLAGS) \$(CFLAGS) -c $d->{deps}->[0]\n");
print &splitline("\t\$(CC) \$(COMPAT) \$(CFLAGS) \$(XFLAGS) -c $d->{deps}->[0]\n");
}
print "\n";
print $makefile_extra{'gtk'}->{'end'};
@ -1232,7 +1232,7 @@ if (defined $makefiles{'lcc'}) {
}
if ($d->{obj} =~ /\.obj$/) {
print &splitline("\tlcc -O -p6 \$(COMPAT)".
" \$(XFLAGS) \$(CFLAGS) ".$d->{deps}->[0],69)."\n";
" \$(CFLAGS) \$(XFLAGS) ".$d->{deps}->[0],69)."\n";
} else {
print &splitline("\tlrc \$(RCFL) -r \$(RCFLAGS) ".
$d->{deps}->[0],69)."\n";
@ -1317,9 +1317,9 @@ if (defined $makefiles{'osx'}) {
}
$firstdep = $d->{deps}->[0];
if ($firstdep =~ /\.c$/) {
print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) -c \$<\n";
print "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS) -c \$<\n";
} elsif ($firstdep =~ /\.m$/) {
print "\t\$(CC) -x objective-c \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) -c \$<\n";
print "\t\$(CC) -x objective-c \$(COMPAT) \$(FWHACK) \$(CFLAGS) \$(XFLAGS) -c \$<\n";
}
}
print "\n".$makefile_extra{'osx'}->{'end'};

Просмотреть файл

@ -4,7 +4,8 @@
#
# Pass an argument of the form `2004-02-08' to have the archive
# tagged as a development snapshot; of the form `0.54' to have it
# tagged as a release.
# tagged as a release; of the form `r1234' to have it tagged as a
# custom build. Otherwise it'll be tagged as unidentified.
case "$1" in
????-??-??)
@ -13,6 +14,11 @@ case "$1" in
ver="-DSNAPSHOT=$1"
docver=
;;
r*)
arcsuffix="-$1"
ver="-DSVN_REV=$1"
docver=
;;
'')
arcsuffix=
ver=

7
pscp.c
Просмотреть файл

@ -180,12 +180,6 @@ int from_backend(void *frontend, int is_stderr, const char *data, int datalen)
return 0;
}
/*
* If this is before the real session begins, just return.
*/
if (!outptr)
return 0;
if ((outlen > 0) && (len > 0)) {
unsigned used = outlen;
if (used > len)
@ -424,6 +418,7 @@ static void do_cmd(char *host, char *user, char *cmd)
cfg.x11_forward = 0;
cfg.agentfwd = 0;
cfg.portfwd[0] = cfg.portfwd[1] = '\0';
cfg.ssh_simple = TRUE;
/*
* Set up main and possibly fallback command depending on

70
psftp.c
Просмотреть файл

@ -321,22 +321,24 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart)
* If none of them exists, of course, we start at 0.
*/
i = 0;
while (i < nnames) {
char *nextoutfname;
int ret;
if (outfname)
nextoutfname = dir_file_cat(outfname,
ournames[i]->filename);
else
nextoutfname = dupstr(ournames[i]->filename);
ret = (file_type(nextoutfname) == FILE_TYPE_NONEXISTENT);
sfree(nextoutfname);
if (ret)
break;
i++;
}
if (i > 0)
i--;
if (restart) {
while (i < nnames) {
char *nextoutfname;
int ret;
if (outfname)
nextoutfname = dir_file_cat(outfname,
ournames[i]->filename);
else
nextoutfname = dupstr(ournames[i]->filename);
ret = (file_type(nextoutfname) == FILE_TYPE_NONEXISTENT);
sfree(nextoutfname);
if (ret)
break;
i++;
}
if (i > 0)
i--;
}
/*
* Now we're ready to recurse. Starting at ournames[i]
@ -461,6 +463,7 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart)
printf("error while writing local file\n");
ret = 0;
xfer_set_error(xfer);
break;
}
wpos += wlen;
}
@ -568,23 +571,25 @@ int sftp_put_file(char *fname, char *outfname, int recurse, int restart)
* If none of them exists, of course, we start at 0.
*/
i = 0;
while (i < nnames) {
char *nextoutfname;
nextoutfname = dupcat(outfname, "/", ournames[i], NULL);
sftp_register(req = fxp_stat_send(nextoutfname));
rreq = sftp_find_request(pktin = sftp_recv());
assert(rreq == req);
result = fxp_stat_recv(pktin, rreq, &attrs);
sfree(nextoutfname);
if (!result)
break;
i++;
}
if (i > 0)
i--;
if (restart) {
while (i < nnames) {
char *nextoutfname;
nextoutfname = dupcat(outfname, "/", ournames[i], NULL);
sftp_register(req = fxp_stat_send(nextoutfname));
rreq = sftp_find_request(pktin = sftp_recv());
assert(rreq == req);
result = fxp_stat_recv(pktin, rreq, &attrs);
sfree(nextoutfname);
if (!result)
break;
i++;
}
if (i > 0)
i--;
}
/*
* Now we're ready to recurse. Starting at ournames[i]
/*
* Now we're ready to recurse. Starting at ournames[i]
* and continuing on to the end of the list, we
* construct a new source and target file name, and
* call sftp_put_file again.
@ -2747,6 +2752,7 @@ static int psftp_connect(char *userhost, char *user, int portnumber)
cfg.x11_forward = 0;
cfg.agentfwd = 0;
cfg.portfwd[0] = cfg.portfwd[1] = '\0';
cfg.ssh_simple = TRUE;
/* Set up subsystem name. */
strcpy(cfg.remote_cmd, "sftp");

28
putty.h
Просмотреть файл

@ -252,6 +252,7 @@ enum {
KEX_DHGROUP1,
KEX_DHGROUP14,
KEX_DHGEX,
KEX_RSA,
KEX_MAX
};
@ -388,14 +389,12 @@ struct backend_tag {
*/
void (*unthrottle) (void *handle, int);
int (*cfg_info) (void *handle);
char *name;
int protocol;
int default_port;
};
extern struct backend_list {
int protocol;
char *name;
Backend *backend;
} backends[];
extern Backend *backends[];
/*
* Suggested default protocol provided by the backend link module.
@ -588,7 +587,13 @@ struct config_tag {
/* SSH bug compatibility modes */
int sshbug_ignore1, sshbug_plainpw1, sshbug_rsa1,
sshbug_hmac2, sshbug_derivekey2, sshbug_rsapad2,
sshbug_pksessid2, sshbug_rekey2;
sshbug_pksessid2, sshbug_rekey2, sshbug_maxpkt2;
/*
* ssh_simple means that we promise never to open any channel other
* than the main one, which means it can safely use a very large
* window in SSH-2.
*/
int ssh_simple;
/* Options for pterm. Should split out into platform-dependent part. */
int stamp_utmp;
int login_shell;
@ -598,6 +603,7 @@ struct config_tag {
FontSpec widefont;
FontSpec wideboldfont;
int shadowboldoffset;
int crhaslf;
};
/*
@ -777,10 +783,12 @@ void random_destroy_seed(void);
/*
* Exports from settings.c.
*/
char *save_settings(char *section, int do_host, Config * cfg);
void save_open_settings(void *sesskey, int do_host, Config *cfg);
void load_settings(char *section, int do_host, Config * cfg);
void load_open_settings(void *sesskey, int do_host, Config *cfg);
Backend *backend_from_name(const char *name);
Backend *backend_from_proto(int proto);
char *save_settings(char *section, Config * cfg);
void save_open_settings(void *sesskey, Config *cfg);
void load_settings(char *section, Config * cfg);
void load_open_settings(void *sesskey, Config *cfg);
void get_sesslist(struct sesslist *, int allocate);
void do_defaults(char *, Config *);
void registry_cleanup(void);

4
raw.c
Просмотреть файл

@ -278,5 +278,7 @@ Backend raw_backend = {
raw_provide_logctx,
raw_unthrottle,
raw_cfg_info,
1
"raw",
PROT_RAW,
0
};

Просмотреть файл

@ -349,5 +349,7 @@ Backend rlogin_backend = {
rlogin_provide_logctx,
rlogin_unthrottle,
rlogin_cfg_info,
1
"rlogin",
PROT_RLOGIN,
513
};

Просмотреть файл

@ -104,16 +104,18 @@ void ser_setup_config_box(struct controlbox *b, int midsession,
struct controlset *s;
union control *c;
/*
* Add the serial back end to the protocols list at the top of
* the config box.
*/
s = ctrl_getset(b, "Session", "hostport",
"Specify your connection by host name or IP address");
{
if (!midsession) {
int i;
extern void config_protocolbuttons_handler(union control *, void *,
void *, int);
/*
* Add the serial back end to the protocols list at the
* top of the config box.
*/
s = ctrl_getset(b, "Session", "hostport",
"Specify the destination you want to connect to");
for (i = 0; i < s->ncontrols; i++) {
c = s->ctrls[i];
if (c->generic.type == CTRL_RADIO &&

Просмотреть файл

@ -27,6 +27,7 @@ static const struct keyval kexnames[] = {
{ "dh-gex-sha1", KEX_DHGEX },
{ "dh-group14-sha1", KEX_DHGROUP14 },
{ "dh-group1-sha1", KEX_DHGROUP1 },
{ "rsa", KEX_RSA },
{ "WARN", KEX_WARN }
};
@ -51,6 +52,29 @@ const char *const ttymodes[] = {
"CS8", "PARENB", "PARODD", NULL
};
/*
* Convenience functions to access the backends[] array
* (which is only present in tools that manage settings).
*/
Backend *backend_from_name(const char *name)
{
Backend **p;
for (p = backends; *p != NULL; p++)
if (!strcmp((*p)->name, name))
return *p;
return NULL;
}
Backend *backend_from_proto(int proto)
{
Backend **p;
for (p = backends; *p != NULL; p++)
if ((*p)->protocol == proto)
return *p;
return NULL;
}
static void gpps(void *handle, const char *name, const char *def,
char *val, int len)
{
@ -231,7 +255,7 @@ static void wprefs(void *sesskey, char *name,
write_setting_s(sesskey, name, buf);
}
char *save_settings(char *section, int do_host, Config * cfg)
char *save_settings(char *section, Config * cfg)
{
void *sesskey;
char *errmsg;
@ -239,20 +263,18 @@ char *save_settings(char *section, int do_host, Config * cfg)
sesskey = open_settings_w(section, &errmsg);
if (!sesskey)
return errmsg;
save_open_settings(sesskey, do_host, cfg);
save_open_settings(sesskey, cfg);
close_settings_w(sesskey);
return NULL;
}
void save_open_settings(void *sesskey, int do_host, Config *cfg)
void save_open_settings(void *sesskey, Config *cfg)
{
int i;
char *p;
write_setting_i(sesskey, "Present", 1);
if (do_host) {
write_setting_s(sesskey, "HostName", cfg->host);
}
write_setting_s(sesskey, "HostName", cfg->host);
write_setting_filename(sesskey, "LogFileName", cfg->logfilename);
write_setting_i(sesskey, "LogType", cfg->logtype);
write_setting_i(sesskey, "LogFileClash", cfg->logxfovr);
@ -260,11 +282,11 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg)
write_setting_i(sesskey, "SSHLogOmitPasswords", cfg->logomitpass);
write_setting_i(sesskey, "SSHLogOmitData", cfg->logomitdata);
p = "raw";
for (i = 0; backends[i].name != NULL; i++)
if (backends[i].protocol == cfg->protocol) {
p = backends[i].name;
break;
}
{
const Backend *b = backend_from_proto(cfg->protocol);
if (b)
p = b->name;
}
write_setting_s(sesskey, "Protocol", p);
write_setting_i(sesskey, "PortNumber", cfg->port);
/* The CloseOnExit numbers are arranged in a different order from
@ -366,6 +388,7 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg)
write_setting_i(sesskey, "DECOriginMode", cfg->dec_om);
write_setting_i(sesskey, "AutoWrapMode", cfg->wrap_mode);
write_setting_i(sesskey, "LFImpliesCR", cfg->lfhascr);
write_setting_i(sesskey, "CRImpliesLF", cfg->crhaslf);
write_setting_i(sesskey, "DisableArabicShaping", cfg->arabicshaping);
write_setting_i(sesskey, "DisableBidi", cfg->bidi);
write_setting_i(sesskey, "WinNameAlways", cfg->win_name_always);
@ -431,6 +454,7 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg)
write_setting_i(sesskey, "BugRSAPad2", 2-cfg->sshbug_rsapad2);
write_setting_i(sesskey, "BugPKSessID2", 2-cfg->sshbug_pksessid2);
write_setting_i(sesskey, "BugRekey2", 2-cfg->sshbug_rekey2);
write_setting_i(sesskey, "BugMaxPkt2", 2-cfg->sshbug_maxpkt2);
write_setting_i(sesskey, "StampUtmp", cfg->stamp_utmp);
write_setting_i(sesskey, "LoginShell", cfg->login_shell);
write_setting_i(sesskey, "ScrollbarOnLeft", cfg->scrollbar_on_left);
@ -447,16 +471,16 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg)
write_setting_i(sesskey, "SerialFlowControl", cfg->serflow);
}
void load_settings(char *section, int do_host, Config * cfg)
void load_settings(char *section, Config * cfg)
{
void *sesskey;
sesskey = open_settings_r(section);
load_open_settings(sesskey, do_host, cfg);
load_open_settings(sesskey, cfg);
close_settings_r(sesskey);
}
void load_open_settings(void *sesskey, int do_host, Config *cfg)
void load_open_settings(void *sesskey, Config *cfg)
{
int i;
char prot[10];
@ -466,11 +490,7 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
cfg->remote_cmd_ptr2 = NULL;
cfg->ssh_nc_host[0] = '\0';
if (do_host) {
gpps(sesskey, "HostName", "", cfg->host, sizeof(cfg->host));
} else {
cfg->host[0] = '\0'; /* blank hostname */
}
gpps(sesskey, "HostName", "", cfg->host, sizeof(cfg->host));
gppfile(sesskey, "LogFileName", &cfg->logfilename);
gppi(sesskey, "LogType", 0, &cfg->logtype);
gppi(sesskey, "LogFileClash", LGXF_ASK, &cfg->logxfovr);
@ -481,12 +501,13 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
gpps(sesskey, "Protocol", "default", prot, 10);
cfg->protocol = default_protocol;
cfg->port = default_port;
for (i = 0; backends[i].name != NULL; i++)
if (!strcmp(prot, backends[i].name)) {
cfg->protocol = backends[i].protocol;
{
const Backend *b = backend_from_name(prot);
if (b) {
cfg->protocol = b->protocol;
gppi(sesskey, "PortNumber", default_port, &cfg->port);
break;
}
}
/* Address family selection */
gppi(sesskey, "AddressFamily", ADDRTYPE_UNSPEC, &cfg->addressfamily);
@ -577,9 +598,9 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
char *default_kexes;
gppi(sesskey, "BugDHGEx2", 0, &i); i = 2-i;
if (i == FORCE_ON)
default_kexes = "dh-group14-sha1,dh-group1-sha1,WARN,dh-gex-sha1";
default_kexes = "dh-group14-sha1,dh-group1-sha1,rsa,WARN,dh-gex-sha1";
else
default_kexes = "dh-gex-sha1,dh-group14-sha1,dh-group1-sha1,WARN";
default_kexes = "dh-gex-sha1,dh-group14-sha1,dh-group1-sha1,rsa,WARN";
gprefs(sesskey, "KEX", default_kexes,
kexnames, KEX_MAX, cfg->ssh_kexlist);
}
@ -662,6 +683,7 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
gppi(sesskey, "DECOriginMode", 0, &cfg->dec_om);
gppi(sesskey, "AutoWrapMode", 1, &cfg->wrap_mode);
gppi(sesskey, "LFImpliesCR", 0, &cfg->lfhascr);
gppi(sesskey, "CRImpliesLF", 0, &cfg->crhaslf);
gppi(sesskey, "DisableArabicShaping", 0, &cfg->arabicshaping);
gppi(sesskey, "DisableBidi", 0, &cfg->bidi);
gppi(sesskey, "WinNameAlways", 1, &cfg->win_name_always);
@ -767,6 +789,8 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
gppi(sesskey, "BugRSAPad2", 0, &i); cfg->sshbug_rsapad2 = 2-i;
gppi(sesskey, "BugPKSessID2", 0, &i); cfg->sshbug_pksessid2 = 2-i;
gppi(sesskey, "BugRekey2", 0, &i); cfg->sshbug_rekey2 = 2-i;
gppi(sesskey, "BugMaxPkt2", 0, &i); cfg->sshbug_maxpkt2 = 2-i;
cfg->ssh_simple = FALSE;
gppi(sesskey, "StampUtmp", 1, &cfg->stamp_utmp);
gppi(sesskey, "LoginShell", 1, &cfg->login_shell);
gppi(sesskey, "ScrollbarOnLeft", 0, &cfg->scrollbar_on_left);
@ -785,7 +809,7 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
void do_defaults(char *session, Config * cfg)
{
load_settings(session, (session != NULL && *session), cfg);
load_settings(session, cfg);
}
static int sessioncmp(const void *av, const void *bv)

29
sign.sh Executable file
Просмотреть файл

@ -0,0 +1,29 @@
#!/bin/sh
# Generate GPG signatures on a PuTTY release/snapshot directory as
# delivered by Buildscr.
# Usage: sign.sh <builddir> <keytype>
# e.g. sign.sh build.out Snapshots
# or sign.sh 0.60 Releases
set -e
sign() {
# Check for the prior existence of the signature, so we can
# re-run this script if it encounters an error part way
# through.
echo "----- Signing $2 with '$keyname'"
test -f "$3" || \
gpg --load-extension=idea "$1" -u "$keyname" -o "$3" "$2"
}
cd "$1"
for t in DSA RSA; do
keyname="$2 ($t)"
echo "===== Signing with '$keyname'"
for i in putty*src.zip putty*.tar.gz x86/*.exe x86/*.zip; do
sign --detach-sign "$i" "$i.$t"
done
sign --clearsign md5sums md5sums.$t
done

1037
ssh.c

Разница между файлами не показана из-за своего большого размера Загрузить разницу

23
ssh.h
Просмотреть файл

@ -82,6 +82,17 @@ void crcda_free_context(void *handle);
int detect_attack(void *handle, unsigned char *buf, uint32 len,
unsigned char *IV);
/*
* SSH2 RSA key exchange functions
*/
struct ssh_hash;
void *ssh_rsakex_newkey(char *data, int len);
void ssh_rsakex_freekey(void *key);
int ssh_rsakex_klen(void *key);
void ssh_rsakex_encrypt(const struct ssh_hash *h, unsigned char *in, int inlen,
unsigned char *out, int outlen,
void *key);
typedef struct {
uint32 h[4];
} MD5_Core_State;
@ -194,15 +205,10 @@ struct ssh_hash {
};
struct ssh_kex {
/*
* Plugging in another KEX algorithm requires structural chaos,
* so it's hard to abstract them into nice little structures
* like this. Fortunately, all our KEXes are basically
* Diffie-Hellman at the moment, so in this structure I simply
* parametrise the DH exchange a bit.
*/
char *name, *groupname;
const unsigned char *pdata, *gdata;/* NULL means use group exchange */
enum { KEXTYPE_DH, KEXTYPE_RSA } main_type;
/* For DH */
const unsigned char *pdata, *gdata; /* NULL means group exchange */
int plen, glen;
const struct ssh_hash *hash;
};
@ -268,6 +274,7 @@ extern const struct ssh_hash ssh_sha256;
extern const struct ssh_kexes ssh_diffiehellman_group1;
extern const struct ssh_kexes ssh_diffiehellman_group14;
extern const struct ssh_kexes ssh_diffiehellman_gex;
extern const struct ssh_kexes ssh_rsa_kex;
extern const struct ssh_signkey ssh_dss;
extern const struct ssh_signkey ssh_rsa;
extern const struct ssh_mac ssh_hmac_md5;

Просмотреть файл

@ -959,7 +959,7 @@ static const struct ssh2_cipher ssh_3des_ssh2_ctr = {
/*
* Single DES in SSH-2. "des-cbc" is marked as HISTORIC in
* draft-ietf-secsh-assignednumbers-04.txt, referring to
* RFC 4250, referring to
* FIPS-46-3. ("Single DES (i.e., DES) will be permitted
* for legacy systems only.") , but ssh.com support it and
* apparently aren't the only people to do so, so we sigh

Просмотреть файл

@ -52,7 +52,7 @@ static const unsigned char G[] = { 2 };
static const struct ssh_kex ssh_diffiehellman_group1_sha1 = {
"diffie-hellman-group1-sha1", "group1",
P1, G, lenof(P1), lenof(G), &ssh_sha1
KEXTYPE_DH, P1, G, lenof(P1), lenof(G), &ssh_sha1
};
static const struct ssh_kex *const group1_list[] = {
@ -66,7 +66,7 @@ const struct ssh_kexes ssh_diffiehellman_group1 = {
static const struct ssh_kex ssh_diffiehellman_group14_sha1 = {
"diffie-hellman-group14-sha1", "group14",
P14, G, lenof(P14), lenof(G), &ssh_sha1
KEXTYPE_DH, P14, G, lenof(P14), lenof(G), &ssh_sha1
};
static const struct ssh_kex *const group14_list[] = {
@ -80,12 +80,12 @@ const struct ssh_kexes ssh_diffiehellman_group14 = {
static const struct ssh_kex ssh_diffiehellman_gex_sha256 = {
"diffie-hellman-group-exchange-sha256", NULL,
NULL, NULL, 0, 0, &ssh_sha256
KEXTYPE_DH, NULL, NULL, 0, 0, &ssh_sha256
};
static const struct ssh_kex ssh_diffiehellman_gex_sha1 = {
"diffie-hellman-group-exchange-sha1", NULL,
NULL, NULL, 0, 0, &ssh_sha1
KEXTYPE_DH, NULL, NULL, 0, 0, &ssh_sha1
};
static const struct ssh_kex *const gex_list[] = {

Просмотреть файл

@ -231,14 +231,14 @@ static int dss_verifysig(void *key, char *sig, int siglen,
#endif
/*
* Commercial SSH (2.0.13) and OpenSSH disagree over the format
* of a DSA signature. OpenSSH is in line with the IETF drafts:
* of a DSA signature. OpenSSH is in line with RFC 4253:
* it uses a string "ssh-dss", followed by a 40-byte string
* containing two 160-bit integers end-to-end. Commercial SSH
* can't be bothered with the header bit, and considers a DSA
* signature blob to be _just_ the 40-byte string containing
* the two 160-bit integers. We tell them apart by measuring
* the length: length 40 means the commercial-SSH bug, anything
* else is assumed to be IETF-compliant.
* else is assumed to be RFC-compliant.
*/
if (siglen != 40) { /* bug not present; read admin fields */
getstring(&sig, &siglen, &p, &slen);

154
sshrsa.c
Просмотреть файл

@ -836,3 +836,157 @@ const struct ssh_signkey ssh_rsa = {
"ssh-rsa",
"rsa2"
};
void *ssh_rsakex_newkey(char *data, int len)
{
return rsa2_newkey(data, len);
}
void ssh_rsakex_freekey(void *key)
{
rsa2_freekey(key);
}
int ssh_rsakex_klen(void *key)
{
struct RSAKey *rsa = (struct RSAKey *) key;
return bignum_bitcount(rsa->modulus);
}
static void oaep_mask(const struct ssh_hash *h, void *seed, int seedlen,
void *vdata, int datalen)
{
unsigned char *data = (unsigned char *)vdata;
unsigned count = 0;
while (datalen > 0) {
int i, max = (datalen > h->hlen ? h->hlen : datalen);
void *s;
unsigned char counter[4], hash[SSH2_KEX_MAX_HASH_LEN];
assert(h->hlen <= SSH2_KEX_MAX_HASH_LEN);
PUT_32BIT(counter, count);
s = h->init();
h->bytes(s, seed, seedlen);
h->bytes(s, counter, 4);
h->final(s, hash);
count++;
for (i = 0; i < max; i++)
data[i] ^= hash[i];
data += max;
datalen -= max;
}
}
void ssh_rsakex_encrypt(const struct ssh_hash *h, unsigned char *in, int inlen,
unsigned char *out, int outlen,
void *key)
{
Bignum b1, b2;
struct RSAKey *rsa = (struct RSAKey *) key;
int k, i;
char *p;
const int HLEN = h->hlen;
/*
* Here we encrypt using RSAES-OAEP. Essentially this means:
*
* - we have a SHA-based `mask generation function' which
* creates a pseudo-random stream of mask data
* deterministically from an input chunk of data.
*
* - we have a random chunk of data called a seed.
*
* - we use the seed to generate a mask which we XOR with our
* plaintext.
*
* - then we use _the masked plaintext_ to generate a mask
* which we XOR with the seed.
*
* - then we concatenate the masked seed and the masked
* plaintext, and RSA-encrypt that lot.
*
* The result is that the data input to the encryption function
* is random-looking and (hopefully) contains no exploitable
* structure such as PKCS1-v1_5 does.
*
* For a precise specification, see RFC 3447, section 7.1.1.
* Some of the variable names below are derived from that, so
* it'd probably help to read it anyway.
*/
/* k denotes the length in octets of the RSA modulus. */
k = (7 + bignum_bitcount(rsa->modulus)) / 8;
/* The length of the input data must be at most k - 2hLen - 2. */
assert(inlen > 0 && inlen <= k - 2*HLEN - 2);
/* The length of the output data wants to be precisely k. */
assert(outlen == k);
/*
* Now perform EME-OAEP encoding. First set up all the unmasked
* output data.
*/
/* Leading byte zero. */
out[0] = 0;
/* At position 1, the seed: HLEN bytes of random data. */
for (i = 0; i < HLEN; i++)
out[i + 1] = random_byte();
/* At position 1+HLEN, the data block DB, consisting of: */
/* The hash of the label (we only support an empty label here) */
h->final(h->init(), out + HLEN + 1);
/* A bunch of zero octets */
memset(out + 2*HLEN + 1, 0, outlen - (2*HLEN + 1));
/* A single 1 octet, followed by the input message data. */
out[outlen - inlen - 1] = 1;
memcpy(out + outlen - inlen, in, inlen);
/*
* Now use the seed data to mask the block DB.
*/
oaep_mask(h, out+1, HLEN, out+HLEN+1, outlen-HLEN-1);
/*
* And now use the masked DB to mask the seed itself.
*/
oaep_mask(h, out+HLEN+1, outlen-HLEN-1, out+1, HLEN);
/*
* Now `out' contains precisely the data we want to
* RSA-encrypt.
*/
b1 = bignum_from_bytes(out, outlen);
b2 = modpow(b1, rsa->exponent, rsa->modulus);
p = (char *)out;
for (i = outlen; i--;) {
*p++ = bignum_byte(b2, i);
}
freebn(b1);
freebn(b2);
/*
* And we're done.
*/
}
static const struct ssh_kex ssh_rsa_kex_sha1 = {
"rsa1024-sha1", NULL, KEXTYPE_RSA, NULL, NULL, 0, 0, &ssh_sha1
};
static const struct ssh_kex ssh_rsa_kex_sha256 = {
"rsa2048-sha256", NULL, KEXTYPE_RSA, NULL, NULL, 0, 0, &ssh_sha256
};
static const struct ssh_kex *const rsa_kex_list[] = {
&ssh_rsa_kex_sha256,
&ssh_rsa_kex_sha1
};
const struct ssh_kexes ssh_rsa_kex = {
sizeof(rsa_kex_list) / sizeof(*rsa_kex_list),
rsa_kex_list
};

Просмотреть файл

@ -1106,5 +1106,7 @@ Backend telnet_backend = {
telnet_provide_logctx,
telnet_unthrottle,
telnet_cfg_info,
"telnet",
PROT_TELNET,
23
};

Просмотреть файл

@ -1223,6 +1223,8 @@ static void power_on(Terminal *term, int clear)
term->erase_char = term->basic_erase_char;
term->alt_which = 0;
term_print_finish(term);
term->xterm_mouse = FALSE;
set_raw_mouse_mode(term->frontend, FALSE);
{
int i;
for (i = 0; i < 256; i++)
@ -1448,7 +1450,7 @@ Terminal *term_init(Config *mycfg, struct unicode_data *ucsdata,
term->vt52_mode = FALSE;
term->cr_lf_return = FALSE;
term->seen_disp_event = FALSE;
term->xterm_mouse = term->mouse_is_down = FALSE;
term->mouse_is_down = FALSE;
term->reset_132 = FALSE;
term->cblinker = term->tblinker = 0;
term->has_focus = 1;
@ -1612,6 +1614,8 @@ void term_size(Terminal *term, int newrows, int newcols, int newsavelines)
addpos234(term->screen, line, 0);
term->curs.y += 1;
term->savecurs.y += 1;
term->alt_y += 1;
term->alt_savecurs.y += 1;
} else {
/* Add a new blank line at the bottom of the screen. */
line = newline(term, newcols, FALSE);
@ -1632,6 +1636,8 @@ void term_size(Terminal *term, int newrows, int newcols, int newsavelines)
term->tempsblines += 1;
term->curs.y -= 1;
term->savecurs.y -= 1;
term->alt_y -= 1;
term->alt_savecurs.y -= 1;
}
term->rows -= 1;
}
@ -1691,12 +1697,26 @@ void term_size(Terminal *term, int newrows, int newcols, int newsavelines)
term->savecurs.y = 0;
if (term->savecurs.y >= newrows)
term->savecurs.y = newrows - 1;
if (term->savecurs.x >= newcols)
term->savecurs.x = newcols - 1;
if (term->alt_savecurs.y < 0)
term->alt_savecurs.y = 0;
if (term->alt_savecurs.y >= newrows)
term->alt_savecurs.y = newrows - 1;
if (term->alt_savecurs.x >= newcols)
term->alt_savecurs.x = newcols - 1;
if (term->curs.y < 0)
term->curs.y = 0;
if (term->curs.y >= newrows)
term->curs.y = newrows - 1;
if (term->curs.x >= newcols)
term->curs.x = newcols - 1;
if (term->alt_y < 0)
term->alt_y = 0;
if (term->alt_y >= newrows)
term->alt_y = newrows - 1;
if (term->alt_x >= newcols)
term->alt_x = newcols - 1;
term->alt_x = term->alt_y = 0;
term->wrapnext = term->alt_wnext = FALSE;
@ -2850,6 +2870,13 @@ static void term_out(Terminal *term)
term->wrapnext = FALSE;
seen_disp_event(term);
term->paste_hold = 0;
if (term->cfg.crhaslf) {
if (term->curs.y == term->marg_b)
scroll(term, term->marg_t, term->marg_b, 1, TRUE);
else if (term->curs.y < term->rows - 1)
term->curs.y++;
}
if (term->logctx)
logtraffic(term->logctx, (unsigned char) c, LGTYP_ASCII);
break;
@ -6398,6 +6425,7 @@ char *term_get_ttymode(Terminal *term, const char *mode)
val = term->cfg.bksp_is_delete ? "^?" : "^H";
}
/* FIXME: perhaps we should set ONLCR based on cfg.lfhascr as well? */
/* FIXME: or ECHO and friends based on local echo state? */
return dupstr(val);
}

Просмотреть файл

@ -46,7 +46,7 @@ static int null_sendbuffer(void *);
static void null_size(void *, int, int);
static void null_special(void *, Telnet_Special);
static const struct telnet_special *null_get_specials(void *handle);
static Socket null_socket(void *);
static int null_connected(void *);
static int null_exitcode(void *);
static int null_sendok(void *);
static int null_ldisc(void *, int);
@ -57,16 +57,16 @@ static int null_cfg_info(void *);
Backend null_backend = {
null_init, null_free, null_reconfig, null_send, null_sendbuffer, null_size,
null_special, null_get_specials, null_socket, null_exitcode, null_sendok,
null_special, null_get_specials, null_connected, null_exitcode, null_sendok,
null_ldisc, null_provide_ldisc, null_provide_logctx, null_unthrottle,
null_cfg_info, 0
null_cfg_info, "null", -1, 0
};
Backend loop_backend = {
loop_init, loop_free, null_reconfig, loop_send, null_sendbuffer, null_size,
null_special, null_get_specials, null_socket, null_exitcode, null_sendok,
null_special, null_get_specials, null_connected, null_exitcode, null_sendok,
null_ldisc, null_provide_ldisc, null_provide_logctx, null_unthrottle,
null_cfg_info, 0
null_cfg_info, "loop", -1, 0
};
struct loop_state {
@ -134,9 +134,9 @@ static const struct telnet_special *null_get_specials (void *handle) {
return NULL;
}
static Socket null_socket(void *handle) {
static int null_connected(void *handle) {
return NULL;
return 0;
}
static int null_exitcode(void *handle) {

Просмотреть файл

@ -49,6 +49,7 @@ struct uctrl {
GtkAdjustment *adj; /* for the scrollbar in a list box */
guint entrysig;
guint textsig;
int nclicks;
};
struct dlgparam {
@ -98,8 +99,10 @@ static gboolean listitem_single_key(GtkWidget *item, GdkEventKey *event,
gpointer data);
static gboolean listitem_multi_key(GtkWidget *item, GdkEventKey *event,
gpointer data);
static gboolean listitem_button(GtkWidget *item, GdkEventButton *event,
gpointer data);
static gboolean listitem_button_press(GtkWidget *item, GdkEventButton *event,
gpointer data);
static gboolean listitem_button_release(GtkWidget *item, GdkEventButton *event,
gpointer data);
static void menuitem_activate(GtkMenuItem *item, gpointer data);
static void coloursel_ok(GtkButton *button, gpointer data);
static void coloursel_cancel(GtkButton *button, gpointer data);
@ -467,7 +470,9 @@ void dlg_listbox_addwithid(union control *ctrl, void *dlg,
gtk_signal_connect(GTK_OBJECT(listitem), "focus_in_event",
GTK_SIGNAL_FUNC(widget_focus), dp);
gtk_signal_connect(GTK_OBJECT(listitem), "button_press_event",
GTK_SIGNAL_FUNC(listitem_button), dp);
GTK_SIGNAL_FUNC(listitem_button_press), dp);
gtk_signal_connect(GTK_OBJECT(listitem), "button_release_event",
GTK_SIGNAL_FUNC(listitem_button_release), dp);
gtk_object_set_data(GTK_OBJECT(listitem), "user-data",
GINT_TO_POINTER(id));
} else {
@ -1121,13 +1126,26 @@ static gboolean listitem_multi_key(GtkWidget *item, GdkEventKey *event,
return listitem_key(item, event, data, TRUE);
}
static gboolean listitem_button(GtkWidget *item, GdkEventButton *event,
gpointer data)
static gboolean listitem_button_press(GtkWidget *item, GdkEventButton *event,
gpointer data)
{
struct dlgparam *dp = (struct dlgparam *)data;
if (event->type == GDK_2BUTTON_PRESS ||
event->type == GDK_3BUTTON_PRESS) {
struct uctrl *uc = dlg_find_bywidget(dp, GTK_WIDGET(item));
struct uctrl *uc = dlg_find_bywidget(dp, GTK_WIDGET(item));
switch (event->type) {
default:
case GDK_BUTTON_PRESS: uc->nclicks = 1; break;
case GDK_2BUTTON_PRESS: uc->nclicks = 2; break;
case GDK_3BUTTON_PRESS: uc->nclicks = 3; break;
}
return FALSE;
}
static gboolean listitem_button_release(GtkWidget *item, GdkEventButton *event,
gpointer data)
{
struct dlgparam *dp = (struct dlgparam *)data;
struct uctrl *uc = dlg_find_bywidget(dp, GTK_WIDGET(item));
if (uc->nclicks>1) {
uc->ctrl->generic.handler(uc->ctrl, dp, dp->data, EVENT_ACTION);
return TRUE;
}
@ -1412,6 +1430,7 @@ GtkWidget *layout_ctrls(struct dlgparam *dp, struct Shortcuts *scs,
uc->entry = uc->list = uc->menu = NULL;
uc->button = uc->optmenu = uc->text = NULL;
uc->label = NULL;
uc->nclicks = 0;
switch (ctrl->generic.type) {
case CTRL_BUTTON:
@ -2749,7 +2768,7 @@ static void licence_clicked(GtkButton *button, gpointer data)
char *title;
char *licence =
"Copyright 1997-2007 Simon Tatham.\n\n"
"Copyright 1997-2008 Simon Tatham.\n\n"
"Portions copyright Robert de Bath, Joris van Rantwijk, Delian "
"Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas "
@ -2830,7 +2849,7 @@ void about_box(void *window)
w, FALSE, FALSE, 5);
gtk_widget_show(w);
w = gtk_label_new("Copyright 1997-2007 Simon Tatham. All rights reserved");
w = gtk_label_new("Copyright 1997-2008 Simon Tatham. All rights reserved");
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(aboutbox)->vbox),
w, FALSE, FALSE, 5);
gtk_widget_show(w);

Просмотреть файл

@ -663,13 +663,12 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
end = 2;
}
/* Control-Break is the same as Control-C */
/* Control-Break sends a Break special to the backend */
if (event->keyval == GDK_Break &&
(event->state & GDK_CONTROL_MASK)) {
output[1] = '\003';
use_ucsoutput = FALSE;
end = 2;
special = TRUE;
if (inst->back)
inst->back->special(inst->backhandle, TS_BRK);
return TRUE;
}
/* We handle Return ourselves, because it needs to be flagged as
@ -724,6 +723,13 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
end = 1 + sprintf(output+1, "\033[Z");
use_ucsoutput = FALSE;
}
/* And normal Tab is Tab, if the keymap hasn't already told us.
* (Curiously, at least one version of the MacOS 10.5 X server
* doesn't translate Tab for us. */
if (event->keyval == GDK_Tab && end <= 1) {
output[1] = '\t';
end = 2;
}
/*
* NetHack keypad mode.
@ -1431,7 +1437,7 @@ void palette_reset(void *frontend)
int r = i / 36, g = (i / 6) % 6, b = i % 6;
inst->cols[i+16].red = r ? r * 0x2828 + 0x3737 : 0;
inst->cols[i+16].green = g ? g * 0x2828 + 0x3737 : 0;
inst->cols[i+16].blue = b ? b + 0x2828 + 0x3737 : 0;
inst->cols[i+16].blue = b ? b * 0x2828 + 0x3737 : 0;
} else {
int shade = i - 216;
shade = shade * 0x0a0a + 0x0808;
@ -1864,7 +1870,7 @@ void sys_cursor(void *frontend, int x, int y)
*/
void do_beep(void *frontend, int mode)
{
if (mode != BELL_VISUAL)
if (mode == BELL_DEFAULT)
gdk_beep();
}
@ -2408,7 +2414,7 @@ static void help(FILE *fp) {
}
}
int do_cmdline(int argc, char **argv, int do_everything,
int do_cmdline(int argc, char **argv, int do_everything, int *allow_launch,
struct gui_data *inst, Config *cfg)
{
int err = 0;
@ -2614,7 +2620,8 @@ int do_cmdline(int argc, char **argv, int do_everything,
exit(1);
} else if(p[0] != '-' && (!do_everything ||
process_nonoption_arg(p, cfg))) {
process_nonoption_arg(p, cfg,
allow_launch))) {
/* do nothing */
} else {
@ -3321,6 +3328,7 @@ void set_window_icon(GtkWidget *window, const char *const *const *icon,
int n_icon)
{
GdkPixmap *iconpm;
GdkBitmap *iconmask;
#if GTK_CHECK_VERSION(2,0,0)
GList *iconlist;
int n;
@ -3330,9 +3338,9 @@ void set_window_icon(GtkWidget *window, const char *const *const *icon,
return;
gtk_widget_realize(window);
iconpm = gdk_pixmap_create_from_xpm_d(window->window, NULL,
iconpm = gdk_pixmap_create_from_xpm_d(window->window, &iconmask,
NULL, (gchar **)icon[0]);
gdk_window_set_icon(window->window, NULL, iconpm, NULL);
gdk_window_set_icon(window->window, NULL, iconpm, iconmask);
#if GTK_CHECK_VERSION(2,0,0)
iconlist = NULL;
@ -3492,15 +3500,23 @@ int pt_main(int argc, char **argv)
/* Splatter this argument so it doesn't clutter a ps listing */
memset(argv[1], 0, strlen(argv[1]));
} else {
if (do_cmdline(argc, argv, 0, inst, &inst->cfg))
/* By default, we bring up the config dialog, rather than launching
* a session. This gets set to TRUE if something happens to change
* that (e.g., a hostname is specified on the command-line). */
int allow_launch = FALSE;
if (do_cmdline(argc, argv, 0, &allow_launch, inst, &inst->cfg))
exit(1); /* pre-defaults pass to get -class */
do_defaults(NULL, &inst->cfg);
if (do_cmdline(argc, argv, 1, inst, &inst->cfg))
if (do_cmdline(argc, argv, 1, &allow_launch, inst, &inst->cfg))
exit(1); /* post-defaults, do everything */
cmdline_run_saved(&inst->cfg);
if (!cfg_launchable(&inst->cfg) && !cfgbox(&inst->cfg))
if (loaded_session)
allow_launch = TRUE;
if ((!allow_launch || !cfg_launchable(&inst->cfg)) &&
!cfgbox(&inst->cfg))
exit(0); /* config box hit Cancel */
}

Просмотреть файл

@ -60,6 +60,18 @@ extern long tickcount_offset;
#define WCHAR wchar_t
#define BYTE unsigned char
/*
* Unix-specific global flag
*
* FLAG_STDERR_TTY indicates that standard error might be a terminal and
* might get its configuration munged, so anything trying to output plain
* text (i.e. with newlines in it) will need to put it back into cooked
* mode first. Applications setting this flag should also call
* stderr_tty_init() before messing with any terminal modes, and can call
* premsg() before outputting text to stderr and postmsg() afterwards.
*/
#define FLAG_STDERR_TTY 0x1000
/* Things pty.c needs from pterm.c */
char *get_x_display(void *frontend);
int font_dimension(void *frontend, int which);/* 0 for width, 1 for height */
@ -80,7 +92,7 @@ int reallyclose(void *frontend);
/* Things pterm.c needs from {ptermm,uxputty}.c */
char *make_default_wintitle(char *hostname);
int process_nonoption_arg(char *arg, Config *cfg);
int process_nonoption_arg(char *arg, Config *cfg, int *allow_launch);
/* pterm.c needs this special function in xkeysym.c */
int keysym_to_unicode(int keysym);
@ -91,6 +103,12 @@ char *x_get_default(const char *key);
/* Things uxstore.c provides to pterm.c */
void provide_xrm_string(char *string);
/* Things provided by uxcons.c */
struct termios;
void stderr_tty_init(void);
void premsg(struct termios *);
void postmsg(struct termios *);
/* The interface used by uxsel.c */
void uxsel_init(void);
typedef int (*uxsel_callback_fn)(int fd, int event);

Просмотреть файл

@ -18,6 +18,31 @@ int console_batch_mode = FALSE;
static void *console_logctx = NULL;
static struct termios orig_termios_stderr;
static int stderr_is_a_tty;
void stderr_tty_init()
{
/* Ensure that if stderr is a tty, we can get it back to a sane state. */
if ((flags & FLAG_STDERR_TTY) && isatty(STDERR_FILENO)) {
stderr_is_a_tty = TRUE;
tcgetattr(STDERR_FILENO, &orig_termios_stderr);
}
}
void premsg(struct termios *cf)
{
if (stderr_is_a_tty) {
tcgetattr(STDERR_FILENO, cf);
tcsetattr(STDERR_FILENO, TCSADRAIN, &orig_termios_stderr);
}
}
void postmsg(struct termios *cf)
{
if (stderr_is_a_tty)
tcsetattr(STDERR_FILENO, TCSADRAIN, cf);
}
/*
* Clean up and exit.
*/
@ -101,6 +126,7 @@ int verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
static const char abandoned[] = "Connection abandoned.\n";
char line[32];
struct termios cf;
/*
* Verify the key.
@ -110,6 +136,7 @@ int verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
if (ret == 0) /* success - key matched OK */
return 1;
premsg(&cf);
if (ret == 2) { /* key was different */
if (console_batch_mode) {
fprintf(stderr, wrongmsg_batch, keytype, fingerprint);
@ -141,9 +168,11 @@ int verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
if (line[0] != '\0' && line[0] != '\r' && line[0] != '\n') {
if (line[0] == 'y' || line[0] == 'Y')
store_host_key(host, port, keytype, keystr);
postmsg(&cf);
return 1;
} else {
fprintf(stderr, abandoned);
postmsg(&cf);
return 0;
}
}
@ -166,7 +195,9 @@ int askalg(void *frontend, const char *algtype, const char *algname,
static const char abandoned[] = "Connection abandoned.\n";
char line[32];
struct termios cf;
premsg(&cf);
if (console_batch_mode) {
fprintf(stderr, msg_batch, algtype, algname);
return 0;
@ -187,9 +218,11 @@ int askalg(void *frontend, const char *algtype, const char *algname,
}
if (line[0] == 'y' || line[0] == 'Y') {
postmsg(&cf);
return 1;
} else {
fprintf(stderr, abandoned);
postmsg(&cf);
return 0;
}
}
@ -215,7 +248,9 @@ int askappend(void *frontend, Filename filename,
"Logging will not be enabled.\n";
char line[32];
struct termios cf;
premsg(&cf);
if (console_batch_mode) {
fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename.path);
fflush(stderr);
@ -235,6 +270,7 @@ int askappend(void *frontend, Filename filename,
tcsetattr(0, TCSANOW, &oldmode);
}
postmsg(&cf);
if (line[0] == 'y' || line[0] == 'Y')
return 2;
else if (line[0] == 'n' || line[0] == 'N')
@ -266,7 +302,10 @@ void old_keyfile_warning(void)
"Once the key is loaded into PuTTYgen, you can perform\n"
"this conversion simply by saving it again.\n";
struct termios cf;
premsg(&cf);
fputs(message, stderr);
postmsg(&cf);
}
void console_provide_logctx(void *logctx)
@ -276,8 +315,11 @@ void console_provide_logctx(void *logctx)
void logevent(void *frontend, const char *string)
{
struct termios cf;
premsg(&cf);
if (console_logctx)
log_eventlog(console_logctx, string);
postmsg(&cf);
}
static void console_data_untrusted(const char *data, int len)

Просмотреть файл

@ -97,6 +97,10 @@ static int cmpfortree(void *av, void *bv)
return -1;
if (as > bs)
return +1;
if (a < b)
return -1;
if (a > b)
return +1;
return 0;
}
@ -453,6 +457,14 @@ static int try_connect(Actual_Socket sock)
short localport;
int fl, salen;
/*
* Remove the socket from the tree before we overwrite its
* internal socket id, because that forms part of the tree's
* sorting criterion. We'll add it back before exiting this
* function, whether we changed anything or not.
*/
del234(sktree, sock);
if (sock->s >= 0)
close(sock->s);
@ -605,9 +617,14 @@ static int try_connect(Actual_Socket sock)
}
uxsel_tell(sock);
add234(sktree, sock);
ret:
/*
* No matter what happened, put the socket back in the tree.
*/
add234(sktree, sock);
if (err)
plug_log(sock->plug, 1, sock->addr, sock->port, strerror(err), err);
return err;
@ -1060,6 +1077,7 @@ static int net_select_result(int fd, int event)
#endif
socklen_t addrlen = sizeof(ss);
int t; /* socket of connection */
int fl;
memset(&ss, 0, addrlen);
t = accept(s->s, (struct sockaddr *)&ss, &addrlen);
@ -1067,6 +1085,10 @@ static int net_select_result(int fd, int event)
break;
}
fl = fcntl(t, F_GETFL);
if (fl != -1)
fcntl(t, F_SETFL, fl | O_NONBLOCK);
if (s->localhost_only &&
!sockaddr_is_loopback((struct sockaddr *)&ss)) {
close(t); /* someone let nonlocal through?! */

Просмотреть файл

@ -27,14 +27,19 @@
void *logctx;
static struct termios orig_termios;
void fatalbox(char *p, ...)
{
struct termios cf;
va_list ap;
premsg(&cf);
fprintf(stderr, "FATAL ERROR: ");
va_start(ap, p);
vfprintf(stderr, p, ap);
va_end(ap);
fputc('\n', stderr);
postmsg(&cf);
if (logctx) {
log_free(logctx);
logctx = NULL;
@ -43,12 +48,15 @@ void fatalbox(char *p, ...)
}
void modalfatalbox(char *p, ...)
{
struct termios cf;
va_list ap;
premsg(&cf);
fprintf(stderr, "FATAL ERROR: ");
va_start(ap, p);
vfprintf(stderr, p, ap);
va_end(ap);
fputc('\n', stderr);
postmsg(&cf);
if (logctx) {
log_free(logctx);
logctx = NULL;
@ -57,12 +65,15 @@ void modalfatalbox(char *p, ...)
}
void connection_fatal(void *frontend, char *p, ...)
{
struct termios cf;
va_list ap;
premsg(&cf);
fprintf(stderr, "FATAL ERROR: ");
va_start(ap, p);
vfprintf(stderr, p, ap);
va_end(ap);
fputc('\n', stderr);
postmsg(&cf);
if (logctx) {
log_free(logctx);
logctx = NULL;
@ -71,17 +82,19 @@ void connection_fatal(void *frontend, char *p, ...)
}
void cmdline_error(char *p, ...)
{
struct termios cf;
va_list ap;
premsg(&cf);
fprintf(stderr, "plink: ");
va_start(ap, p);
vfprintf(stderr, p, ap);
va_end(ap);
fputc('\n', stderr);
postmsg(&cf);
exit(1);
}
static int local_tty = 0; /* do we have a local tty? */
static struct termios orig_termios;
static int local_tty = FALSE; /* do we have a local tty? */
static Backend *back;
static void *backhandle;
@ -106,7 +119,7 @@ int platform_default_i(const char *name, int def)
if (!strcmp(name, "TermWidth") ||
!strcmp(name, "TermHeight")) {
struct winsize size;
if (ioctl(0, TIOCGWINSZ, (void *)&size) >= 0)
if (ioctl(STDIN_FILENO, TIOCGWINSZ, (void *)&size) >= 0)
return (!strcmp(name, "TermWidth") ? size.ws_col : size.ws_row);
}
return def;
@ -180,7 +193,7 @@ void ldisc_update(void *frontend, int echo, int edit)
*/
mode.c_iflag = (mode.c_iflag | INPCK | PARMRK) & ~IGNPAR;
tcsetattr(0, TCSANOW, &mode);
tcsetattr(STDIN_FILENO, TCSANOW, &mode);
}
/* Helper function to extract a special character from a termios. */
@ -366,48 +379,49 @@ char *get_ttymode(void *frontend, const char *mode)
void cleanup_termios(void)
{
if (local_tty)
tcsetattr(0, TCSANOW, &orig_termios);
tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios);
}
bufchain stdout_data, stderr_data;
void try_output(int is_stderr)
int try_output(int is_stderr)
{
bufchain *chain = (is_stderr ? &stderr_data : &stdout_data);
int fd = (is_stderr ? 2 : 1);
int fd = (is_stderr ? STDERR_FILENO : STDOUT_FILENO);
void *senddata;
int sendlen, ret;
int sendlen, ret, fl;
if (bufchain_size(chain) == 0)
return;
return bufchain_size(&stdout_data) + bufchain_size(&stderr_data);
bufchain_prefix(chain, &senddata, &sendlen);
ret = write(fd, senddata, sendlen);
if (ret > 0)
bufchain_consume(chain, ret);
else if (ret < 0) {
fl = fcntl(fd, F_GETFL);
if (fl != -1 && !(fl & O_NONBLOCK))
fcntl(fd, F_SETFL, fl | O_NONBLOCK);
do {
bufchain_prefix(chain, &senddata, &sendlen);
ret = write(fd, senddata, sendlen);
if (ret > 0)
bufchain_consume(chain, ret);
} while (ret == sendlen && bufchain_size(chain) != 0);
if (fl != -1 && !(fl & O_NONBLOCK))
fcntl(fd, F_SETFL, fl);
if (ret < 0 && errno != EAGAIN) {
perror(is_stderr ? "stderr: write" : "stdout: write");
exit(1);
}
return bufchain_size(&stdout_data) + bufchain_size(&stderr_data);
}
int from_backend(void *frontend_handle, int is_stderr,
const char *data, int len)
{
int osize, esize;
if (is_stderr) {
bufchain_add(&stderr_data, data, len);
try_output(1);
return try_output(TRUE);
} else {
bufchain_add(&stdout_data, data, len);
try_output(0);
return try_output(FALSE);
}
osize = bufchain_size(&stdout_data);
esize = bufchain_size(&stderr_data);
return osize + esize;
}
int from_backend_untrusted(void *frontend_handle, const char *data, int len)
@ -582,7 +596,9 @@ int main(int argc, char **argv)
default_protocol = PROT_SSH;
default_port = 22;
flags = FLAG_STDERR;
flags = FLAG_STDERR | FLAG_STDERR_TTY;
stderr_tty_init();
/*
* Process the command line.
*/
@ -596,15 +612,11 @@ int main(int argc, char **argv)
* Override the default protocol if PLINK_PROTOCOL is set.
*/
char *p = getenv("PLINK_PROTOCOL");
int i;
if (p) {
for (i = 0; backends[i].backend != NULL; i++) {
if (!strcmp(backends[i].name, p)) {
default_protocol = cfg.protocol = backends[i].protocol;
default_port = cfg.port =
backends[i].backend->default_port;
break;
}
const Backend *b = backend_from_name(p);
if (b) {
default_protocol = cfg.protocol = b->protocol;
default_port = cfg.port = b->default_port;
}
}
}
@ -681,19 +693,14 @@ int main(int argc, char **argv)
*/
r = strchr(p, ',');
if (r) {
int i, j;
for (i = 0; backends[i].backend != NULL; i++) {
j = strlen(backends[i].name);
if (j == r - p &&
!memcmp(backends[i].name, p, j)) {
default_protocol = cfg.protocol =
backends[i].protocol;
portnumber =
backends[i].backend->default_port;
p = r + 1;
break;
}
const Backend *b;
*r = '\0';
b = backend_from_name(p);
if (b) {
default_protocol = cfg.protocol = b->protocol;
portnumber = b->default_port;
}
p = r + 1;
}
/*
@ -836,19 +843,11 @@ int main(int argc, char **argv)
* Select protocol. This is farmed out into a table in a
* separate file to enable an ssh-free variant.
*/
{
int i;
back = NULL;
for (i = 0; backends[i].backend != NULL; i++)
if (backends[i].protocol == cfg.protocol) {
back = backends[i].backend;
break;
}
if (back == NULL) {
fprintf(stderr,
"Internal fault: Unsupported protocol found\n");
return 1;
}
back = backend_from_proto(cfg.protocol);
if (back == NULL) {
fprintf(stderr,
"Internal fault: Unsupported protocol found\n");
return 1;
}
/*
@ -869,6 +868,14 @@ int main(int argc, char **argv)
sk_init();
uxsel_init();
/*
* Unix Plink doesn't provide any way to add forwardings after the
* connection is set up, so if there are none now, we can safely set
* the "simple" flag.
*/
if (cfg.protocol == PROT_SSH && !cfg.x11_forward && !cfg.agentfwd &&
cfg.portfwd[0] == '\0' && cfg.portfwd[1] == '\0')
cfg.ssh_simple = TRUE;
/*
* Start up the connection.
*/
@ -897,7 +904,7 @@ int main(int argc, char **argv)
* fails, because we know we aren't necessarily running in a
* console.
*/
local_tty = (tcgetattr(0, &orig_termios) == 0);
local_tty = (tcgetattr(STDIN_FILENO, &orig_termios) == 0);
atexit(cleanup_termios);
ldisc_update(NULL, 1, 1);
sending = FALSE;
@ -921,17 +928,17 @@ int main(int argc, char **argv)
back->sendok(backhandle) &&
back->sendbuffer(backhandle) < MAX_STDIN_BACKLOG) {
/* If we're OK to send, then try to read from stdin. */
FD_SET_MAX(0, maxfd, rset);
FD_SET_MAX(STDIN_FILENO, maxfd, rset);
}
if (bufchain_size(&stdout_data) > 0) {
/* If we have data for stdout, try to write to stdout. */
FD_SET_MAX(1, maxfd, wset);
FD_SET_MAX(STDOUT_FILENO, maxfd, wset);
}
if (bufchain_size(&stderr_data) > 0) {
/* If we have data for stderr, try to write to stderr. */
FD_SET_MAX(2, maxfd, wset);
FD_SET_MAX(STDERR_FILENO, maxfd, wset);
}
/* Count the currently active fds. */
@ -1028,12 +1035,12 @@ int main(int argc, char **argv)
back->size(backhandle, size.ws_col, size.ws_row);
}
if (FD_ISSET(0, &rset)) {
if (FD_ISSET(STDIN_FILENO, &rset)) {
char buf[4096];
int ret;
if (connopen && back->connected(backhandle)) {
ret = read(0, buf, sizeof(buf));
ret = read(STDIN_FILENO, buf, sizeof(buf));
if (ret < 0) {
perror("stdin: read");
exit(1);
@ -1049,12 +1056,12 @@ int main(int argc, char **argv)
}
}
if (FD_ISSET(1, &wset)) {
try_output(0);
if (FD_ISSET(STDOUT_FILENO, &wset)) {
back->unthrottle(backhandle, try_output(FALSE));
}
if (FD_ISSET(2, &wset)) {
try_output(1);
if (FD_ISSET(STDERR_FILENO, &wset)) {
back->unthrottle(backhandle, try_output(TRUE));
}
if ((!connopen || !back->connected(backhandle)) &&

Просмотреть файл

@ -33,7 +33,7 @@ void cleanup_exit(int code)
exit(code);
}
int process_nonoption_arg(char *arg, Config *cfg)
int process_nonoption_arg(char *arg, Config *cfg, int *allow_launch)
{
return 0; /* pterm doesn't have any. */
}

Просмотреть файл

@ -360,8 +360,10 @@ static void pty_open_master(Pty pty)
/*
* Set the pty master into non-blocking mode.
*/
int i = 1;
ioctl(pty->master_fd, FIONBIO, &i);
int fl;
fl = fcntl(pty->master_fd, F_GETFL);
if (fl != -1 && !(fl & O_NONBLOCK))
fcntl(pty->master_fd, F_SETFL, fl | O_NONBLOCK);
}
if (!ptys_by_fd)
@ -775,10 +777,10 @@ static const char *pty_init(void *frontend, void **backend_handle, Config *cfg,
close(slavefd);
setsid();
#ifdef TIOCSCTTY
ioctl(slavefd, TIOCSCTTY, 1);
ioctl(0, TIOCSCTTY, 1);
#endif
pgrp = getpid();
tcsetpgrp(slavefd, pgrp);
tcsetpgrp(0, pgrp);
setpgid(pgrp, pgrp);
close(open(pty->name, O_WRONLY, 0));
setpgid(pgrp, pgrp);
@ -1085,5 +1087,7 @@ Backend pty_backend = {
pty_provide_logctx,
pty_unthrottle,
pty_cfg_info,
1
"pty",
-1,
0
};

Просмотреть файл

@ -33,13 +33,7 @@ void cleanup_exit(int code)
Backend *select_backend(Config *cfg)
{
int i;
Backend *back = NULL;
for (i = 0; backends[i].backend != NULL; i++)
if (backends[i].protocol == cfg->protocol) {
back = backends[i].backend;
break;
}
Backend *back = backend_from_proto(cfg->protocol);
assert(back != NULL);
return back;
}
@ -53,7 +47,7 @@ static int got_host = 0;
const int use_event_log = 1, new_session = 1, saved_sessions = 1;
int process_nonoption_arg(char *arg, Config *cfg)
int process_nonoption_arg(char *arg, Config *cfg, int *allow_launch)
{
char *p, *q = arg;
@ -104,6 +98,8 @@ int process_nonoption_arg(char *arg, Config *cfg)
cfg->host[sizeof(cfg->host) - 1] = '\0';
got_host = 1;
}
if (got_host)
*allow_launch = TRUE;
return 1;
}
@ -135,13 +131,10 @@ int main(int argc, char **argv)
default_protocol = be_default_protocol;
/* Find the appropriate default port. */
{
int i;
Backend *b = backend_from_proto(default_protocol);
default_port = 0; /* illegal */
for (i = 0; backends[i].backend != NULL; i++)
if (backends[i].protocol == default_protocol) {
default_port = backends[i].backend->default_port;
break;
}
if (b)
default_port = b->default_port;
}
return pt_main(argc, argv);
}

Просмотреть файл

@ -536,5 +536,7 @@ Backend serial_backend = {
serial_provide_logctx,
serial_unthrottle,
serial_cfg_info,
1
"serial",
PROT_SERIAL,
0
};

Просмотреть файл

@ -23,6 +23,11 @@ char sshver[] = "PuTTY-Snapshot-" SNAPSHOT_TEXT;
char ver[] = "Release " STR(RELEASE);
char sshver[] = "PuTTY-Release-" STR(RELEASE);
#elif defined SVN_REV
char ver[] = "Custom build r" STR(SVN_REV);
char sshver[] = "PuTTY-Custom-r" STR(SVN_REV);
#else
char ver[] = "Unidentified build, " __DATE__ " " __TIME__;

Просмотреть файл

@ -45,7 +45,7 @@ BEGIN
PUSHBUTTON "View &Licence", 101, 6, 52, 70, 14
CTEXT "Pageant", 102, 10, 6, 120, 8
CTEXT "", 100, 10, 16, 120, 16
CTEXT "\251 1997-2007 Simon Tatham. All rights reserved.",
CTEXT "\251 1997-2008 Simon Tatham. All rights reserved.",
103, 10, 34, 120, 16
END
@ -57,7 +57,7 @@ FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "OK", IDOK, 98, 243, 44, 14
LTEXT "Copyright \251 1997-2007 Simon Tatham", 1000, 10, 10, 206, 8
LTEXT "Copyright \251 1997-2008 Simon Tatham", 1000, 10, 10, 206, 8
LTEXT "Portions copyright Robert de Bath, Joris van Rantwijk, Delian", 1001, 10, 26, 206, 8
LTEXT "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas", 1002, 10, 34, 206, 8

Просмотреть файл

@ -2,6 +2,7 @@
; $Id$
;
; -- Inno Setup installer script for PuTTY and its related tools.
; Last tested with Inno Setup 5.0.8.
;
; TODO for future releases:
;
@ -13,16 +14,16 @@
[Setup]
AppName=PuTTY
AppVerName=PuTTY version 0.59
VersionInfoTextVersion=Release 0.59
AppVersion=0.59
VersionInfoVersion=0.59.0.0
AppVerName=PuTTY version 0.60
VersionInfoTextVersion=Release 0.60
AppVersion=0.60
VersionInfoVersion=0.60.0.0
AppPublisher=Simon Tatham
AppPublisherURL=http://www.chiark.greenend.org.uk/~sgtatham/putty/
AppReadmeFile={app}\README.txt
DefaultDirName={pf}\PuTTY
DefaultGroupName=PuTTY
SetupIconFile=installer.ico
SetupIconFile=puttyins.ico
UninstallDisplayIcon={app}\putty.exe
ChangesAssociations=yes
;ChangesEnvironment=yes -- when PATH munging is sorted (probably)
@ -92,3 +93,14 @@ Root: HKCR; Subkey: "PuTTYPrivateKey\shell\edit\command"; ValueType: string; Val
; XXX: it would be nice if this task weren't run if a silent uninstall is
; requested, but "skipifsilent" is disallowed.
Filename: "{app}\putty.exe"; Parameters: "-cleanup-during-uninstall"; RunOnceId: "PuTTYCleanup"; StatusMsg: "Cleaning up saved sessions etc (optional)..."
[Messages]
; Since it's possible for the user to be asked to restart their computer,
; we should override the default messages to explain exactly why, so they
; can make an informed decision. (Especially as 95% of users won't need or
; want to restart; see rant above.)
FinishedRestartLabel=One or more [name] programs are still running. Setup will not replace these program files until you restart your computer. Would you like to restart now?
; This message is popped up in a message box on a /SILENT install.
FinishedRestartMessage=One or more [name] programs are still running.%nSetup will not replace these program files until you restart your computer.%n%nWould you like to restart now?
; ...and this comes up if you try to uninstall.
UninstalledAndNeedsRestart=One or more %1 programs are still running.%nThe program files will not be removed until your computer is restarted.%n%nWould you like to restart now?

Просмотреть файл

@ -38,7 +38,7 @@ BEGIN
PUSHBUTTON "View &Licence", 101, 6, 52, 70, 14
CTEXT "PuTTYgen", 102, 10, 6, 120, 8
CTEXT "", 100, 10, 16, 120, 16
CTEXT "\251 1997-2007 Simon Tatham. All rights reserved.",
CTEXT "\251 1997-2008 Simon Tatham. All rights reserved.",
103, 10, 34, 120, 16
END
@ -50,7 +50,7 @@ FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "OK", IDOK, 98, 243, 44, 14
LTEXT "Copyright \251 1997-2007 Simon Tatham", 1000, 10, 10, 206, 8
LTEXT "Copyright \251 1997-2008 Simon Tatham", 1000, 10, 10, 206, 8
LTEXT "Portions copyright Robert de Bath, Joris van Rantwijk, Delian", 1001, 10, 26, 206, 8
LTEXT "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas", 1002, 10, 34, 206, 8

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 11 KiB

После

Ширина:  |  Высота:  |  Размер: 11 KiB

Просмотреть файл

@ -39,24 +39,37 @@
/* We keep this around even for snapshots, for monotonicity of version
* numbering. It needs to be kept up to date. NB _comma_-separated. */
#define BASE_VERSION 0,59
#define BASE_VERSION 0,60
#if defined SNAPSHOT
/* Make SVN_REV mandatory for snapshots, to avoid issuing binary
* version numbers that look like full releases. */
#if (!defined SVN_REV) || (SVN_REV == 0)
#ifndef SVN_REV
#error SVN_REV not defined/nonzero for snapshot build
#endif
#define VERSION_TEXT "Development snapshot " STR(SNAPSHOT) ":r" STR(SVN_REV)
#ifdef MODIFIED
#define BINARY_VERSION 0,0,0,0
#else
#define BINARY_VERSION BASE_VERSION,SVN_REV,0
#endif
#elif defined RELEASE
#define VERSION_TEXT "Release " STR(RELEASE)
#define BINARY_VERSION BASE_VERSION,0,0
#elif defined SVN_REV
#define VERSION_TEXT "Custom build r" STR(SVN_REV)
#ifdef MODIFIED
#define BINARY_VERSION 0,0,0,0
#else
#define BINARY_VERSION BASE_VERSION,SVN_REV,0
#endif
#else
/* We can't reliably get the same date and time as version.c, so
@ -102,7 +115,7 @@ BEGIN
VALUE "OriginalFilename", APPNAME
VALUE "FileVersion", VERSION_TEXT
VALUE "ProductVersion", VERSION_TEXT
VALUE "LegalCopyright", "Copyright \251 1997-2007 Simon Tatham."
VALUE "LegalCopyright", "Copyright \251 1997-2008 Simon Tatham."
#if (!defined SNAPSHOT) && (!defined RELEASE)
/* Only if VS_FF_PRIVATEBUILD. */
VALUE "PrivateBuild", VERSION_TEXT /* NBI */

Просмотреть файл

@ -26,7 +26,7 @@ BEGIN
PUSHBUTTON "Visit &Web Site", IDA_WEB, 84, 52, 70, 14
CTEXT "PuTTY", IDA_TEXT1, 10, 6, 194, 8
CTEXT "", IDA_VERSION, 10, 16, 194, 16
CTEXT "\251 1997-2007 Simon Tatham. All rights reserved.",
CTEXT "\251 1997-2008 Simon Tatham. All rights reserved.",
IDA_TEXT2, 10, 34, 194, 16
END
@ -58,7 +58,7 @@ FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "OK", IDOK, 98, 243, 44, 14
LTEXT "Copyright \251 1997-2007 Simon Tatham", 1000, 10, 10, 206, 8
LTEXT "Copyright \251 1997-2008 Simon Tatham", 1000, 10, 10, 206, 8
LTEXT "Portions copyright Robert de Bath, Joris van Rantwijk, Delian", 1001, 10, 26, 206, 8
LTEXT "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas", 1002, 10, 34, 206, 8

Просмотреть файл

@ -2194,8 +2194,13 @@ int dlg_listbox_index(union control *ctrl, void *dlg)
struct dlgparam *dp = (struct dlgparam *)dlg;
struct winctrl *c = dlg_findbyctrl(dp, ctrl);
int msg, ret;
assert(c && c->ctrl->generic.type == CTRL_LISTBOX &&
!c->ctrl->listbox.multisel);
assert(c && c->ctrl->generic.type == CTRL_LISTBOX);
if (c->ctrl->listbox.multisel) {
assert(c->ctrl->listbox.height != 0); /* not combo box */
ret = SendDlgItemMessage(dp->hwnd, c->base_id+1, LB_GETSELCOUNT, 0, 0);
if (ret == LB_ERR || ret > 1)
return -1;
}
msg = (c->ctrl->listbox.height != 0 ? LB_GETCURSEL : CB_GETCURSEL);
ret = SendDlgItemMessage(dp->hwnd, c->base_id+1, msg, 0, 0);
if (ret == LB_ERR)

Просмотреть файл

@ -219,12 +219,7 @@ static void start_backend(void)
* Select protocol. This is farmed out into a table in a
* separate file to enable an ssh-free variant.
*/
back = NULL;
for (i = 0; backends[i].backend != NULL; i++)
if (backends[i].protocol == cfg.protocol) {
back = backends[i].backend;
break;
}
back = backend_from_proto(cfg.protocol);
if (back == NULL) {
char *str = dupprintf("%s Internal Error", appname);
MessageBox(NULL, "Unsupported protocol number found",
@ -361,17 +356,18 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
{
char *p;
int got_host = 0;
/* By default, we bring up the config dialog, rather than launching
* a session. This gets set to TRUE if something happens to change
* that (e.g., a hostname is specified on the command-line). */
int allow_launch = FALSE;
default_protocol = be_default_protocol;
/* Find the appropriate default port. */
{
int i;
Backend *b = backend_from_proto(default_protocol);
default_port = 0; /* illegal */
for (i = 0; backends[i].backend != NULL; i++)
if (backends[i].protocol == default_protocol) {
default_port = backends[i].backend->default_port;
break;
}
if (b)
default_port = b->default_port;
}
cfg.logtype = LGTYP_NONE;
@ -397,6 +393,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
if (!cfg_launchable(&cfg) && !do_config()) {
cleanup_exit(0);
}
allow_launch = TRUE; /* allow it to be launched directly */
} else if (*p == '&') {
/*
* An initial & means we've been given a command line
@ -415,6 +412,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
} else if (!do_config()) {
cleanup_exit(0);
}
allow_launch = TRUE;
} else {
/*
* Otherwise, break up the command line and deal with
@ -539,7 +537,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
cmdline_run_saved(&cfg);
if (!cfg_launchable(&cfg) && !do_config()) {
if (loaded_session || got_host)
allow_launch = TRUE;
if ((!allow_launch || !cfg_launchable(&cfg)) && !do_config()) {
cleanup_exit(0);
}
@ -596,15 +597,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
}
}
/* Check for invalid Port number (i.e. zero) */
if (cfg.port == 0) {
char *str = dupprintf("%s Internal Error", appname);
MessageBox(NULL, "Invalid Port Number",
str, MB_OK | MB_ICONEXCLAMATION);
sfree(str);
cleanup_exit(1);
}
if (!prev) {
wndclass.style = 0;
wndclass.lpfnWndProc = WndProc;
@ -816,9 +808,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
sfree(handles);
if (must_close_session)
close_session();
}
sfree(handles);
} else
sfree(handles);
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT)
@ -3564,8 +3555,9 @@ int char_width(Context ctx, int uc) {
/*
* Translate a WM_(SYS)?KEY(UP|DOWN) message into a string of ASCII
* codes. Returns number of bytes used or zero to drop the message
* or -1 to forward the message to windows.
* codes. Returns number of bytes used, zero to drop the message,
* -1 to forward the message to Windows, or another negative number
* to indicate a NUL-terminated "special" string.
*/
static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
unsigned char *output)
@ -3985,9 +3977,9 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
return p - output;
}
if (wParam == VK_CANCEL && shift_state == 2) { /* Ctrl-Break */
*p++ = 3;
*p++ = 0;
return -2;
if (back)
back->special(backhandle, TS_BRK);
return 0;
}
if (wParam == VK_PAUSE) { /* Break/Pause */
*p++ = 26;

Просмотреть файл

@ -96,7 +96,7 @@ struct handle_input {
*/
char buffer[4096]; /* the data read from the handle */
DWORD len; /* how much data that was */
int readret; /* lets us know about read errors */
int readerr; /* lets us know about read errors */
/*
* Callback function called by this module when data arrives on
@ -113,7 +113,7 @@ static DWORD WINAPI handle_input_threadfunc(void *param)
struct handle_input *ctx = (struct handle_input *) param;
OVERLAPPED ovl, *povl;
HANDLE oev;
int readlen;
int readret, readlen;
if (ctx->flags & HANDLE_FLAG_OVERLAPPED) {
povl = &ovl;
@ -132,17 +132,34 @@ static DWORD WINAPI handle_input_threadfunc(void *param)
memset(povl, 0, sizeof(OVERLAPPED));
povl->hEvent = oev;
}
ctx->readret = ReadFile(ctx->h, ctx->buffer, readlen,
&ctx->len, povl);
if (povl && !ctx->readret && GetLastError() == ERROR_IO_PENDING) {
readret = ReadFile(ctx->h, ctx->buffer,readlen, &ctx->len, povl);
if (!readret)
ctx->readerr = GetLastError();
else
ctx->readerr = 0;
if (povl && !readret && ctx->readerr == ERROR_IO_PENDING) {
WaitForSingleObject(povl->hEvent, INFINITE);
ctx->readret = GetOverlappedResult(ctx->h, povl, &ctx->len, FALSE);
readret = GetOverlappedResult(ctx->h, povl, &ctx->len, FALSE);
if (!readret)
ctx->readerr = GetLastError();
else
ctx->readerr = 0;
}
if (!ctx->readret)
if (!readret) {
/*
* Windows apparently sends ERROR_BROKEN_PIPE when a
* pipe we're reading from is closed normally from the
* writing end. This is ludicrous; if that situation
* isn't a natural EOF, _nothing_ is. So if we get that
* particular error, we pretend it's EOF.
*/
if (ctx->readerr == ERROR_BROKEN_PIPE)
ctx->readerr = 0;
ctx->len = 0;
}
if (ctx->readret && ctx->len == 0 &&
if (readret && ctx->len == 0 &&
(ctx->flags & HANDLE_FLAG_IGNOREEOF))
continue;
@ -227,7 +244,7 @@ struct handle_output {
* and read by the main thread after receiving that signal.
*/
DWORD lenwritten; /* how much data we actually wrote */
int writeret; /* return value from WriteFile */
int writeerr; /* return value from WriteFile */
/*
* Data only ever read or written by the main thread.
@ -245,6 +262,7 @@ static DWORD WINAPI handle_output_threadfunc(void *param)
{
struct handle_output *ctx = (struct handle_output *) param;
OVERLAPPED ovl, *povl;
int writeret;
if (ctx->flags & HANDLE_FLAG_OVERLAPPED)
povl = &ovl;
@ -259,14 +277,23 @@ static DWORD WINAPI handle_output_threadfunc(void *param)
}
if (povl)
memset(povl, 0, sizeof(OVERLAPPED));
ctx->writeret = WriteFile(ctx->h, ctx->buffer, ctx->len,
&ctx->lenwritten, povl);
if (povl && !ctx->writeret && GetLastError() == ERROR_IO_PENDING)
ctx->writeret = GetOverlappedResult(ctx->h, povl,
&ctx->lenwritten, TRUE);
writeret = WriteFile(ctx->h, ctx->buffer, ctx->len,
&ctx->lenwritten, povl);
if (!writeret)
ctx->writeerr = GetLastError();
else
ctx->writeerr = 0;
if (povl && !writeret && GetLastError() == ERROR_IO_PENDING) {
writeret = GetOverlappedResult(ctx->h, povl,
&ctx->lenwritten, TRUE);
if (!writeret)
ctx->writeerr = GetLastError();
else
ctx->writeerr = 0;
}
SetEvent(ctx->ev_to_main);
if (!ctx->writeret)
if (!writeret)
break;
}
@ -512,7 +539,7 @@ void handle_got_event(HANDLE event)
/*
* EOF, or (nearly equivalently) read error.
*/
h->u.i.gotdata(h, NULL, (h->u.i.readret ? 0 : -1));
h->u.i.gotdata(h, NULL, -h->u.i.readerr);
h->u.i.defunct = TRUE;
} else {
backlog = h->u.i.gotdata(h, h->u.i.buffer, h->u.i.len);
@ -526,13 +553,13 @@ void handle_got_event(HANDLE event)
* write. Call the callback to indicate that the output
* buffer size has decreased, or to indicate an error.
*/
if (!h->u.o.writeret) {
if (h->u.o.writeerr) {
/*
* Write error. Send a negative value to the callback,
* and mark the thread as defunct (because the output
* thread is terminating by now).
*/
h->u.o.sentdata(h, -1);
h->u.o.sentdata(h, -h->u.o.writeerr);
h->u.o.defunct = TRUE;
} else {
bufchain_consume(&h->u.o.queued_data, h->u.o.lenwritten);

Просмотреть файл

@ -21,7 +21,6 @@ static int help_has_contents;
#ifndef NO_HTMLHELP
typedef HWND (CALLBACK *htmlhelp_t)(HWND, LPCSTR, UINT, DWORD);
static char *chm_path;
static DWORD html_help_cookie;
static htmlhelp_t htmlhelp;
#endif /* NO_HTMLHELP */
@ -63,9 +62,7 @@ void init_help(void)
if (!htmlhelp)
FreeLibrary(dllHH);
}
if (htmlhelp)
htmlhelp(NULL, NULL, HH_INITIALIZE, (DWORD)&html_help_cookie);
else
if (!htmlhelp)
chm_path = NULL;
}
#endif /* NO_HTMLHELP */
@ -73,10 +70,9 @@ void init_help(void)
void shutdown_help(void)
{
#ifndef NO_HTMLHELP
if (chm_path)
htmlhelp(NULL, NULL, HH_UNINITIALIZE, html_help_cookie);
#endif /* NO_HTMLHELP */
/* Nothing to do currently.
* (If we were running HTML Help single-threaded, this is where we'd
* call HH_UNINITIALIZE.) */
}
int has_help(void)

Просмотреть файл

@ -42,6 +42,7 @@
#define WINHELP_CTX_terminal_autowrap "terminal.autowrap:config-autowrap"
#define WINHELP_CTX_terminal_decom "terminal.decom:config-decom"
#define WINHELP_CTX_terminal_lfhascr "terminal.lfhascr:config-crlf"
#define WINHELP_CTX_terminal_crhaslf "terminal.crhaslf:config-lfcr"
#define WINHELP_CTX_terminal_bce "terminal.bce:config-erase"
#define WINHELP_CTX_terminal_blink "terminal.blink:config-blink"
#define WINHELP_CTX_terminal_answerback "terminal.answerback:config-answerback"
@ -130,6 +131,7 @@
#define WINHELP_CTX_ssh_bugs_rsapad2 "ssh.bugs.rsapad2:config-ssh-bug-sig"
#define WINHELP_CTX_ssh_bugs_pksessid2 "ssh.bugs.pksessid2:config-ssh-bug-pksessid2"
#define WINHELP_CTX_ssh_bugs_rekey2 "ssh.bugs.rekey2:config-ssh-bug-rekey"
#define WINHELP_CTX_ssh_bugs_maxpkt2 "ssh.bugs.maxpkt2:config-ssh-bug-maxpkt2"
#define WINHELP_CTX_serial_line "serial.line:config-serial-line"
#define WINHELP_CTX_serial_speed "serial.speed:config-serial-speed"
#define WINHELP_CTX_serial_databits "serial.databits:config-serial-databits"

Просмотреть файл

@ -96,6 +96,10 @@ static int cmpfortree(void *av, void *bv)
return -1;
if (as > bs)
return +1;
if (a < b)
return -1;
if (a > b)
return +1;
return 0;
}
@ -788,6 +792,14 @@ static DWORD try_connect(Actual_Socket sock)
family = AF_INET;
}
/*
* Remove the socket from the tree before we overwrite its
* internal socket id, because that forms part of the tree's
* sorting criterion. We'll add it back before exiting this
* function, whether we changed anything or not.
*/
del234(sktree, sock);
s = p_socket(family, SOCK_STREAM, 0);
sock->s = s;
@ -932,11 +944,15 @@ static DWORD try_connect(Actual_Socket sock)
sock->writable = 1;
}
add234(sktree, sock);
err = 0;
ret:
/*
* No matter what happened, put the socket back in the tree.
*/
add234(sktree, sock);
if (err)
plug_log(sock->plug, 1, sock->addr, sock->port, sock->error, err);
return err;

Просмотреть файл

@ -228,7 +228,13 @@ int stdin_gotdata(struct handle *h, void *data, int len)
/*
* Special case: report read error.
*/
fprintf(stderr, "Unable to read from standard input\n");
char buf[4096];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, -len, 0,
buf, lenof(buf), NULL);
buf[lenof(buf)-1] = '\0';
if (buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = '\0';
fprintf(stderr, "Unable to read from standard input: %s\n", buf);
cleanup_exit(0);
}
noise_ultralight(len);
@ -249,8 +255,14 @@ void stdouterr_sent(struct handle *h, int new_backlog)
/*
* Special case: report write error.
*/
fprintf(stderr, "Unable to write to standard %s\n",
(h == stdout_handle ? "output" : "error"));
char buf[4096];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, -new_backlog, 0,
buf, lenof(buf), NULL);
buf[lenof(buf)-1] = '\0';
if (buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = '\0';
fprintf(stderr, "Unable to write to standard %s: %s\n",
(h == stdout_handle ? "output" : "error"), buf);
cleanup_exit(0);
}
if (connopen && back->connected(backhandle)) {
@ -295,13 +307,10 @@ int main(int argc, char **argv)
char *p = getenv("PLINK_PROTOCOL");
int i;
if (p) {
for (i = 0; backends[i].backend != NULL; i++) {
if (!strcmp(backends[i].name, p)) {
default_protocol = cfg.protocol = backends[i].protocol;
default_port = cfg.port =
backends[i].backend->default_port;
break;
}
const Backend *b = backend_from_name(p);
if (b) {
default_protocol = cfg.protocol = b->protocol;
default_port = cfg.port = b->default_port;
}
}
}
@ -368,19 +377,14 @@ int main(int argc, char **argv)
*/
r = strchr(p, ',');
if (r) {
int i, j;
for (i = 0; backends[i].backend != NULL; i++) {
j = strlen(backends[i].name);
if (j == r - p &&
!memcmp(backends[i].name, p, j)) {
default_protocol = cfg.protocol =
backends[i].protocol;
portnumber =
backends[i].backend->default_port;
p = r + 1;
break;
}
const Backend *b;
*r = '\0';
b = backend_from_name(p);
if (b) {
default_protocol = cfg.protocol = b->protocol;
portnumber = b->default_port;
}
p = r + 1;
}
/*
@ -523,19 +527,11 @@ int main(int argc, char **argv)
* Select protocol. This is farmed out into a table in a
* separate file to enable an ssh-free variant.
*/
{
int i;
back = NULL;
for (i = 0; backends[i].backend != NULL; i++)
if (backends[i].protocol == cfg.protocol) {
back = backends[i].backend;
break;
}
if (back == NULL) {
fprintf(stderr,
"Internal fault: Unsupported protocol found\n");
return 1;
}
back = backend_from_proto(cfg.protocol);
if (back == NULL) {
fprintf(stderr,
"Internal fault: Unsupported protocol found\n");
return 1;
}
/*

Просмотреть файл

@ -21,7 +21,7 @@ struct printer_job_tag {
static char *printer_add_enum(int param, DWORD level, char *buffer,
int offset, int *nprinters_ptr)
{
DWORD needed, nprinters;
DWORD needed = 0, nprinters = 0;
buffer = sresize(buffer, offset+512, char);

Просмотреть файл

@ -221,8 +221,39 @@ static const char *serial_init(void *frontend_handle, void **backend_handle,
logevent(serial->frontend, msg);
}
serport = CreateFile(cfg->serline, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
{
/*
* Munge the string supplied by the user into a Windows filename.
*
* Windows supports opening a few "legacy" devices (including
* COM1-9) by specifying their names verbatim as a filename to
* open. (Thus, no files can ever have these names. See
* <http://msdn2.microsoft.com/en-us/library/aa365247.aspx>
* ("Naming a File") for the complete list of reserved names.)
*
* However, this doesn't let you get at devices COM10 and above.
* For that, you need to specify a filename like "\\.\COM10".
* This is also necessary for special serial and serial-like
* devices such as \\.\WCEUSBSH001. It also works for the "legacy"
* names, so you can do \\.\COM1 (verified as far back as Win95).
* See <http://msdn2.microsoft.com/en-us/library/aa363858.aspx>
* (CreateFile() docs).
*
* So, we believe that prepending "\\.\" should always be the
* Right Thing. However, just in case someone finds something to
* talk to that doesn't exist under there, if the serial line
* contains a backslash, we use it verbatim. (This also lets
* existing configurations using \\.\ continue working.)
*/
char *serfilename =
dupprintf("%s%s",
strchr(cfg->serline, '\\') ? "" : "\\\\.\\",
cfg->serline);
serport = CreateFile(serfilename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
sfree(serfilename);
}
if (serport == INVALID_HANDLE_VALUE)
return "Unable to open serial port";
@ -423,5 +454,7 @@ Backend serial_backend = {
serial_provide_logctx,
serial_unthrottle,
serial_cfg_info,
1
"serial",
PROT_SERIAL,
0
};