зеркало из https://github.com/github/putty.git
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:
Коммит
822628246e
|
@ -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
|
89
CHECKLST.txt
89
CHECKLST.txt
|
@ -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
|
||||
|
|
2
LICENCE
2
LICENCE
|
@ -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
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
|
||||
|
|
12
be_all.c
12
be_all.c
|
@ -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
|
||||
};
|
||||
|
|
14
be_all_s.c
14
be_all_s.c
|
@ -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
|
||||
};
|
||||
|
|
13
be_none.c
13
be_none.c
|
@ -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
|
||||
};
|
||||
|
|
12
be_nos_s.c
12
be_nos_s.c
|
@ -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
be_nossh.c
10
be_nossh.c
|
@ -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
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
5
cmdgen.c
5
cmdgen.c
|
@ -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);
|
||||
|
|
24
cmdline.c
24
cmdline.c
|
@ -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
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.
|
||||
|
|
14
doc/faq.but
14
doc/faq.but
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
28
mkfiles.pl
28
mkfiles.pl
|
@ -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
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
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
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
4
raw.c
|
@ -278,5 +278,7 @@ Backend raw_backend = {
|
|||
raw_provide_logctx,
|
||||
raw_unthrottle,
|
||||
raw_cfg_info,
|
||||
1
|
||||
"raw",
|
||||
PROT_RAW,
|
||||
0
|
||||
};
|
||||
|
|
4
rlogin.c
4
rlogin.c
|
@ -349,5 +349,7 @@ Backend rlogin_backend = {
|
|||
rlogin_provide_logctx,
|
||||
rlogin_unthrottle,
|
||||
rlogin_cfg_info,
|
||||
1
|
||||
"rlogin",
|
||||
PROT_RLOGIN,
|
||||
513
|
||||
};
|
||||
|
|
16
sercfg.c
16
sercfg.c
|
@ -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 &&
|
||||
|
|
76
settings.c
76
settings.c
|
@ -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)
|
||||
|
|
|
@ -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
1037
ssh.c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
23
ssh.h
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;
|
||||
|
|
2
sshdes.c
2
sshdes.c
|
@ -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
|
||||
|
|
8
sshdh.c
8
sshdh.c
|
@ -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[] = {
|
||||
|
|
4
sshdss.c
4
sshdss.c
|
@ -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
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
|
||||
};
|
||||
|
|
2
telnet.c
2
telnet.c
|
@ -1106,5 +1106,7 @@ Backend telnet_backend = {
|
|||
telnet_provide_logctx,
|
||||
telnet_unthrottle,
|
||||
telnet_cfg_info,
|
||||
"telnet",
|
||||
PROT_TELNET,
|
||||
23
|
||||
};
|
||||
|
|
30
terminal.c
30
terminal.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
14
testback.c
14
testback.c
|
@ -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 */
|
||||
}
|
||||
|
||||
|
|
20
unix/unix.h
20
unix/unix.h
|
@ -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)
|
||||
|
|
24
unix/uxnet.c
24
unix/uxnet.c
|
@ -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?! */
|
||||
|
|
141
unix/uxplink.c
141
unix/uxplink.c
|
@ -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. */
|
||||
}
|
||||
|
|
14
unix/uxpty.c
14
unix/uxpty.c
|
@ -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
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче