├── LATEST.VER ├── wcwidth-update ├── .gitignore └── get-unidata ├── windows ├── pscp.ico ├── putty.ico ├── pageant.ico ├── pageants.ico ├── puttycfg.ico ├── puttygen.ico ├── puttyins.ico ├── website.url ├── pscp.rc ├── psftp.rc ├── plink.rc ├── putty.rc ├── puttytel.rc ├── winnojmp.c ├── wincapi.h ├── winx11.c ├── wintime.c ├── win_res.h ├── windefs.c ├── wincapi.c ├── rcstuff.h ├── pageant.mft ├── puttygen.mft ├── putty.mft ├── README.txt ├── puttygen.rc ├── README-msi.txt ├── version.rc2 ├── pageant.rc ├── win_res.rc2 ├── winsecur.h ├── winnpc.c └── winhelp.c ├── contrib ├── nice-ibeam.cur ├── cygtermd │ ├── Makefile │ ├── README │ ├── pty.h │ ├── malloc.c │ ├── telnet.h │ └── malloc.h ├── logrewrap.pl └── gdb.py ├── unix ├── configure ├── uxnogtk.c ├── x11misc.h ├── gtkmisc.h ├── uxpeer.c ├── ux_x11.c ├── pterm.plist ├── putty.plist ├── uxsignal.c ├── uxpterm.c ├── uxprint.c ├── pterm.bundle ├── uxgen.c ├── gtkcols.h ├── uxputty.c ├── x11misc.c ├── uxcfg.c ├── putty.bundle ├── uxsel.c └── uxnoise.c ├── doc ├── mancfg.but ├── manpages.but ├── vids.but ├── site.but ├── chm.css ├── blurb.but ├── Makefile └── sshnames.but ├── cgtest.c ├── testdata ├── lattrs.txt ├── scocols.txt ├── display.txt ├── vt100.txt └── utf8.txt ├── be_none.c ├── noterm.c ├── rdb ├── makefile ├── No_SSH-0.53.dif ├── No_SSH-0.53b.dif ├── 24-bit-color ├── No_SSH-0.51.dif ├── No_SSH-0.46.dif ├── Missing-patches │ ├── BELL.diff │ ├── 0041 Update multimon.h support.diff │ └── rdb24bit │ │ ├── 0010-ITU-T-T.416-truecolour-fuzzterm.patch │ │ └── 0008-Add-flag-to-reduce-scrollback-memory-consumption.patch ├── No_SSH-0.48.dif ├── No_SSH-0.45.dif ├── No_SSH-0.47.dif ├── mkzip.sh ├── win256c.txt ├── git-commit-putty-bin ├── mk_pcodes.sh ├── dbcs_chars.sh ├── ITU-T-T.416-P41.txt └── pickscript ├── GNUmakefile ├── puttyps.h ├── nogss.c ├── mkauto.sh ├── time.c ├── sshnogss.c ├── resource.h ├── be_ssh.c ├── pproxy.c ├── sshgssc.h ├── sshblowf.h ├── aqsync.c ├── be_nossh.c ├── charset ├── slookup.c ├── enum.c ├── README ├── sbcs.c ├── toucs.c ├── fromucs.c ├── xenc.c ├── sbcsgen.pl └── internal.h ├── be_nos_s.c ├── notiming.c ├── noshare.c ├── version.c ├── ldisc.h ├── noprint.c ├── int64.h ├── miscucs.c ├── be_all.c ├── be_all_s.c ├── icons └── cicon.pl ├── nocproxy.c ├── nullplug.c ├── mksrcarc.sh ├── mkunxarc.sh ├── Buildscr.cv ├── LICENCE ├── nocmdline.c ├── errsock.c ├── version.h ├── sign.sh ├── sshbpp.h ├── pinger.c ├── sshcr.h ├── sshecdsag.c ├── README.md ├── .gitignore ├── defs.h ├── puttymem.h ├── ssh1censor.c ├── sessprep.c ├── ldiscucs.c ├── licence.pl ├── ssharcf.c ├── proxy.h ├── callback.c └── be_misc.c /LATEST.VER: -------------------------------------------------------------------------------- 1 | 0.70 2 | -------------------------------------------------------------------------------- /wcwidth-update/.gitignore: -------------------------------------------------------------------------------- 1 | UNIDATA* 2 | *.c 3 | -------------------------------------------------------------------------------- /windows/pscp.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdebath/PuTTY/HEAD/windows/pscp.ico -------------------------------------------------------------------------------- /windows/putty.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdebath/PuTTY/HEAD/windows/putty.ico -------------------------------------------------------------------------------- /windows/pageant.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdebath/PuTTY/HEAD/windows/pageant.ico -------------------------------------------------------------------------------- /contrib/nice-ibeam.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdebath/PuTTY/HEAD/contrib/nice-ibeam.cur -------------------------------------------------------------------------------- /unix/configure: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | $(echo "$0" | sed '$s!configure$!../configure!') "$@" 4 | -------------------------------------------------------------------------------- /windows/pageants.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdebath/PuTTY/HEAD/windows/pageants.ico -------------------------------------------------------------------------------- /windows/puttycfg.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdebath/PuTTY/HEAD/windows/puttycfg.ico -------------------------------------------------------------------------------- /windows/puttygen.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdebath/PuTTY/HEAD/windows/puttygen.ico -------------------------------------------------------------------------------- /windows/puttyins.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdebath/PuTTY/HEAD/windows/puttyins.ico -------------------------------------------------------------------------------- /doc/mancfg.but: -------------------------------------------------------------------------------- 1 | \cfg{man-mindepth}{2} 2 | 3 | \C{not-shown} Chapter title which is not shown 4 | -------------------------------------------------------------------------------- /doc/manpages.but: -------------------------------------------------------------------------------- 1 | \A{man-pages} Man pages for Unix PuTTY 2 | 3 | This appendix contains all the man pages for Unix PuTTY. 4 | -------------------------------------------------------------------------------- /windows/website.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=https://www.chiark.greenend.org.uk/~sgtatham/putty/ 3 | -------------------------------------------------------------------------------- /cgtest.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cgtest.c: stub file to compile cmdgen.c in self-test mode 3 | */ 4 | 5 | #define TEST_CMDGEN 6 | #include "cmdgen.c" 7 | -------------------------------------------------------------------------------- /contrib/cygtermd/Makefile: -------------------------------------------------------------------------------- 1 | cygtermd.exe: main.c sel.c telnet.c pty.c malloc.c 2 | gcc -o cygtermd.exe main.c sel.c telnet.c pty.c malloc.c 3 | -------------------------------------------------------------------------------- /doc/vids.but: -------------------------------------------------------------------------------- 1 | \# Fallback versionid for use when the build system hasn't provided a 2 | better one. 3 | 4 | \versionid no version information available 5 | -------------------------------------------------------------------------------- /testdata/lattrs.txt: -------------------------------------------------------------------------------- 1 | Test of line attributes: 2 | 3 | #3Double-height top 4 | #4Double-height bottom 5 | #5Normal text (#5) 6 | #6Double-width only 7 | -------------------------------------------------------------------------------- /windows/pscp.rc: -------------------------------------------------------------------------------- 1 | #include "rcstuff.h" 2 | 3 | #define APPNAME "PSCP" 4 | #define APPDESC "Command-line SCP/SFTP client" 5 | 6 | 200 ICON "pscp.ico" 7 | 8 | #include "version.rc2" 9 | -------------------------------------------------------------------------------- /windows/psftp.rc: -------------------------------------------------------------------------------- 1 | #include "rcstuff.h" 2 | 3 | #define APPNAME "PSFTP" 4 | #define APPDESC "Command-line interactive SFTP client" 5 | 6 | 200 ICON "pscp.ico" 7 | 8 | #include "version.rc2" 9 | -------------------------------------------------------------------------------- /windows/plink.rc: -------------------------------------------------------------------------------- 1 | #include "rcstuff.h" 2 | 3 | #define APPNAME "Plink" 4 | #define APPDESC "Command-line SSH, Telnet, and Rlogin client" 5 | 6 | 200 ICON "putty.ico" 7 | 8 | #include "version.rc2" 9 | -------------------------------------------------------------------------------- /doc/site.but: -------------------------------------------------------------------------------- 1 | \# Additional configuration for the version of the PuTTY docs 2 | \# actually published as HTML on the website. 3 | 4 | \cfg{xhtml-head-end}{} 5 | -------------------------------------------------------------------------------- /be_none.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Linking module for programs that do not support selection of backend 3 | * (such as pterm). 4 | */ 5 | 6 | #include 7 | #include "putty.h" 8 | 9 | Backend *backends[] = { 10 | NULL 11 | }; 12 | -------------------------------------------------------------------------------- /noterm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Stubs of functions in terminal.c, for use in programs that don't 3 | * have a terminal. 4 | */ 5 | 6 | #include "putty.h" 7 | #include "terminal.h" 8 | 9 | void term_nopaste(Terminal *term) 10 | { 11 | } 12 | -------------------------------------------------------------------------------- /unix/uxnogtk.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uxnogtk.c: link into non-GUI Unix programs so that they can tell 3 | * buildinfo about a lack of GTK. 4 | */ 5 | 6 | #include "putty.h" 7 | 8 | char *buildinfo_gtk_version(void) 9 | { 10 | return NULL; 11 | } 12 | -------------------------------------------------------------------------------- /windows/putty.rc: -------------------------------------------------------------------------------- 1 | #include "rcstuff.h" 2 | 3 | #define APPNAME "PuTTY" 4 | #define APPDESC "SSH, Telnet and Rlogin client" 5 | 6 | #include "win_res.rc2" 7 | 8 | #ifndef NO_MANIFESTS 9 | 1 RT_MANIFEST "putty.mft" 10 | #endif /* NO_MANIFESTS */ 11 | -------------------------------------------------------------------------------- /rdb/makefile: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | @cmd /C "cd windows & nmake /NOLOGO /f Makefile.vc all" 4 | @copy windows\*.exe C:\USR\PUTTY 5 | 6 | clean: 7 | @cmd /C "cd windows & nmake /NOLOGO /f Makefile.vc clean" 8 | 9 | # This is a tiny makefile for VS on Windows. 10 | -------------------------------------------------------------------------------- /windows/puttytel.rc: -------------------------------------------------------------------------------- 1 | #include "rcstuff.h" 2 | 3 | #define APPNAME "PuTTYtel" 4 | #define APPDESC "Telnet and Rlogin client" 5 | 6 | #include "win_res.rc2" 7 | 8 | #ifndef NO_MANIFESTS 9 | /* FIXME */ 10 | 1 RT_MANIFEST "putty.mft" 11 | #endif /* NO_MANIFESTS */ 12 | -------------------------------------------------------------------------------- /doc/chm.css: -------------------------------------------------------------------------------- 1 | /* Stylesheet for a Windows .CHM help file */ 2 | 3 | body { font-size: 75%; font-family: Verdana, Arial, Helvetica, Sans-Serif; } 4 | 5 | h1 { font-weight: bold; font-size: 150%; } 6 | h2 { font-weight: bold; font-size: 130%; } 7 | h3 { font-weight: bold; font-size: 120%; } 8 | -------------------------------------------------------------------------------- /GNUmakefile: -------------------------------------------------------------------------------- 1 | # This is so I can do either an autoconf build or a local one. 2 | ifneq ($(wildcard Makefile),) 3 | include Makefile 4 | 5 | # Doesn't exist in autoconf makefiles. 6 | realclean: 7 | $(MAKE) -f Makefile.rdb realclean 8 | else 9 | include Makefile.rdb 10 | endif 11 | 12 | -------------------------------------------------------------------------------- /puttyps.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Find the platform-specific header for this platform. 3 | */ 4 | 5 | #ifndef PUTTY_PUTTYPS_H 6 | #define PUTTY_PUTTYPS_H 7 | 8 | #ifdef _WINDOWS 9 | 10 | #include "winstuff.h" 11 | 12 | #else 13 | 14 | #include "unix.h" 15 | 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /windows/winnojmp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * winnojmp.c: stub jump list functions for Windows executables that 3 | * don't update the jump list. 4 | */ 5 | 6 | void add_session_to_jumplist(const char * const sessionname) {} 7 | void remove_session_from_jumplist(const char * const sessionname) {} 8 | void clear_jumplist(void) {} 9 | -------------------------------------------------------------------------------- /nogss.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Stub definitions of the GSSAPI library list, for Unix pterm and 3 | * any other application that needs the symbols defined but has no 4 | * use for them. 5 | */ 6 | 7 | #include "putty.h" 8 | 9 | const int ngsslibs = 0; 10 | const char *const gsslibnames[1] = { "dummy" }; 11 | const struct keyvalwhere gsslibkeywords[1] = { { "dummy", 0, -1, -1 } }; 12 | -------------------------------------------------------------------------------- /rdb/No_SSH-0.53.dif: -------------------------------------------------------------------------------- 1 | diff --git a/window.c b/window.c 2 | index 9ea6c01..9315aeb 100644 3 | --- a/window.c 4 | +++ b/window.c 5 | @@ -77,6 +77,8 @@ 6 | #define WHEEL_DELTA 120 7 | #endif 8 | 9 | +static int is_shift_pressed(void); 10 | + 11 | static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 12 | static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, 13 | unsigned char *output); 14 | -------------------------------------------------------------------------------- /rdb/No_SSH-0.53b.dif: -------------------------------------------------------------------------------- 1 | diff --git a/window.c b/window.c 2 | index 9ea6c01..9315aeb 100644 3 | --- a/window.c 4 | +++ b/window.c 5 | @@ -77,6 +77,8 @@ 6 | #define WHEEL_DELTA 120 7 | #endif 8 | 9 | +static int is_shift_pressed(void); 10 | + 11 | static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 12 | static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, 13 | unsigned char *output); 14 | -------------------------------------------------------------------------------- /mkauto.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # This script makes the autoconf mechanism for the Unix port work. 3 | # It's separate from mkfiles.pl because it won't work (and isn't needed) 4 | # on a non-Unix system. 5 | 6 | # It's nice to be able to run this from inside the unix subdir as 7 | # well as from outside. 8 | test -f unix.h && cd .. 9 | 10 | # Run autoconf on our real configure.in. 11 | autoreconf -i && rm -rf autom4te.cache 12 | -------------------------------------------------------------------------------- /time.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Portable implementation of ltime() for any ISO-C platform where 3 | * time_t behaves. (In practice, we've found that platforms such as 4 | * Windows and Mac have needed their own specialised implementations.) 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | struct tm ltime(void) 11 | { 12 | time_t t; 13 | time(&t); 14 | assert (t != ((time_t)-1)); 15 | return *localtime(&t); 16 | } 17 | -------------------------------------------------------------------------------- /sshnogss.c: -------------------------------------------------------------------------------- 1 | #include "putty.h" 2 | #ifndef NO_GSSAPI 3 | 4 | /* For platforms not supporting GSSAPI */ 5 | 6 | struct ssh_gss_liblist *ssh_gss_setup(Conf *conf) 7 | { 8 | struct ssh_gss_liblist *list = snew(struct ssh_gss_liblist *); 9 | list->libraries = NULL; 10 | list->nlibraries = 0; 11 | return list; 12 | } 13 | 14 | void ssh_gss_cleanup(struct ssh_gss_liblist *list) 15 | { 16 | sfree(list); 17 | } 18 | 19 | #endif /* NO_GSSAPI */ 20 | -------------------------------------------------------------------------------- /resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Developer Studio generated include file. 3 | // Used by win_res.rc 4 | // 5 | 6 | // Next default values for new objects 7 | // 8 | #ifdef APSTUDIO_INVOKED 9 | #ifndef APSTUDIO_READONLY_SYMBOLS 10 | #define _APS_NEXT_RESOURCE_VALUE 101 11 | #define _APS_NEXT_COMMAND_VALUE 40001 12 | #define _APS_NEXT_CONTROL_VALUE 1000 13 | #define _APS_NEXT_SYMED_VALUE 101 14 | #endif 15 | #endif 16 | -------------------------------------------------------------------------------- /be_ssh.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Linking module for programs that are restricted to only using SSH 3 | * (pscp and psftp). These do not support selection of backend, but 4 | * must still have a backends[] array mentioning SSH because 5 | * settings.c will want to consult it during session load. 6 | */ 7 | 8 | #include 9 | #include "putty.h" 10 | 11 | const int be_default_protocol = PROT_SSH; 12 | 13 | Backend *backends[] = { 14 | &ssh_backend, 15 | NULL 16 | }; 17 | -------------------------------------------------------------------------------- /windows/wincapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * wincapi.h: Windows Crypto API functions defined in wincrypt.c 3 | * that use the crypt32 library. Also centralises the machinery 4 | * for dynamically loading that library. 5 | */ 6 | 7 | #if !defined NO_SECURITY 8 | 9 | #ifndef WINCAPI_GLOBAL 10 | #define WINCAPI_GLOBAL extern 11 | #endif 12 | 13 | DECL_WINDOWS_FUNCTION(WINCAPI_GLOBAL, BOOL, CryptProtectMemory, 14 | (LPVOID,DWORD,DWORD)); 15 | 16 | int got_crypt(void); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /testdata/scocols.txt: -------------------------------------------------------------------------------- 1 | Test of (destructive) SCO colour rendering. 2 | SCO fg: [=0F0[=7F [=1F1[=7F [=2F2[=7F [=3F3[=7F [=4F4[=7F [=5F5[=7F [=6F6[=7F [=7F7[=7F [=8F8[=7F [=9F9[=7F [=10F10[=7F [=11F11[=7F [=12F12[=7F [=13F13[=7F [=14F14[=7F [=15F15[=7F 3 | SCO bg: [=0G0[=0G [=1G1[=0G [=2G2[=0G [=3G3[=0G [=4G4[=0G [=5G5[=0G [=6G6[=0G [=7G7[=0G [=8G8[=0G [=9G9[=0G [=10G10[=0G [=11G11[=0G [=12G12[=0G [=13G13[=0G [=14G14[=0G [=15G15[=0G 4 | -------------------------------------------------------------------------------- /pproxy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * pproxy.c: dummy implementation of platform_new_connection(), to 3 | * be supplanted on any platform which has its own local proxy 4 | * method. 5 | */ 6 | 7 | #include "putty.h" 8 | #include "network.h" 9 | #include "proxy.h" 10 | 11 | Socket platform_new_connection(SockAddr addr, const char *hostname, 12 | int port, int privport, 13 | int oobinline, int nodelay, int keepalive, 14 | Plug plug, Conf *conf) 15 | { 16 | return NULL; 17 | } 18 | -------------------------------------------------------------------------------- /rdb/24-bit-color: -------------------------------------------------------------------------------- 1 | #!/usr/bin/awk -f 2 | true , /; exec awk -f "$0" -- "$@" ; exit; / {} 3 | BEGIN{ 4 | 5 | s="/\\/\\/\\/\\/\\"; s=s s s s s s s s; 6 | for (colnum = 0; colnum<77; colnum++) { 7 | r = 255-(colnum*255/76); 8 | g = (colnum*510/76); 9 | b = (colnum*255/76); 10 | if (g>255) g = 510-g; 11 | 12 | printf "\033[48;2;%d;%d;%dm", r,g,b; 13 | printf "\033[38;2;%d;%d;%dm", 255-r,255-g,255-b; 14 | printf "%s\033[0m", substr(s,colnum+1,1); 15 | } 16 | printf "\n"; 17 | exit 18 | } 19 | -------------------------------------------------------------------------------- /windows/winx11.c: -------------------------------------------------------------------------------- 1 | /* 2 | * winx11.c: fetch local auth data for X forwarding. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "putty.h" 10 | #include "ssh.h" 11 | 12 | void platform_get_x11_auth(struct X11Display *disp, Conf *conf) 13 | { 14 | char *xauthpath = conf_get_filename(conf, CONF_xauthfile)->path; 15 | if (xauthpath[0]) 16 | x11_get_auth_from_authfile(disp, xauthpath); 17 | } 18 | 19 | const int platform_uses_x11_unix_by_default = FALSE; 20 | -------------------------------------------------------------------------------- /sshgssc.h: -------------------------------------------------------------------------------- 1 | #ifndef PUTTY_SSHGSSC_H 2 | #define PUTTY_SSHGSSC_H 3 | #include "putty.h" 4 | #ifndef NO_GSSAPI 5 | 6 | #include "pgssapi.h" 7 | #include "sshgss.h" 8 | 9 | typedef struct gssapi_ssh_gss_ctx { 10 | OM_uint32 maj_stat; 11 | OM_uint32 min_stat; 12 | gss_ctx_id_t ctx; 13 | time_t expiry; 14 | } gssapi_ssh_gss_ctx; 15 | 16 | void ssh_gssapi_bind_fns(struct ssh_gss_library *lib); 17 | 18 | #else 19 | 20 | int ssh_gssapi_init(void); 21 | 22 | #endif /*NO_GSSAPI*/ 23 | 24 | #endif /*PUTTY_SSHGSSC_H*/ 25 | -------------------------------------------------------------------------------- /unix/x11misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * x11misc.h: header file for functions that need to refer to Xlib 3 | * data types. Has to be separate from unix.h so that we can include 4 | * it only after including the X headers, which in turn has to be done 5 | * after putty.h has told us whether NOT_X_WINDOWS is defined. 6 | */ 7 | 8 | #ifndef NOT_X_WINDOWS 9 | 10 | /* 11 | * x11misc.c. 12 | */ 13 | void x11_ignore_error(Display *disp, unsigned char errcode); 14 | 15 | /* 16 | * gtkmisc.c 17 | */ 18 | Display *get_x11_display(void); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /rdb/No_SSH-0.51.dif: -------------------------------------------------------------------------------- 1 | diff --git a/winnet.c b/winnet.c 2 | index 2be9233..9d030fa 100644 3 | --- a/winnet.c 4 | +++ b/winnet.c 5 | @@ -85,13 +85,14 @@ void sk_addr_free(SockAddr addr) { 6 | sfree(addr); 7 | } 8 | 9 | + extern char *do_select(SOCKET skt, int startup); 10 | + 11 | Socket sk_new(SockAddr addr, int port, sk_receiver_t receiver) { 12 | SOCKET s; 13 | SOCKADDR_IN a; 14 | DWORD err; 15 | char *errstr; 16 | Socket ret; 17 | - extern char *do_select(SOCKET skt, int startup); 18 | 19 | /* 20 | * Create Socket structure. 21 | -------------------------------------------------------------------------------- /contrib/cygtermd/README: -------------------------------------------------------------------------------- 1 | This directory contains 'cygtermd', a small and specialist Telnet 2 | server designed to act as middleware between PuTTY and a Cygwin shell 3 | session running on the same machine, so that PuTTY can act as an 4 | xterm-alike for Cygwin. 5 | 6 | To install it, you must compile it from source using Cygwin gcc, 7 | install it in Cygwin's /bin, and configure PuTTY to use it as a local 8 | proxy process. For detailed instructions, see the PuTTY Wishlist page 9 | at 10 | 11 | https://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/cygwin-terminal-window.html 12 | -------------------------------------------------------------------------------- /sshblowf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Header file shared between sshblowf.c and sshbcrypt.c. Exposes the 3 | * internal Blowfish routines needed by bcrypt. 4 | */ 5 | 6 | typedef struct BlowfishContext BlowfishContext; 7 | 8 | void *blowfish_make_context(void); 9 | void blowfish_free_context(void *handle); 10 | void blowfish_initkey(BlowfishContext *ctx); 11 | void blowfish_expandkey(BlowfishContext *ctx, 12 | const void *key, short keybytes, 13 | const void *salt, short saltbytes); 14 | void blowfish_lsb_encrypt_ecb(void *blk, int len, BlowfishContext *ctx); 15 | -------------------------------------------------------------------------------- /aqsync.c: -------------------------------------------------------------------------------- 1 | /* 2 | * aqsync.c: the agent_query_synchronous() wrapper function. 3 | * 4 | * This is a very small thing to have to put in its own module, but it 5 | * wants to be shared between back ends, and exist in any SSH client 6 | * program and also Pageant, and _nowhere else_ (because it pulls in 7 | * the main agent_query). 8 | */ 9 | 10 | #include 11 | 12 | #include "putty.h" 13 | 14 | void agent_query_synchronous(strbuf *query, void **out, int *outlen) 15 | { 16 | agent_pending_query *pending; 17 | 18 | pending = agent_query(query, out, outlen, NULL, 0); 19 | assert(!pending); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /rdb/No_SSH-0.46.dif: -------------------------------------------------------------------------------- 1 | diff --git a/window.c b/window.c 2 | index 3cd719a..62475de 100644 3 | --- a/window.c 4 | +++ b/window.c 5 | @@ -260,7 +260,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { 6 | char msg[1024]; 7 | char *realhost; 8 | 9 | - error = back->init (hwnd, cfg.host, cfg.port, &realhost); 10 | + if (back->init) 11 | + error = back->init (hwnd, cfg.host, cfg.port, &realhost); 12 | + else 13 | + error = "Backend missing"; 14 | if (error) { 15 | sprintf(msg, "Unable to open connection:\n%s", error); 16 | MessageBox(NULL, msg, "PuTTY Error", MB_ICONERROR | MB_OK); 17 | -------------------------------------------------------------------------------- /be_nossh.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Linking module for PuTTYtel: list the available backends not 3 | * including ssh. 4 | */ 5 | 6 | #include 7 | #include "putty.h" 8 | 9 | const int be_default_protocol = PROT_TELNET; 10 | 11 | const char *const appname = "PuTTYtel"; 12 | 13 | Backend *backends[] = { 14 | &telnet_backend, 15 | &rlogin_backend, 16 | &raw_backend, 17 | NULL 18 | }; 19 | 20 | /* 21 | * Stub implementations of functions not used in non-ssh versions. 22 | */ 23 | void random_save_seed(void) 24 | { 25 | } 26 | 27 | void random_destroy_seed(void) 28 | { 29 | } 30 | 31 | void noise_ultralight(unsigned long data) 32 | { 33 | } 34 | -------------------------------------------------------------------------------- /charset/slookup.c: -------------------------------------------------------------------------------- 1 | /* 2 | * slookup.c - static lookup of character sets. 3 | */ 4 | 5 | #include "charset.h" 6 | #include "internal.h" 7 | 8 | #define ENUM_CHARSET(x) extern charset_spec const charset_##x; 9 | #include "enum.c" 10 | #undef ENUM_CHARSET 11 | 12 | static charset_spec const *const cs_table[] = { 13 | 14 | #define ENUM_CHARSET(x) &charset_##x, 15 | #include "enum.c" 16 | #undef ENUM_CHARSET 17 | 18 | }; 19 | 20 | charset_spec const *charset_find_spec(int charset) 21 | { 22 | int i; 23 | 24 | for (i = 0; i < (int)lenof(cs_table); i++) 25 | if (cs_table[i]->charset == charset) 26 | return cs_table[i]; 27 | 28 | return NULL; 29 | } 30 | -------------------------------------------------------------------------------- /be_nos_s.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Linking module for PuTTYtel: list the available backends not 3 | * including ssh. 4 | */ 5 | 6 | #include 7 | #include "putty.h" 8 | 9 | const int be_default_protocol = PROT_TELNET; 10 | 11 | const char *const appname = "PuTTYtel"; 12 | 13 | Backend *backends[] = { 14 | &telnet_backend, 15 | &rlogin_backend, 16 | &raw_backend, 17 | &serial_backend, 18 | NULL 19 | }; 20 | 21 | /* 22 | * Stub implementations of functions not used in non-ssh versions. 23 | */ 24 | void random_save_seed(void) 25 | { 26 | } 27 | 28 | void random_destroy_seed(void) 29 | { 30 | } 31 | 32 | void noise_ultralight(unsigned long data) 33 | { 34 | } 35 | -------------------------------------------------------------------------------- /notiming.c: -------------------------------------------------------------------------------- 1 | /* 2 | * notiming.c: stub version of timing API. 3 | * 4 | * Used in any tool which needs a subsystem linked against the 5 | * timing API but doesn't want to actually provide timing. For 6 | * example, key generation tools need the random number generator, 7 | * but they don't want the hassle of calling noise_regular() at 8 | * regular intervals - and they don't _need_ it either, since they 9 | * have their own rigorous and different means of noise collection. 10 | */ 11 | 12 | #include "putty.h" 13 | 14 | unsigned long schedule_timer(int ticks, timer_fn_t fn, void *ctx) 15 | { 16 | return 0; 17 | } 18 | 19 | void expire_timer_context(void *ctx) 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /noshare.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Stub implementation of SSH connection-sharing IPC, for any 3 | * platform which can't support it at all. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "tree234.h" 11 | #include "putty.h" 12 | #include "ssh.h" 13 | #include "network.h" 14 | 15 | int platform_ssh_share(const char *name, Conf *conf, 16 | Plug downplug, Plug upplug, Socket *sock, 17 | char **logtext, char **ds_err, char **us_err, 18 | int can_upstream, int can_downstream) 19 | { 20 | return SHARE_NONE; 21 | } 22 | 23 | void platform_ssh_share_cleanup(const char *name) 24 | { 25 | } 26 | -------------------------------------------------------------------------------- /version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PuTTY version numbering 3 | */ 4 | 5 | /* 6 | * The difficult part of deciding what goes in these version strings 7 | * is done in Buildscr, and then written into version.h. All we have 8 | * to do here is to drop it into variables of the right names. 9 | */ 10 | 11 | #ifdef SOURCE_COMMIT 12 | #include "empty.h" 13 | #endif 14 | 15 | #include "version.h" 16 | 17 | const char ver[] = TEXTVER; 18 | const char sshver[] = SSHVER; 19 | const char commitid[] = SOURCE_COMMIT; 20 | 21 | /* 22 | * SSH local version string MUST be under 40 characters. Here's a 23 | * compile time assertion to verify this. 24 | */ 25 | enum { vorpal_sword = 1 / (sizeof(sshver) <= 40) }; 26 | -------------------------------------------------------------------------------- /unix/gtkmisc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Miscellaneous helper functions for GTK. 3 | */ 4 | 5 | #ifndef PUTTY_GTKMISC_H 6 | #define PUTTY_GTKMISC_H 7 | 8 | int string_width(const char *text); 9 | void get_label_text_dimensions(const char *text, int *width, int *height); 10 | 11 | void align_label_left(GtkLabel *label); 12 | 13 | GtkWidget *our_dialog_new(void); 14 | void our_dialog_add_to_content_area(GtkWindow *dlg, GtkWidget *w, 15 | gboolean expand, gboolean fill, 16 | guint padding); 17 | void our_dialog_set_action_area(GtkWindow *dlg, GtkWidget *w); 18 | GtkBox *our_dialog_make_action_hbox(GtkWindow *dlg); 19 | 20 | #endif /* PUTTY_GTKMISC_H */ 21 | -------------------------------------------------------------------------------- /rdb/Missing-patches/BELL.diff: -------------------------------------------------------------------------------- 1 | diff --git a/unix/gtkwin.c b/unix/gtkwin.c 2 | index 54f5028..41872d1 100644 3 | --- a/unix/gtkwin.c 4 | +++ b/unix/gtkwin.c 5 | @@ -2165,8 +2165,15 @@ void sys_cursor(void *frontend, int x, int y) 6 | */ 7 | void do_beep(void *frontend, int mode) 8 | { 9 | + /* BELL_DISABLED, BELL_DEFAULT, BELL_VISUAL, BELL_WAVEFILE, BELL_PCSPEAKER */ 10 | if (mode == BELL_DEFAULT) 11 | gdk_beep(); 12 | + if (mode == BELL_WAVEFILE) { 13 | + Filename *bell_wavefile = conf_get_filename(conf, CONF_bell_wavefile); 14 | + call_play_command(bell_wavefile->path); 15 | + } 16 | + if (mode == BELL_PCSPEAKER) 17 | + call_beep_command(); 18 | } 19 | 20 | int char_width(Context ctx, int uc) 21 | -------------------------------------------------------------------------------- /ldisc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ldisc.h: defines the Ldisc data structure used by ldisc.c and 3 | * ldiscucs.c. (Unfortunately it was necessary to split the ldisc 4 | * module in two, to avoid unnecessarily linking in the Unicode 5 | * stuff in tools that don't require it.) 6 | */ 7 | 8 | #ifndef PUTTY_LDISC_H 9 | #define PUTTY_LDISC_H 10 | 11 | typedef struct ldisc_tag { 12 | Terminal *term; 13 | Backend *back; 14 | void *backhandle; 15 | void *frontend; 16 | 17 | /* 18 | * Values cached out of conf. 19 | */ 20 | int telnet_keyboard, telnet_newline, protocol, localecho, localedit; 21 | 22 | char *buf; 23 | int buflen, bufsiz, quotenext; 24 | } *Ldisc; 25 | 26 | #endif /* PUTTY_LDISC_H */ 27 | -------------------------------------------------------------------------------- /windows/wintime.c: -------------------------------------------------------------------------------- 1 | /* 2 | * wintime.c - Avoid trouble with time() returning (time_t)-1 on Windows. 3 | */ 4 | 5 | #include "putty.h" 6 | #include 7 | 8 | struct tm ltime(void) 9 | { 10 | SYSTEMTIME st; 11 | struct tm tm; 12 | 13 | memset(&tm, 0, sizeof(tm)); /* in case there are any other fields */ 14 | 15 | GetLocalTime(&st); 16 | tm.tm_sec=st.wSecond; 17 | tm.tm_min=st.wMinute; 18 | tm.tm_hour=st.wHour; 19 | tm.tm_mday=st.wDay; 20 | tm.tm_mon=st.wMonth-1; 21 | tm.tm_year=(st.wYear>=1900?st.wYear-1900:0); 22 | tm.tm_wday=st.wDayOfWeek; 23 | tm.tm_yday=-1; /* GetLocalTime doesn't tell us */ 24 | tm.tm_isdst=0; /* GetLocalTime doesn't tell us */ 25 | return tm; 26 | } 27 | -------------------------------------------------------------------------------- /contrib/cygtermd/pty.h: -------------------------------------------------------------------------------- 1 | /* 2 | * pty.h - FIXME 3 | */ 4 | 5 | #ifndef FIXME_PTY_H 6 | #define FIXME_PTY_H 7 | 8 | #include "telnet.h" /* for struct shdata */ 9 | 10 | /* 11 | * Called at program startup to actually allocate a pty, so that 12 | * we can start passing in resize events as soon as they arrive. 13 | */ 14 | void pty_preinit(void); 15 | 16 | /* 17 | * Set the terminal size for the pty. 18 | */ 19 | void pty_resize(int w, int h); 20 | 21 | /* 22 | * Start a program in a subprocess running in the pty we allocated. 23 | * Returns the fd of the pty master. 24 | */ 25 | int run_program_in_pty(const struct shell_data *shdata, 26 | char *directory, char **program_args); 27 | 28 | #endif /* FIXME_PTY_H */ 29 | -------------------------------------------------------------------------------- /charset/enum.c: -------------------------------------------------------------------------------- 1 | /* 2 | * enum.c - enumerate all charsets defined by the library. 3 | * 4 | * This file maintains a list of every other source file which 5 | * contains ENUM_CHARSET definitions. It #includes each one with 6 | * ENUM_CHARSETS defined, which causes those source files to do 7 | * nothing at all except call the ENUM_CHARSET macro on each 8 | * charset they define. 9 | * 10 | * This file in turn is included from various other places, with 11 | * the ENUM_CHARSET macro defined to various different things. This 12 | * allows us to have multiple implementations of the master charset 13 | * lookup table (a static one and a dynamic one). 14 | */ 15 | 16 | #define ENUM_CHARSETS 17 | #include "sbcsdat.c" 18 | #include "utf8.c" 19 | #undef ENUM_CHARSETS 20 | -------------------------------------------------------------------------------- /testdata/display.txt: -------------------------------------------------------------------------------- 1 | Test of all features involved in do_text() 2 | ========================================== 3 | 4 | Reverse video + red on yellow:  bing!  5 | Yellow on red should look the same:  bong!  6 | 7 | Basic attrs, combining chars, both widths: Bold blink underline [Λ̊][チ][text] 8 | Wide char should be off by 1 narrow char: Bold blink underline [Λ̊][チ][text] 9 | 10 | Double width, double height. Should be red top, magenta bottom, blue DW only: 11 | #3Bold blink underline [Λ̊][チ][text] 12 | #4Bold blink underline [Λ̊][チ][text] 13 | #6Bold blink underline [Λ̊][チ][text] 14 | 15 | -------------------------------------------------------------------------------- /noprint.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Stub implementation of the printing interface for PuTTY, for the 3 | * benefit of non-printing terminal applications. 4 | */ 5 | 6 | #include 7 | #include 8 | #include "putty.h" 9 | 10 | struct printer_job_tag { 11 | int dummy; 12 | }; 13 | 14 | printer_job *printer_start_job(char *printer) 15 | { 16 | return NULL; 17 | } 18 | 19 | void printer_job_data(printer_job *pj, void *data, int len) 20 | { 21 | } 22 | 23 | void printer_finish_job(printer_job *pj) 24 | { 25 | } 26 | 27 | printer_enum *printer_start_enum(int *nprinters_ptr) 28 | { 29 | *nprinters_ptr = 0; 30 | return NULL; 31 | } 32 | char *printer_get_name(printer_enum *pe, int i) 33 | { 34 | return NULL; 35 | } 36 | void printer_finish_enum(printer_enum *pe) 37 | { 38 | } 39 | -------------------------------------------------------------------------------- /unix/uxpeer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Unix: wrapper for getsockopt(SO_PEERCRED), conditionalised on 3 | * appropriate autoconfery. 4 | */ 5 | 6 | #ifdef HAVE_CONFIG_H 7 | # include "uxconfig.h" /* leading space prevents mkfiles.pl trying to follow */ 8 | #endif 9 | 10 | #ifdef HAVE_SO_PEERCRED 11 | #define _GNU_SOURCE 12 | #include 13 | #endif 14 | 15 | #include 16 | 17 | #include "putty.h" 18 | 19 | int so_peercred(int fd, int *pid, int *uid, int *gid) 20 | { 21 | #ifdef HAVE_SO_PEERCRED 22 | struct ucred cr; 23 | socklen_t crlen = sizeof(cr); 24 | if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &crlen) == 0) { 25 | *pid = cr.pid; 26 | *uid = cr.uid; 27 | *gid = cr.gid; 28 | return TRUE; 29 | } 30 | #endif 31 | return FALSE; 32 | } 33 | -------------------------------------------------------------------------------- /charset/README: -------------------------------------------------------------------------------- 1 | This subdirectory contains a general character-set conversion 2 | library, used in the Unix port of PuTTY, and available for use in 3 | other ports if it should happen to be useful. 4 | 5 | This is a variant of a library that's currently used in some other 6 | programs such as Timber and Halibut. At some future date, we would 7 | like to merge the two libraries, so that all programs use the same 8 | libcharset. 9 | 10 | It is therefore a _strong_ design goal that this library should remain 11 | perfectly general, and not tied to particulars of PuTTY. It must not 12 | reference any code outside its own subdirectory; it should not have 13 | PuTTY-specific helper routines added to it unless they can be 14 | documented in a general manner which might make them useful in other 15 | circumstances as well. 16 | -------------------------------------------------------------------------------- /contrib/cygtermd/malloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * malloc.c: implementation of malloc.h 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | #include "malloc.h" 9 | 10 | extern void fatal(const char *, ...); 11 | 12 | void *smalloc(size_t size) { 13 | void *p; 14 | p = malloc(size); 15 | if (!p) { 16 | fatal("out of memory"); 17 | } 18 | return p; 19 | } 20 | 21 | void sfree(void *p) { 22 | if (p) { 23 | free(p); 24 | } 25 | } 26 | 27 | void *srealloc(void *p, size_t size) { 28 | void *q; 29 | if (p) { 30 | q = realloc(p, size); 31 | } else { 32 | q = malloc(size); 33 | } 34 | if (!q) 35 | fatal("out of memory"); 36 | return q; 37 | } 38 | 39 | char *dupstr(const char *s) { 40 | char *r = smalloc(1+strlen(s)); 41 | strcpy(r,s); 42 | return r; 43 | } 44 | -------------------------------------------------------------------------------- /windows/win_res.h: -------------------------------------------------------------------------------- 1 | /* 2 | * win_res.h - constants shared between win_res.rc2 and the C code. 3 | */ 4 | 5 | #ifndef PUTTY_WIN_RES_H 6 | #define PUTTY_WIN_RES_H 7 | 8 | #define IDI_MAINICON 200 9 | #define IDI_CFGICON 201 10 | 11 | #define IDD_MAINBOX 102 12 | #define IDD_LOGBOX 110 13 | #define IDD_ABOUTBOX 111 14 | #define IDD_RECONF 112 15 | #define IDD_LICENCEBOX 113 16 | 17 | #define IDN_LIST 1001 18 | #define IDN_COPY 1002 19 | 20 | #define IDA_ICON 1001 21 | #define IDA_TEXT 1002 22 | #define IDA_LICENCE 1003 23 | #define IDA_WEB 1004 24 | 25 | #define IDC_TAB 1001 26 | #define IDC_TABSTATIC1 1002 27 | #define IDC_TABSTATIC2 1003 28 | #define IDC_TABLIST 1004 29 | #define IDC_HELPBTN 1005 30 | #define IDC_ABOUT 1006 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /windows/windefs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * windefs.c: default settings that are specific to Windows. 3 | */ 4 | 5 | #include "putty.h" 6 | 7 | #include 8 | 9 | FontSpec *platform_default_fontspec(const char *name) 10 | { 11 | if (!strcmp(name, "Font")) 12 | return fontspec_new("Courier New", 0, 10, ANSI_CHARSET); 13 | else 14 | return fontspec_new("", 0, 0, 0); 15 | } 16 | 17 | Filename *platform_default_filename(const char *name) 18 | { 19 | if (!strcmp(name, "LogFileName")) 20 | return filename_from_str("putty.log"); 21 | else 22 | return filename_from_str(""); 23 | } 24 | 25 | char *platform_default_s(const char *name) 26 | { 27 | if (!strcmp(name, "SerialLine")) 28 | return dupstr("COM1"); 29 | return NULL; 30 | } 31 | 32 | int platform_default_i(const char *name, int def) 33 | { 34 | return def; 35 | } 36 | -------------------------------------------------------------------------------- /int64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Header for int64.c. 3 | */ 4 | 5 | #ifndef PUTTY_INT64_H 6 | #define PUTTY_INT64_H 7 | 8 | #include "defs.h" 9 | 10 | typedef struct { 11 | unsigned long hi, lo; 12 | } uint64; 13 | 14 | uint64 uint64_div10(uint64 x, int *remainder); 15 | void uint64_decimal(uint64 x, char *buffer); 16 | uint64 uint64_make(unsigned long hi, unsigned long lo); 17 | uint64 uint64_add(uint64 x, uint64 y); 18 | uint64 uint64_add32(uint64 x, unsigned long y); 19 | int uint64_compare(uint64 x, uint64 y); 20 | uint64 uint64_subtract(uint64 x, uint64 y); 21 | double uint64_to_double(uint64 x); 22 | uint64 uint64_shift_right(uint64 x, int shift); 23 | uint64 uint64_shift_left(uint64 x, int shift); 24 | uint64 uint64_from_decimal(char *str); 25 | 26 | void BinarySink_put_uint64(BinarySink *, uint64); 27 | uint64 BinarySource_get_uint64(BinarySource *); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /miscucs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Centralised Unicode-related helper functions, separate from misc.c 3 | * so that they can be omitted from tools that aren't including 4 | * Unicode handling. 5 | */ 6 | 7 | #include "putty.h" 8 | #include "misc.h" 9 | 10 | wchar_t *dup_mb_to_wc_c(int codepage, int flags, const char *string, int len) 11 | { 12 | int mult; 13 | for (mult = 1 ;; mult++) { 14 | wchar_t *ret = snewn(mult*len + 2, wchar_t); 15 | int outlen; 16 | outlen = mb_to_wc(codepage, flags, string, len, ret, mult*len + 1); 17 | if (outlen < mult*len+1) { 18 | ret[outlen] = L'\0'; 19 | return ret; 20 | } 21 | sfree(ret); 22 | } 23 | } 24 | 25 | wchar_t *dup_mb_to_wc(int codepage, int flags, const char *string) 26 | { 27 | return dup_mb_to_wc_c(codepage, flags, string, strlen(string)); 28 | } 29 | -------------------------------------------------------------------------------- /wcwidth-update/get-unidata: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | curl > EastAsianWidth.txt \ 5 | http://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt 6 | 7 | VER=$(head -1 EastAsianWidth.txt | sed 's/^# [A-Za-z]*-\([0-9.]*\).txt/\1/') 8 | echo "$VER" 9 | 10 | [ -f "UNIDATA-$VER/EastAsianWidth.txt" ] && { 11 | if cmp EastAsianWidth.txt "UNIDATA-$VER/EastAsianWidth.txt" 12 | then 13 | echo No update required. 14 | rm EastAsianWidth.txt 15 | exit 16 | fi 17 | } 18 | 19 | mkdir -p "UNIDATA-$VER" 20 | mkdir -p "UNIDATA-$VER/extracted" 21 | 22 | curl > "UNIDATA-$VER"/UnicodeData.txt \ 23 | http://www.unicode.org/Public/UNIDATA/UnicodeData.txt 24 | 25 | curl > "UNIDATA-$VER"/extracted/DerivedGeneralCategory.txt \ 26 | http://www.unicode.org/Public/UNIDATA/extracted/DerivedGeneralCategory.txt 27 | 28 | mv EastAsianWidth.txt "UNIDATA-$VER"/EastAsianWidth.txt 29 | 30 | -------------------------------------------------------------------------------- /rdb/Missing-patches/0041 Update multimon.h support.diff: -------------------------------------------------------------------------------- 1 | 3b0b5f9f6194069ca40d33b07be9ed349f790d94 2 | diff --git a/windows/window.c b/windows/window.c 3 | index 44f92901ece63dcf944a4483327ae20e33342df1..9f50846c3e60ad10864f3182bf6adb8292b6cc61 100644 4 | --- a/windows/window.c 5 | +++ b/windows/window.c 6 | @@ -10,10 +10,6 @@ 7 | #include 8 | #include 9 | 10 | -#ifndef NO_MULTIMON 11 | -#define COMPILE_MULTIMON_STUBS 12 | -#endif 13 | - 14 | #define PUTTY_DO_GLOBALS /* actually _define_ globals */ 15 | #include "putty.h" 16 | #include "terminal.h" 17 | @@ -21,7 +17,9 @@ 18 | #include "win_res.h" 19 | #include "winsecur.h" 20 | 21 | -#ifndef NO_MULTIMON 22 | +#if !defined(NO_MULTIMON) && !defined(NO_MULTIMON_H) 23 | +/* This is needed to provide the stubs for running on Windows 95 */ 24 | +#define COMPILE_MULTIMON_STUBS 25 | #include 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /windows/wincapi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * wincapi.c: implementation of wincapi.h. 3 | */ 4 | 5 | #include "putty.h" 6 | 7 | #if !defined NO_SECURITY 8 | 9 | #define WINCAPI_GLOBAL 10 | #include "wincapi.h" 11 | 12 | int got_crypt(void) 13 | { 14 | static int attempted = FALSE; 15 | static int successful; 16 | static HMODULE crypt; 17 | 18 | if (!attempted) { 19 | attempted = TRUE; 20 | crypt = load_system32_dll("crypt32.dll"); 21 | successful = crypt && 22 | #ifdef COVERITY 23 | /* The build toolchain I use with Coverity doesn't know 24 | * about this function, so can't type-check it */ 25 | GET_WINDOWS_FUNCTION_NO_TYPECHECK(crypt, CryptProtectMemory) 26 | #else 27 | GET_WINDOWS_FUNCTION(crypt, CryptProtectMemory) 28 | #endif 29 | ; 30 | } 31 | return successful; 32 | } 33 | 34 | #endif /* !defined NO_SECURITY */ 35 | -------------------------------------------------------------------------------- /be_all.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Linking module for PuTTY proper: list the available backends 3 | * including ssh. 4 | */ 5 | 6 | #include 7 | #include "putty.h" 8 | 9 | /* 10 | * This appname is not strictly in the right place, since Plink 11 | * also uses this module. However, Plink doesn't currently use any 12 | * of the dialog-box sorts of things that make use of appname, so 13 | * it shouldn't do any harm here. I'm trying to avoid having to 14 | * have tiny little source modules containing nothing but 15 | * declarations of appname, for as long as I can... 16 | */ 17 | const char *const appname = "PuTTY"; 18 | 19 | #ifdef TELNET_DEFAULT 20 | const int be_default_protocol = PROT_TELNET; 21 | #else 22 | const int be_default_protocol = PROT_SSH; 23 | #endif 24 | 25 | Backend *backends[] = { 26 | &ssh_backend, 27 | &telnet_backend, 28 | &rlogin_backend, 29 | &raw_backend, 30 | NULL 31 | }; 32 | -------------------------------------------------------------------------------- /rdb/No_SSH-0.48.dif: -------------------------------------------------------------------------------- 1 | diff --git a/putty.h b/putty.h 2 | index 273a811..e891c2c 100644 3 | --- a/putty.h 4 | +++ b/putty.h 5 | @@ -240,7 +240,7 @@ extern Backend telnet_backend; 6 | * Exports from ssh.c. 7 | */ 8 | 9 | -extern Backend ssh_backend; 10 | +Backend ssh_backend; 11 | 12 | /* 13 | * Exports from ldisc.c. 14 | diff --git a/window.c b/window.c 15 | index 0a68857..fab0761 100644 16 | --- a/window.c 17 | +++ b/window.c 18 | @@ -291,7 +291,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { 19 | char msg[1024]; 20 | char *realhost; 21 | 22 | - error = back->init (hwnd, cfg.host, cfg.port, &realhost); 23 | + if (back->init) 24 | + error = back->init (hwnd, cfg.host, cfg.port, &realhost); 25 | + else 26 | + error = "Backend missing"; 27 | if (error) { 28 | sprintf(msg, "Unable to open connection:\n%s", error); 29 | MessageBox(NULL, msg, "PuTTY Error", MB_ICONERROR | MB_OK); 30 | -------------------------------------------------------------------------------- /rdb/No_SSH-0.45.dif: -------------------------------------------------------------------------------- 1 | diff --git a/windlg.c b/windlg.c 2 | index 58b570f..9a461a2 100644 3 | --- a/windlg.c 4 | +++ b/windlg.c 5 | @@ -5,8 +5,8 @@ 6 | #include 7 | #include 8 | 9 | -#include "putty.h" 10 | #include "ssh.h" 11 | +#include "putty.h" 12 | #include "win_res.h" 13 | 14 | #define NPANELS 7 15 | diff --git a/window.c b/window.c 16 | index 3cd719a..62475de 100644 17 | --- a/window.c 18 | +++ b/window.c 19 | @@ -260,7 +260,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { 20 | char msg[1024]; 21 | char *realhost; 22 | 23 | - error = back->init (hwnd, cfg.host, cfg.port, &realhost); 24 | + if (back->init) 25 | + error = back->init (hwnd, cfg.host, cfg.port, &realhost); 26 | + else 27 | + error = "Backend missing"; 28 | if (error) { 29 | sprintf(msg, "Unable to open connection:\n%s", error); 30 | MessageBox(NULL, msg, "PuTTY Error", MB_ICONERROR | MB_OK); 31 | -------------------------------------------------------------------------------- /rdb/No_SSH-0.47.dif: -------------------------------------------------------------------------------- 1 | diff --git a/putty.h b/putty.h 2 | index 0ca50aa..8e4de63 100644 3 | --- a/putty.h 4 | +++ b/putty.h 5 | @@ -196,7 +196,7 @@ extern Backend telnet_backend; 6 | * Exports from ssh.c. 7 | */ 8 | 9 | -extern Backend ssh_backend; 10 | +Backend ssh_backend; 11 | 12 | /* 13 | * Exports from sshrand.c. 14 | diff --git a/window.c b/window.c 15 | index e8c4515..12bee8b 100644 16 | --- a/window.c 17 | +++ b/window.c 18 | @@ -260,7 +260,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { 19 | char msg[1024]; 20 | char *realhost; 21 | 22 | - error = back->init (hwnd, cfg.host, cfg.port, &realhost); 23 | + if (back->init) 24 | + error = back->init (hwnd, cfg.host, cfg.port, &realhost); 25 | + else 26 | + error = "Backend missing"; 27 | if (error) { 28 | sprintf(msg, "Unable to open connection:\n%s", error); 29 | MessageBox(NULL, msg, "PuTTY Error", MB_ICONERROR | MB_OK); 30 | -------------------------------------------------------------------------------- /unix/ux_x11.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ux_x11.c: fetch local auth data for X forwarding. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "putty.h" 12 | #include "ssh.h" 13 | #include "network.h" 14 | 15 | void platform_get_x11_auth(struct X11Display *disp, Conf *conf) 16 | { 17 | char *xauthfile; 18 | int needs_free; 19 | 20 | /* 21 | * Find the .Xauthority file. 22 | */ 23 | needs_free = FALSE; 24 | xauthfile = getenv("XAUTHORITY"); 25 | if (!xauthfile) { 26 | xauthfile = getenv("HOME"); 27 | if (xauthfile) { 28 | xauthfile = dupcat(xauthfile, "/.Xauthority", NULL); 29 | needs_free = TRUE; 30 | } 31 | } 32 | 33 | if (xauthfile) { 34 | x11_get_auth_from_authfile(disp, xauthfile); 35 | if (needs_free) 36 | sfree(xauthfile); 37 | } 38 | } 39 | 40 | const int platform_uses_x11_unix_by_default = TRUE; 41 | -------------------------------------------------------------------------------- /rdb/mkzip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh - 2 | 3 | rm -f putty-src.zip putty-win.zip 4 | 5 | # Add all the text files 6 | find * \( -name rdb -prune -false \) -o -type f ! \( \ 7 | -name \*.o \ 8 | -o -name \*.exe \ 9 | -o -name \*.map \ 10 | -o -name fuzzterm \ 11 | -o -name pageant \ 12 | -o -name plink \ 13 | -o -name pscp \ 14 | -o -name psftp \ 15 | -o -name pterm \ 16 | -o -name putty \ 17 | -o -name puttygen \ 18 | -o -name puttytel \ 19 | -o -name testbn \ 20 | -o -name \*.ico \ 21 | -o -name \*.iss \ 22 | -o -name \*.url \ 23 | -o -name \*.dsp \ 24 | -o -name \*.dsw \ 25 | -o -name \*.cur \ 26 | \) | sort | zip -@ -X -q -l putty-src.zip 27 | 28 | # And the binary files. 29 | find * \ 30 | -name \*.ico \ 31 | -o -name \*.iss \ 32 | -o -name \*.url \ 33 | -o -name \*.dsp \ 34 | -o -name \*.cur \ 35 | | zip -@ -X -q putty-src.zip 36 | 37 | zip -j9 putty-win.zip windows/*.exe 38 | -------------------------------------------------------------------------------- /testdata/vt100.txt: -------------------------------------------------------------------------------- 1 | VT100 line drawing characters, actually using the VT100 escapes 2 | (B)0ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo 3 | 4 | lqqqqqqqqqqpoopqrssrqqqqqqqqqqwqqqqqqqqqqpoopqrssrqqqqqqqqqqk 5 | x x x 6 | x ooh, swirly! x top right corner x 7 | x x x 8 | tqqqqqqqqqqpoopqrssrqqqqqqqqqqnqqqqqqqqqqpoopqrssrqqqqqqqqqqu 9 | x x x 10 | x stuff down here x is quite inane x 11 | x x x 12 | mqqqqqqqqqqpoopqrssrqqqqqqqqqqvqqqqqqqqqqpoopqrssrqqqqqqqqqqj 13 | 14 | (This won't do the right thing in PuTTY's default UTF-8 translation; 15 | you'll just see lqqqk letters. It should work with a character set 16 | like ISO8859-1.) 17 | -------------------------------------------------------------------------------- /be_all_s.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Linking module for PuTTY proper: list the available backends 3 | * including ssh, plus the serial backend. 4 | */ 5 | 6 | #include 7 | #include "putty.h" 8 | 9 | /* 10 | * This appname is not strictly in the right place, since Plink 11 | * also uses this module. However, Plink doesn't currently use any 12 | * of the dialog-box sorts of things that make use of appname, so 13 | * it shouldn't do any harm here. I'm trying to avoid having to 14 | * have tiny little source modules containing nothing but 15 | * declarations of appname, for as long as I can... 16 | */ 17 | const char *const appname = "PuTTY"; 18 | 19 | #ifdef TELNET_DEFAULT 20 | const int be_default_protocol = PROT_TELNET; 21 | #else 22 | const int be_default_protocol = PROT_SSH; 23 | #endif 24 | 25 | Backend *backends[] = { 26 | &ssh_backend, 27 | &telnet_backend, 28 | &rlogin_backend, 29 | &raw_backend, 30 | &serial_backend, 31 | NULL 32 | }; 33 | -------------------------------------------------------------------------------- /icons/cicon.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # Given a list of input PNGs, create a C source file containing a 4 | # const array of XPMs, named by a given C identifier. 5 | 6 | $id = shift @ARGV; 7 | $k = 0; 8 | @xpms = (); 9 | foreach $f (@ARGV) { 10 | # XPM format is generated directly by ImageMagick, so that's easy 11 | # enough. We just have to adjust the declaration line so that it 12 | # has the right name, linkage and storage class. 13 | @lines = (); 14 | open XPM, "convert $f xpm:- |"; 15 | push @lines, $_ while ; 16 | close XPM; 17 | die "XPM from $f in unexpected format\n" unless $lines[1] =~ /^static.*\{$/; 18 | $lines[1] = "static const char *const ${id}_$k"."[] = {\n"; 19 | $k++; 20 | push @xpms, @lines, "\n"; 21 | } 22 | 23 | # Now output. 24 | foreach $line (@xpms) { print $line; } 25 | print "const char *const *const ${id}[] = {\n"; 26 | for ($i = 0; $i < $k; $i++) { print " ${id}_$i,\n"; } 27 | print "};\n"; 28 | print "const int n_${id} = $k;\n"; 29 | -------------------------------------------------------------------------------- /nocproxy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Routines to refuse to do cryptographic interaction with proxies 3 | * in PuTTY. This is a stub implementation of the same interfaces 4 | * provided by cproxy.c, for use in PuTTYtel. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #define DEFINE_PLUG_METHOD_MACROS 12 | #include "putty.h" 13 | #include "network.h" 14 | #include "proxy.h" 15 | 16 | void proxy_socks5_offerencryptedauth(BinarySink *bs) 17 | { 18 | /* For telnet, don't add any new encrypted authentication routines */ 19 | } 20 | 21 | int proxy_socks5_handlechap (ProxySocket *p) 22 | { 23 | 24 | plug_closing(p->plug, "Proxy error: Trying to handle a SOCKS5 CHAP request" 25 | " in telnet-only build", 26 | PROXY_ERROR_GENERAL, 0); 27 | return 1; 28 | } 29 | 30 | int proxy_socks5_selectchap(ProxySocket *p) 31 | { 32 | plug_closing(p->plug, "Proxy error: Trying to handle a SOCKS5 CHAP request" 33 | " in telnet-only build", 34 | PROXY_ERROR_GENERAL, 0); 35 | return 1; 36 | } 37 | -------------------------------------------------------------------------------- /unix/pterm.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIconFile 6 | Pterm.icns 7 | CFBundleName 8 | Pterm 9 | CFBundleDisplayName 10 | Pterm 11 | CFBundleExecutable 12 | Pterm 13 | CFBundleVersion 14 | Unidentified build 15 | CFBundleShortVersionString 16 | Unidentified build 17 | CFBundleDevelopmentRegion 18 | en 19 | CFBundleIdentifier 20 | org.tartarus.projects.putty.macpterm 21 | CFBundleInfoDictionaryVersion 22 | 6.0 23 | CFBundlePackageType 24 | APPL 25 | CFBundleSignature 26 | ???? 27 | NSHumanReadableCopyright 28 | © 1997-2015 Simon Tatham. All rights reserved. 29 | 30 | 31 | -------------------------------------------------------------------------------- /unix/putty.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIconFile 6 | PuTTY.icns 7 | CFBundleName 8 | PuTTY 9 | CFBundleDisplayName 10 | PuTTY 11 | CFBundleExecutable 12 | PuTTY 13 | CFBundleVersion 14 | Unidentified build 15 | CFBundleShortVersionString 16 | Unidentified build 17 | CFBundleDevelopmentRegion 18 | en 19 | CFBundleIdentifier 20 | org.tartarus.projects.putty.macputty 21 | CFBundleInfoDictionaryVersion 22 | 6.0 23 | CFBundlePackageType 24 | APPL 25 | CFBundleSignature 26 | ???? 27 | NSHumanReadableCopyright 28 | © 1997-2015 Simon Tatham. All rights reserved. 29 | 30 | 31 | -------------------------------------------------------------------------------- /contrib/cygtermd/telnet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Header declaring Telnet-handling functions. 3 | */ 4 | 5 | #ifndef FIXME_TELNET_H 6 | #define FIXME_TELNET_H 7 | 8 | #include "sel.h" 9 | 10 | typedef struct telnet_tag *Telnet; 11 | 12 | struct shell_data { 13 | char **envvars; /* array of "VAR=value" terms */ 14 | int nenvvars; 15 | char *termtype; 16 | }; 17 | 18 | /* 19 | * Create and destroy a Telnet structure. 20 | */ 21 | Telnet telnet_new(sel_wfd *net, sel_wfd *pty); 22 | void telnet_free(Telnet telnet); 23 | 24 | /* 25 | * Process data read from the pty. 26 | */ 27 | void telnet_from_pty(Telnet telnet, char *buf, int len); 28 | 29 | /* 30 | * Process Telnet protocol data received from the network. 31 | */ 32 | void telnet_from_net(Telnet telnet, char *buf, int len); 33 | 34 | /* 35 | * Return true if pre-shell-startup negotiations are complete and 36 | * it's safe to start the shell subprocess now. On a true return, 37 | * also fills in the shell_data structure. 38 | */ 39 | int telnet_shell_ok(Telnet telnet, struct shell_data *shdata); 40 | 41 | #endif /* FIXME_TELNET_H */ 42 | -------------------------------------------------------------------------------- /windows/rcstuff.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Miscellaneous stuff to include in all .rc files. 3 | */ 4 | 5 | #ifndef PUTTY_RCSTUFF_H 6 | #define PUTTY_RCSTUFF_H 7 | 8 | #ifdef __LCC__ 9 | #include 10 | #else 11 | 12 | /* Some compilers don't have winresrc.h */ 13 | #ifndef NO_WINRESRC_H 14 | #ifndef MSVC4 15 | #include 16 | #else 17 | #include 18 | #endif 19 | #endif 20 | 21 | #endif /* end #ifdef __LCC__ */ 22 | 23 | /* Some systems don't define this, so I do it myself if necessary */ 24 | #ifndef TCS_MULTILINE 25 | #define TCS_MULTILINE 0x0200 26 | #endif 27 | 28 | /* Likewise */ 29 | #ifndef RT_MANIFEST 30 | #define RT_MANIFEST 24 31 | #endif 32 | 33 | /* LCC is the offender here. */ 34 | #ifndef VS_FF_DEBUG 35 | #define VS_FF_DEBUG 1 36 | #endif 37 | #ifndef VS_FF_PRERELEASE 38 | #define VS_FF_PRERELEASE 2 39 | #endif 40 | #ifndef VS_FF_PRIVATEBUILD 41 | #define VS_FF_PRIVATEBUILD 8 42 | #endif 43 | #ifndef VOS__WINDOWS32 44 | #define VOS__WINDOWS32 4 45 | #endif 46 | #ifndef VFT_APP 47 | #define VFT_APP 1 48 | #endif 49 | 50 | #endif /* PUTTY_RCSTUFF_H */ 51 | -------------------------------------------------------------------------------- /testdata/utf8.txt: -------------------------------------------------------------------------------- 1 | Test of UTF-8 output in a terminal emulator 2 | ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ 3 | 4 | Some basic Unicode: 5 | ∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β), 6 | ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (A ⇔ B), 7 | 8 | Combining characters: 9 | STARGΛ̊TE SG-1, a = v̇ = r̈, a⃑ ⊥ b⃑ 10 | [----------------------------|------------------------] 11 | ๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่ 12 | สิบสองกษัตริย์ก่อนหน้าแลถัดไป สององค์ไซร้โง่เขลาเบาปัญญา 13 | 14 | Wide characters with difficult wrapping: 15 | Here we go then: コンニチハ コンニチハ コンニチハ コンニチハ コンニチハ コンニチハ コンニチハ コンニチハ コンニチハ コンニチハ コンニチハ コンニチハ コンニチハ コンニチハ コンニチハ 16 | 17 | Arabic and bidirectional text: 18 | (من مجمع الزوائد ومنبع الفوائد للهيثمي ، ج 1 ، ص 74-84) 19 | عن جرير رضي الله عنه قال قال رسول الله صلى الله عليه 20 | وسلم: بني الاسلام على خمس شهادة ان لا اله الا الله واقام 21 | Mixed LTR and RTL text: جرير رضي back to LTR. 22 | 23 | East Asian Ambiguous characters: ¼½¾¼½¾¼½¾¼½¾¼½¾¼½¾¼½¾¼½¾¼½¾¼½¾ 24 | -------------------------------------------------------------------------------- /nullplug.c: -------------------------------------------------------------------------------- 1 | /* 2 | * nullplug.c: provide a null implementation of the Plug vtable which 3 | * ignores all calls. Occasionally useful in cases where we want to 4 | * make a network connection just to see if it works, but not do 5 | * anything with it afterwards except close it again. 6 | */ 7 | 8 | #include "putty.h" 9 | 10 | static void nullplug_socket_log(Plug plug, int type, SockAddr addr, int port, 11 | const char *error_msg, int error_code) 12 | { 13 | } 14 | 15 | static void nullplug_closing(Plug plug, const char *error_msg, int error_code, 16 | int calling_back) 17 | { 18 | } 19 | 20 | static void nullplug_receive(Plug plug, int urgent, char *data, int len) 21 | { 22 | } 23 | 24 | static void nullplug_sent(Plug plug, int bufsize) 25 | { 26 | } 27 | 28 | static const Plug_vtable nullplug_plugvt = { 29 | nullplug_socket_log, 30 | nullplug_closing, 31 | nullplug_receive, 32 | nullplug_sent, 33 | NULL 34 | }; 35 | 36 | static const Plug_vtable *nullplug_plugvt_ptr = &nullplug_plugvt; 37 | 38 | /* 39 | * There's a singleton instance of nullplug, because it's not 40 | * interesting enough to worry about making more than one of them. 41 | */ 42 | Plug nullplug = &nullplug_plugvt_ptr; 43 | -------------------------------------------------------------------------------- /mksrcarc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | perl mkfiles.pl 6 | # These are text files. 7 | text=`{ find . -name CVS -prune -o \ 8 | -name .cvsignore -prune -o \ 9 | -name .svn -prune -o \ 10 | -name LATEST.VER -prune -o \ 11 | -name CHECKLST.txt -prune -o \ 12 | -name mksrcarc.sh -prune -o \ 13 | -name '*.dsp' -prune -o \ 14 | -name '*.dsw' -prune -o \ 15 | -type f -print | sed 's/^\.\///'; } | \ 16 | grep -ivE 'testdata/.*\.txt|MODULE|putty.iss|website.url' | grep -vF .ico | grep -vF .icns` 17 | # These are files which I'm _sure_ should be treated as text, but 18 | # which zip might complain about, so we direct its moans to 19 | # /dev/null! Apparently its heuristics are doubtful of UTF-8 text 20 | # files. 21 | bintext=testdata/*.txt 22 | # These are actual binary files which we don't want transforming. 23 | bin=`{ ls -1 windows/*.ico windows/putty.iss windows/website.url; \ 24 | find . -name '*.dsp' -print -o -name '*.dsw' -print; }` 25 | 26 | verbosely() { 27 | echo "$@" 28 | "$@" 29 | } 30 | 31 | verbosely zip -l putty-src.zip $text 32 | verbosely zip -l putty-src.zip $bintext 33 | verbosely zip putty-src.zip $bin 34 | -------------------------------------------------------------------------------- /unix/uxsignal.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /* 6 | * Calling signal() is non-portable, as it varies in meaning 7 | * between platforms and depending on feature macros, and has 8 | * stupid semantics at least some of the time. 9 | * 10 | * This function provides the same interface as the libc function, 11 | * but provides consistent semantics. It assumes POSIX semantics 12 | * for sigaction() (so you might need to do some more work if you 13 | * port to something ancient like SunOS 4) 14 | */ 15 | void (*putty_signal(int sig, void (*func)(int)))(int) { 16 | struct sigaction sa; 17 | struct sigaction old; 18 | 19 | sa.sa_handler = func; 20 | if(sigemptyset(&sa.sa_mask) < 0) 21 | return SIG_ERR; 22 | sa.sa_flags = SA_RESTART; 23 | if(sigaction(sig, &sa, &old) < 0) 24 | return SIG_ERR; 25 | return old.sa_handler; 26 | } 27 | 28 | void block_signal(int sig, int block_it) 29 | { 30 | sigset_t ss; 31 | 32 | sigemptyset(&ss); 33 | sigaddset(&ss, sig); 34 | if(sigprocmask(block_it ? SIG_BLOCK : SIG_UNBLOCK, &ss, 0) < 0) { 35 | perror("sigprocmask"); 36 | exit(1); 37 | } 38 | } 39 | 40 | /* 41 | Local Variables: 42 | c-basic-offset:4 43 | comment-column:40 44 | End: 45 | */ 46 | -------------------------------------------------------------------------------- /mkunxarc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Build a Unix source distribution from the PuTTY CVS area. 4 | # 5 | # Expects the following arguments: 6 | # - the version number to write into configure.ac 7 | # - the suffix to put on the Unix source tarball 8 | # - the options to put on the 'make' command line for the docs 9 | 10 | autoconfver="$1" 11 | arcsuffix="$2" 12 | docver="$3" 13 | 14 | perl mkfiles.pl 15 | (cd doc && make -s ${docver:+"$docver"}) 16 | 17 | relver=`cat LATEST.VER` 18 | arcname="putty$arcsuffix" 19 | mkdir uxarc 20 | mkdir uxarc/$arcname 21 | find . -name uxarc -prune -o \ 22 | -name CVS -prune -o \ 23 | -name .svn -prune -o \ 24 | -name . -o \ 25 | -type d -exec mkdir uxarc/$arcname/{} \; 26 | find . -name uxarc -prune -o \ 27 | -name CVS -prune -o \ 28 | -name .cvsignore -prune -o \ 29 | -name .svn -prune -o \ 30 | -name configure.ac -prune -o \ 31 | -name '*.zip' -prune -o \ 32 | -name '*.tar.gz' -prune -o \ 33 | -type f -exec ln -s $PWD/{} uxarc/$arcname/{} \; 34 | sed "s/^AC_INIT(putty,.*/AC_INIT(putty, $autoconfver)/" configure.ac > uxarc/$arcname/configure.ac 35 | (cd uxarc/$arcname && sh mkauto.sh) 2>errors || { cat errors >&2; exit 1; } 36 | 37 | tar -C uxarc -chzof $arcname.tar.gz $arcname 38 | rm -rf uxarc 39 | -------------------------------------------------------------------------------- /windows/pageant.mft: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | PuTTY SSH authentication agent 12 | 13 | 14 | 16 | 22 | 23 | 24 | 25 | 26 | 28 | true 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /windows/puttygen.mft: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | SSH key generator for PuTTY 12 | 13 | 14 | 16 | 22 | 23 | 24 | 25 | 26 | 28 | true 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /windows/putty.mft: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 11 | A network client and terminal emulator 12 | 13 | 14 | 16 | 22 | 23 | 24 | 25 | 26 | 28 | true 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /unix/uxpterm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * pterm main program. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | #include "putty.h" 9 | 10 | const char *const appname = "pterm"; 11 | const int use_event_log = 0; /* pterm doesn't need it */ 12 | const int new_session = 0, saved_sessions = 0; /* or these */ 13 | const int dup_check_launchable = 0; /* no need to check host name in conf */ 14 | const int use_pty_argv = TRUE; 15 | 16 | Backend *select_backend(Conf *conf) 17 | { 18 | return &pty_backend; 19 | } 20 | 21 | void initial_config_box(Conf *conf, post_dialog_fn_t after, void *afterctx) 22 | { 23 | /* 24 | * This is a no-op in pterm, except that we'll ensure the protocol 25 | * is set to -1 to inhibit the useless Connection panel in the 26 | * config box. So we do that and then just immediately call the 27 | * post-dialog function with a positive result. 28 | */ 29 | conf_set_int(conf, CONF_protocol, -1); 30 | after(afterctx, 1); 31 | } 32 | 33 | void cleanup_exit(int code) 34 | { 35 | exit(code); 36 | } 37 | 38 | char *make_default_wintitle(char *hostname) 39 | { 40 | return dupstr("pterm"); 41 | } 42 | 43 | void setup(int single) 44 | { 45 | extern void pty_pre_init(void); /* declared in pty.c */ 46 | 47 | cmdline_tooltype = TOOLTYPE_NONNETWORK; 48 | default_protocol = -1; 49 | 50 | if (single) 51 | pty_pre_init(); 52 | } 53 | -------------------------------------------------------------------------------- /charset/sbcs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * sbcs.c - routines to handle single-byte character sets. 3 | */ 4 | 5 | #include "charset.h" 6 | #include "internal.h" 7 | 8 | /* 9 | * The charset_spec for any single-byte character set should 10 | * provide read_sbcs() as its read function, and its `data' field 11 | * should be a wchar_t string constant containing the 256 entries 12 | * of the translation table. 13 | */ 14 | 15 | void read_sbcs(charset_spec const *charset, long int input_chr, 16 | charset_state *state, 17 | void (*emit)(void *ctx, long int output), void *emitctx) 18 | { 19 | const struct sbcs_data *sd = charset->data; 20 | 21 | UNUSEDARG(state); 22 | 23 | emit(emitctx, sd->sbcs2ucs[input_chr]); 24 | } 25 | 26 | void write_sbcs(charset_spec const *charset, long int input_chr, 27 | charset_state *state, 28 | void (*emit)(void *ctx, long int output), void *emitctx) 29 | { 30 | const struct sbcs_data *sd = charset->data; 31 | int i, j, k, c; 32 | 33 | UNUSEDARG(state); 34 | 35 | /* 36 | * Binary-search in the ucs2sbcs table. 37 | */ 38 | i = -1; 39 | j = sd->nvalid; 40 | while (i+1 < j) { 41 | k = (i+j)/2; 42 | c = sd->ucs2sbcs[k]; 43 | if (input_chr < sd->sbcs2ucs[c]) 44 | j = k; 45 | else if (input_chr > sd->sbcs2ucs[c]) 46 | i = k; 47 | else { 48 | emit(emitctx, c); 49 | return; 50 | } 51 | } 52 | emit(emitctx, ERROR); 53 | } 54 | -------------------------------------------------------------------------------- /Buildscr.cv: -------------------------------------------------------------------------------- 1 | # -*- sh -*- 2 | 3 | # Build script to scan PuTTY with the downloadable Coverity scanner 4 | # and generate a tar file to upload to their open-source scanning 5 | # service. 6 | 7 | module putty 8 | 9 | # Preparations. 10 | in putty do ./mkfiles.pl 11 | in putty do ./mkauto.sh 12 | in putty/doc do make 13 | 14 | # Scan the Unix build, on a 64-bit system to differentiate as much as 15 | # possible from the other scan of the cross-platform files. 16 | delegate covscan64 17 | in putty do ./configure 18 | in putty do cov-build --dir cov-int make 19 | in putty do tar czvf cov-int.tar.gz cov-int 20 | return putty/cov-int.tar.gz 21 | enddelegate 22 | 23 | # Scan the Windows build, by means of building with Winelib (since as 24 | # of 2013-07-22, the Coverity Scan website doesn't offer a 32-bit 25 | # Windows scanner for download). 26 | delegate covscan32wine 27 | in putty do tar xzvf cov-int.tar.gz 28 | in putty/windows do cov-build --dir ../cov-int make -f Makefile.mgw CC=winegcc RC=wrc XFLAGS=-DCOVERITY 29 | in putty do tar czvf cov-int.tar.gz cov-int 30 | return putty/cov-int.tar.gz 31 | enddelegate 32 | 33 | # Provide the revision number as one of the build outputs, to make it 34 | # easy to construct a curl upload command which will annotate it 35 | # appropriately when uploaded. 36 | in putty do echo $(vcsfullid) > revision.txt 37 | 38 | deliver putty/revision.txt $@ 39 | deliver putty/cov-int.tar.gz $@ 40 | -------------------------------------------------------------------------------- /unix/uxprint.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Printing interface for PuTTY. 3 | */ 4 | 5 | #include 6 | #include 7 | #include "putty.h" 8 | 9 | struct printer_job_tag { 10 | FILE *fp; 11 | }; 12 | 13 | printer_job *printer_start_job(char *printer) 14 | { 15 | printer_job *ret = snew(printer_job); 16 | /* 17 | * On Unix, we treat the printer string as the name of a 18 | * command to pipe to - typically lpr, of course. 19 | */ 20 | ret->fp = popen(printer, "w"); 21 | if (!ret->fp) { 22 | sfree(ret); 23 | ret = NULL; 24 | } 25 | return ret; 26 | } 27 | 28 | void printer_job_data(printer_job *pj, void *data, int len) 29 | { 30 | if (!pj) 31 | return; 32 | 33 | if (fwrite(data, 1, len, pj->fp) < len) 34 | /* ignore */; 35 | } 36 | 37 | void printer_finish_job(printer_job *pj) 38 | { 39 | if (!pj) 40 | return; 41 | 42 | pclose(pj->fp); 43 | sfree(pj); 44 | } 45 | 46 | /* 47 | * There's no sensible way to enumerate printers under Unix, since 48 | * practically any valid Unix command is a valid printer :-) So 49 | * these are useless stub functions, and uxcfg.c will disable the 50 | * drop-down list in the printer configurer. 51 | */ 52 | printer_enum *printer_start_enum(int *nprinters_ptr) { 53 | *nprinters_ptr = 0; 54 | return NULL; 55 | } 56 | char *printer_get_name(printer_enum *pe, int i) { return NULL; 57 | } 58 | void printer_finish_enum(printer_enum *pe) { } 59 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | PuTTY is copyright 1997-2018 Simon Tatham. 2 | 3 | Portions copyright Robert de Bath, Joris van Rantwijk, Delian 4 | Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry, 5 | Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus 6 | Kuhn, Colin Watson, Christopher Staite, Lorenz Diener, Christian 7 | Brabandt, Jeff Smith, Pavel Kryukov, Maxim Kuznetsov, Svyatoslav 8 | Kuzmich, Nico Williams, Viktor Dukhovni, and CORE SDI S.A. 9 | 10 | Permission is hereby granted, free of charge, to any person 11 | obtaining a copy of this software and associated documentation files 12 | (the "Software"), to deal in the Software without restriction, 13 | including without limitation the rights to use, copy, modify, merge, 14 | publish, distribute, sublicense, and/or sell copies of the Software, 15 | and to permit persons to whom the Software is furnished to do so, 16 | subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be 19 | included in all copies or substantial portions of the Software. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE 25 | FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 26 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | -------------------------------------------------------------------------------- /unix/pterm.bundle: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | ${env:PUTTY_GTK_PREFIX_FROM_MAKEFILE} 9 | 10 | 11 | gtk+-3.0 12 | 18 | ${project}/../osxlaunch 19 | 20 | 21 | ${project}/pterm.plist 22 | 23 | 24 | ${project}/../ptermapp 25 | 26 | 27 | 28 | ${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/immodules/*.so 29 | 30 | 31 | 32 | ${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/printbackends/*.so 33 | 34 | 35 | 36 | ${prefix}/share/themes/Adwaita 37 | 38 | 39 | 40 | ${project}/../icons/Pterm.icns 41 | 42 | 43 | 44 | Adwaita 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /nocmdline.c: -------------------------------------------------------------------------------- 1 | /* 2 | * nocmdline.c - stubs in applications which don't do the 3 | * standard(ish) PuTTY tools' command-line parsing 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include "putty.h" 10 | 11 | /* 12 | * Stub version of the function in cmdline.c which provides the 13 | * password to SSH authentication by remembering it having been passed 14 | * as a command-line option. If we're not doing normal command-line 15 | * handling, then there is no such option, so that function always 16 | * returns failure. 17 | */ 18 | int cmdline_get_passwd_input(prompts_t *p) 19 | { 20 | return -1; 21 | } 22 | 23 | /* 24 | * The main cmdline_process_param function is normally called from 25 | * applications' main(). An application linking against this stub 26 | * module shouldn't have a main() that calls it in the first place :-) 27 | * but it is just occasionally called by other supporting functions, 28 | * such as one in uxputty.c which sometimes handles a non-option 29 | * argument by making up equivalent options and passing them back to 30 | * this function. So we have to provide a link-time stub of this 31 | * function, but it had better not end up being called at run time. 32 | */ 33 | int cmdline_process_param(const char *p, char *value, 34 | int need_save, Conf *conf) 35 | { 36 | assert(FALSE && "cmdline_process_param should never be called"); 37 | } 38 | 39 | /* 40 | * This variable will be referred to, so it has to exist. It's ignored. 41 | */ 42 | int cmdline_tooltype = 0; 43 | -------------------------------------------------------------------------------- /errsock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * A dummy Socket implementation which just holds an error message. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | #define DEFINE_PLUG_METHOD_MACROS 9 | #include "tree234.h" 10 | #include "putty.h" 11 | #include "network.h" 12 | 13 | typedef struct { 14 | char *error; 15 | Plug plug; 16 | 17 | const Socket_vtable *sockvt; 18 | } ErrorSocket; 19 | 20 | static Plug sk_error_plug(Socket s, Plug p) 21 | { 22 | ErrorSocket *es = FROMFIELD(s, ErrorSocket, sockvt); 23 | Plug ret = es->plug; 24 | if (p) 25 | es->plug = p; 26 | return ret; 27 | } 28 | 29 | static void sk_error_close(Socket s) 30 | { 31 | ErrorSocket *es = FROMFIELD(s, ErrorSocket, sockvt); 32 | 33 | sfree(es->error); 34 | sfree(es); 35 | } 36 | 37 | static const char *sk_error_socket_error(Socket s) 38 | { 39 | ErrorSocket *es = FROMFIELD(s, ErrorSocket, sockvt); 40 | return es->error; 41 | } 42 | 43 | static char *sk_error_peer_info(Socket s) 44 | { 45 | return NULL; 46 | } 47 | 48 | static const Socket_vtable ErrorSocket_sockvt = { 49 | sk_error_plug, 50 | sk_error_close, 51 | NULL /* write */, 52 | NULL /* write_oob */, 53 | NULL /* write_eof */, 54 | NULL /* flush */, 55 | NULL /* set_frozen */, 56 | sk_error_socket_error, 57 | sk_error_peer_info, 58 | }; 59 | 60 | Socket new_error_socket(const char *errmsg, Plug plug) 61 | { 62 | ErrorSocket *es = snew(ErrorSocket); 63 | es->sockvt = &ErrorSocket_sockvt; 64 | es->plug = plug; 65 | es->error = dupstr(errmsg); 66 | return &es->sockvt; 67 | } 68 | -------------------------------------------------------------------------------- /rdb/win256c.txt: -------------------------------------------------------------------------------- 1 | | style="color: black; background-color: #00FF00" | green lime 2 | | style="color: black; background-color: #00FFFF" | cyan aqua 3 | | style="color: black; background-color: #A0A0A4" | medium grey 4 | | style="color: black; background-color: #A6CAF0" | sky blue 5 | | style="color: black; background-color: #C0C0C0" | light grey silver 6 | | style="color: black; background-color: #C0DCC0" | money green 7 | | style="color: black; background-color: #FF00FF" | magenta fuchsia 8 | | style="color: black; background-color: #FFFBF0" | cream 9 | | style="color: black; background-color: #FFFF00" | yellow yellow 10 | | style="color: black; background-color: #FFFFFF" | white white 11 | | style="color: white; background-color: #000000" | black black 12 | | style="color: white; background-color: #000080" | dark blue navy 13 | | style="color: white; background-color: #0000FF" | blue blue 14 | | style="color: white; background-color: #008000" | dark green green 15 | | style="color: white; background-color: #008080" | dark cyan teal 16 | | style="color: white; background-color: #800000" | dark red maroon 17 | | style="color: white; background-color: #800080" | dark magenta purple 18 | | style="color: white; background-color: #808000" | dark yellow olive 19 | | style="color: white; background-color: #808080" | dark grey gray 20 | | style="color: white; background-color: #FF0000" | red red 21 | -------------------------------------------------------------------------------- /version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This header file provides the various versioning-related #defines 3 | * for a particular PuTTY build. 4 | * 5 | * When my automated build system does a full build, Buildscr 6 | * completely overwrites this file with information derived from the 7 | * circumstances and type of that build. The information _here_ is 8 | * default stuff used for local development runs of 'make'. 9 | */ 10 | 11 | #define TEXTVER "Unidentified build" 12 | #define SSHVER "PuTTY-Unidentified-Local-Build" 13 | #define BINARY_VERSION 0,0,0,0 14 | 15 | #ifndef SOURCE_COMMIT 16 | /* 17 | * git commit id from which this build was made. This is defined by 18 | * Buildscr for official builds - both source archives and prebuilt 19 | * binaries - in the course of overwriting this file as described 20 | * above. But we put it here under ifdef, so that it can also be 21 | * passed in on the command line for Unix local development builds, 22 | * which I treat specially because Unix developers - e.g. me - are 23 | * quite likely to run 'make install' straight out of their dev 24 | * directory so as to use the bleeding-edge code for day-to-day 25 | * running. 26 | * 27 | * Windows doesn't really need the same treatment, because the easiest 28 | * way to install a build properly on Windows is to run the installer, 29 | * and the easiest way to do that is to run Buildscr, which will 30 | * populate this field its own way. It's only the Unix automake build 31 | * where you might go straight from local 'make' to 'make install' 32 | * without going through Buildscr. 33 | */ 34 | #define SOURCE_COMMIT "unavailable" 35 | #endif 36 | -------------------------------------------------------------------------------- /unix/uxgen.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uxgen.c: Unix implementation of get_heavy_noise() from cmdgen.c. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include "putty.h" 12 | 13 | char *get_random_data(int len, const char *device) 14 | { 15 | char *buf = snewn(len, char); 16 | int fd; 17 | int ngot, ret; 18 | 19 | if (!device) { 20 | static const char *const default_devices[] = { 21 | "/dev/urandom", "/dev/random" 22 | }; 23 | size_t i; 24 | 25 | for (i = 0; i < lenof(default_devices); i++) { 26 | if (access(default_devices[i], R_OK) == 0) { 27 | device = default_devices[i]; 28 | break; 29 | } 30 | } 31 | 32 | if (!device) { 33 | sfree(buf); 34 | fprintf(stderr, "puttygen: cannot find a readable " 35 | "random number source; use --random-device\n"); 36 | return NULL; 37 | } 38 | } 39 | 40 | fd = open(device, O_RDONLY); 41 | if (fd < 0) { 42 | sfree(buf); 43 | fprintf(stderr, "puttygen: %s: open: %s\n", 44 | device, strerror(errno)); 45 | return NULL; 46 | } 47 | 48 | ngot = 0; 49 | while (ngot < len) { 50 | ret = read(fd, buf+ngot, len-ngot); 51 | if (ret < 0) { 52 | close(fd); 53 | sfree(buf); 54 | fprintf(stderr, "puttygen: %s: read: %s\n", 55 | device, strerror(errno)); 56 | return NULL; 57 | } 58 | ngot += ret; 59 | } 60 | 61 | close(fd); 62 | 63 | return buf; 64 | } 65 | -------------------------------------------------------------------------------- /sign.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Generate GPG signatures on a PuTTY release/snapshot directory as 4 | # delivered by Buildscr. 5 | 6 | # Usage: sh sign.sh [-r] 7 | # e.g. sh sign.sh putty (probably in the build.out directory) 8 | # or sh sign.sh -r 0.60 (-r means use the release keys) 9 | 10 | set -e 11 | 12 | keyname=EEF20295D15F7E8A 13 | preliminary=false 14 | 15 | while :; do 16 | case "$1" in 17 | -r) 18 | shift 19 | keyname=9DFE2648B43434E4 20 | ;; 21 | -p) 22 | shift 23 | preliminary=true 24 | ;; 25 | -*) 26 | echo "Unknown option '$1'" >&2 27 | exit 1 28 | ;; 29 | *) 30 | break 31 | ;; 32 | esac 33 | done 34 | 35 | sign() { 36 | # Check for the prior existence of the signature, so we can 37 | # re-run this script if it encounters an error part way 38 | # through. 39 | echo "----- Signing $2 with key '$keyname'" 40 | test -f "$3" || \ 41 | gpg --load-extension=idea "$1" -u "$keyname" -o "$3" "$2" 42 | } 43 | 44 | cd "$1" 45 | echo "===== Signing with key '$keyname'" 46 | if $preliminary; then 47 | sign --clearsign sha512sums ../sha512sums-preliminary.gpg 48 | else 49 | for i in putty*src.zip putty*.tar.gz \ 50 | w32/*.exe w32/*.zip w32/*.msi \ 51 | w64/*.exe w64/*.zip w64/*.msi \ 52 | w32old/*.exe w32old/*.zip; do 53 | sign --detach-sign "$i" "$i.gpg" 54 | done 55 | for i in md5sums sha1sums sha256sums sha512sums; do 56 | sign --clearsign "$i" "$i.gpg" 57 | done 58 | fi 59 | -------------------------------------------------------------------------------- /rdb/Missing-patches/rdb24bit/0010-ITU-T-T.416-truecolour-fuzzterm.patch: -------------------------------------------------------------------------------- 1 | From c088688bdec650b98c1534163875f25fd1d4dd2d Mon Sep 17 00:00:00 2001 2 | From: Robert de Bath 3 | Date: Sat, 7 Nov 2015 22:02:57 +0000 4 | Subject: [PATCH 10/71] ITU-T T.416 truecolour (fuzzterm) 5 | 6 | --- 7 | fuzzterm.c | 8 ++++---- 8 | 1 file changed, 4 insertions(+), 4 deletions(-) 9 | 10 | diff --git a/fuzzterm.c b/fuzzterm.c 11 | index 15b5d63..b5193ec 100644 12 | --- a/fuzzterm.c 13 | +++ b/fuzzterm.c 14 | @@ -45,22 +45,22 @@ int from_backend(void *frontend, int is_stderr, const char *data, int len) 15 | 16 | void request_resize(void *frontend, int x, int y) { } 17 | void do_text(Context ctx, int x, int y, wchar_t * text, int len, 18 | - unsigned long attr, int lattr) 19 | + unsigned long attr, int lattr, int fg_col, int bg_col) 20 | { 21 | int i; 22 | 23 | - printf("TEXT[attr=%08lx,lattr=%02x]@(%d,%d):", attr, lattr, x, y); 24 | + printf("TEXT[attr=%08lx,lattr=%02x,fg=%d,bg=%d]@(%d,%d):", attr, lattr, fg_col, bg_col, x, y); 25 | for (i = 0; i < len; i++) { 26 | printf(" %x", (unsigned)text[i]); 27 | } 28 | printf("\n"); 29 | } 30 | void do_cursor(Context ctx, int x, int y, wchar_t * text, int len, 31 | - unsigned long attr, int lattr) 32 | + unsigned long attr, int lattr, int fg_col, int bg_col) 33 | { 34 | int i; 35 | 36 | - printf("CURS[attr=%08lx,lattr=%02x]@(%d,%d):", attr, lattr, x, y); 37 | + printf("CURS[attr=%08lx,lattr=%02x,fg=%d,bg=%d]@(%d,%d):", attr, lattr, fg_col, bg_col, x, y); 38 | for (i = 0; i < len; i++) { 39 | printf(" %x", (unsigned)text[i]); 40 | } 41 | -- 42 | 2.1.4 43 | 44 | -------------------------------------------------------------------------------- /windows/README.txt: -------------------------------------------------------------------------------- 1 | PuTTY README 2 | ============ 3 | 4 | This is the README file for the PuTTY installer distribution. If 5 | you're reading this, you've probably just run our installer and 6 | installed PuTTY on your system. 7 | 8 | What should I do next? 9 | ---------------------- 10 | 11 | If you want to use PuTTY to connect to other computers, or use PSFTP 12 | to transfer files, you should just be able to run them from the 13 | Start menu. 14 | 15 | If you want to use the command-line-only file transfer utility PSCP, 16 | you will probably want to put the PuTTY installation directory on 17 | your PATH. On Windows 7 and similar versions, you can do this at 18 | Control Panel > System and Security > System > Advanced system 19 | settings > Environment Variables. 20 | 21 | Some versions of Windows will refuse to run HTML Help files (.CHM) 22 | if they are installed on a network drive. If you have installed 23 | PuTTY on a network drive, you might want to check that the help file 24 | works properly. If not, see http://support.microsoft.com/kb/896054 25 | for information on how to solve this problem. 26 | 27 | What do I do if it doesn't work? 28 | -------------------------------- 29 | 30 | The PuTTY home web site is 31 | 32 | https://www.chiark.greenend.org.uk/~sgtatham/putty/ 33 | 34 | Here you will find our list of known bugs and pending feature 35 | requests. If your problem is not listed in there, or in the FAQ, or 36 | in the manuals, read the Feedback page to find out how to report 37 | bugs to us. PLEASE read the Feedback page carefully: it is there to 38 | save you time as well as us. Do not send us one-line bug reports 39 | telling us `it doesn't work'. 40 | -------------------------------------------------------------------------------- /contrib/cygtermd/malloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * malloc.h: safe wrappers around malloc, realloc, free, strdup 3 | */ 4 | 5 | #ifndef UMLWRAP_MALLOC_H 6 | #define UMLWRAP_MALLOC_H 7 | 8 | #include 9 | 10 | /* 11 | * smalloc should guarantee to return a useful pointer - Halibut 12 | * can do nothing except die when it's out of memory anyway. 13 | */ 14 | void *smalloc(size_t size); 15 | 16 | /* 17 | * srealloc should guaranteeably be able to realloc NULL 18 | */ 19 | void *srealloc(void *p, size_t size); 20 | 21 | /* 22 | * sfree should guaranteeably deal gracefully with freeing NULL 23 | */ 24 | void sfree(void *p); 25 | 26 | /* 27 | * dupstr is like strdup, but with the never-return-NULL property 28 | * of smalloc (and also reliably defined in all environments :-) 29 | */ 30 | char *dupstr(const char *s); 31 | 32 | /* 33 | * snew allocates one instance of a given type, and casts the 34 | * result so as to type-check that you're assigning it to the 35 | * right kind of pointer. Protects against allocation bugs 36 | * involving allocating the wrong size of thing. 37 | */ 38 | #define snew(type) \ 39 | ( (type *) smalloc (sizeof (type)) ) 40 | 41 | /* 42 | * snewn allocates n instances of a given type, for arrays. 43 | */ 44 | #define snewn(number, type) \ 45 | ( (type *) smalloc ((number) * sizeof (type)) ) 46 | 47 | /* 48 | * sresize wraps realloc so that you specify the new number of 49 | * elements and the type of the element, with the same type- 50 | * checking advantages. Also type-checks the input pointer. 51 | */ 52 | #define sresize(array, number, type) \ 53 | ( (void)sizeof((array)-(type *)0), \ 54 | (type *) srealloc ((array), (number) * sizeof (type)) ) 55 | 56 | #endif /* UMLWRAP_MALLOC_H */ 57 | -------------------------------------------------------------------------------- /doc/blurb.but: -------------------------------------------------------------------------------- 1 | \define{dash} \u2013{-} 2 | 3 | \title PuTTY User Manual 4 | 5 | \cfg{xhtml-leaf-level}{1} 6 | \cfg{xhtml-leaf-smallest-contents}{2} 7 | \cfg{xhtml-leaf-contains-contents}{true} 8 | \cfg{xhtml-body-end}{

If you want to provide feedback on this manual 9 | or on the PuTTY tools themselves, see the 10 | Feedback 11 | page.

} 12 | 13 | \cfg{html-template-fragment}{%k}{%b} 14 | 15 | \cfg{info-max-file-size}{0} 16 | 17 | \cfg{chm-contents-filename}{index.html} 18 | \cfg{chm-template-filename}{%k.html} 19 | \cfg{chm-head-end}{} 20 | \cfg{chm-extra-file}{chm.css} 21 | 22 | \cfg{xhtml-contents-filename}{index.html} 23 | \cfg{text-filename}{puttydoc.txt} 24 | \cfg{winhelp-filename}{putty.hlp} 25 | \cfg{info-filename}{putty.info} 26 | \cfg{chm-filename}{putty.chm} 27 | 28 | PuTTY is a free (MIT-licensed) Windows Telnet and SSH client. This 29 | manual documents PuTTY, and its companion utilities PSCP, PSFTP, 30 | Plink, Pageant and PuTTYgen. 31 | 32 | \e{Note to Unix users:} this manual currently primarily documents the 33 | Windows versions of the PuTTY utilities. Some options are therefore 34 | mentioned that are absent from the \i{Unix version}; the Unix version has 35 | features not described here; and the \i\cw{pterm} and command-line 36 | \cw{puttygen} utilities are not described at all. The only 37 | Unix-specific documentation that currently exists is the 38 | \I{man pages for PuTTY tools}man pages. 39 | 40 | \copyright This manual is copyright \shortcopyrightdetails. All 41 | rights reserved. You may distribute this documentation under the MIT 42 | licence. See \k{licence} for the licence text in full. 43 | -------------------------------------------------------------------------------- /contrib/logrewrap.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | # Process a PuTTY SSH packet log that has gone through inappropriate 4 | # line wrapping, and try to make it legible again. 5 | # 6 | # Motivation: people often include PuTTY packet logs in email 7 | # messages, and if they're not careful, the sending MUA 'helpfully' 8 | # wraps the lines at 72 characters, corrupting all the hex dumps into 9 | # total unreadability. 10 | # 11 | # But as long as it's only the ASCII part of the dump at the end of 12 | # the line that gets wrapped, and the hex part is untouched, this is a 13 | # mechanically recoverable kind of corruption, because the ASCII is 14 | # redundant and can be reconstructed from the hex. Better still, you 15 | # can spot lines in which this has happened (because the ASCII at the 16 | # end of the line is a truncated version of what we think it should 17 | # say), and use that as a cue to remove the following line. 18 | 19 | use strict; 20 | use warnings; 21 | 22 | while (<>) { 23 | if (/^ ([0-9a-f]{8}) ((?:[0-9a-f]{2} ){0,15}(?:[0-9a-f]{2}))/) { 24 | my $addr = $1; 25 | my $hex = $2; 26 | my $ascii = ""; 27 | for (my $i = 0; $i < length($2); $i += 3) { 28 | my $byte = hex(substr($hex, $i, 2)); 29 | my $char = ($byte >= 32 && $byte < 127 ? chr($byte) : "."); 30 | $ascii .= $char; 31 | } 32 | $hex = substr($hex . (" " x 48), 0, 47); 33 | my $old_line = $_; 34 | chomp($old_line); 35 | my $new_line = " $addr $hex $ascii"; 36 | if ($old_line ne $new_line and 37 | $old_line eq substr($new_line, 0, length($old_line))) { 38 | print "$new_line\n"; 39 | <>; # eat the subsequent wrapped line 40 | next; 41 | } 42 | } 43 | print $_; 44 | } 45 | -------------------------------------------------------------------------------- /windows/puttygen.rc: -------------------------------------------------------------------------------- 1 | /* 2 | * Windows resources for PuTTYgen. 3 | */ 4 | 5 | #include "rcstuff.h" 6 | 7 | #define APPNAME "PuTTYgen" 8 | #define APPDESC "PuTTY SSH key generation utility" 9 | 10 | 200 ICON "puttygen.ico" 11 | 12 | 201 DIALOG DISCARDABLE 0, 0, 318, 270 13 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 14 | CAPTION "PuTTY Key Generator" 15 | FONT 8, "MS Shell Dlg" 16 | BEGIN 17 | END 18 | 19 | 210 DIALOG DISCARDABLE 0, 0, 140, 60 20 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 21 | CAPTION "PuTTYgen: Enter Passphrase" 22 | FONT 8, "MS Shell Dlg" 23 | BEGIN 24 | CTEXT "Enter passphrase for key", 100, 10, 6, 120, 8 25 | CTEXT "", 101, 10, 16, 120, 8 26 | EDITTEXT 102, 10, 26, 120, 12, ES_PASSWORD | ES_AUTOHSCROLL 27 | DEFPUSHBUTTON "O&K", IDOK, 20, 42, 40, 14 28 | PUSHBUTTON "&Cancel", IDCANCEL, 80, 42, 40, 14 29 | END 30 | 31 | /* Accelerators used: cl */ 32 | 213 DIALOG DISCARDABLE 140, 40, 270, 106 33 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 34 | CAPTION "About PuTTYgen" 35 | FONT 8, "MS Shell Dlg" 36 | BEGIN 37 | DEFPUSHBUTTON "&Close", IDOK, 216, 88, 48, 14 38 | PUSHBUTTON "View &Licence", 101, 6, 88, 70, 14 39 | PUSHBUTTON "Visit &Web Site", 102, 140, 88, 70, 14 40 | EDITTEXT 1000, 10, 6, 250, 80, ES_READONLY | ES_MULTILINE | ES_CENTER, WS_EX_STATICEDGE 41 | END 42 | 43 | /* No accelerators used */ 44 | 214 DIALOG DISCARDABLE 50, 50, 326, 231 45 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 46 | CAPTION "PuTTY Licence" 47 | FONT 8, "MS Shell Dlg" 48 | BEGIN 49 | DEFPUSHBUTTON "OK", IDOK, 148, 211, 44, 14 50 | 51 | EDITTEXT 1000, 10, 10, 306, 192, ES_READONLY | ES_MULTILINE | ES_LEFT, WS_EX_STATICEDGE 52 | END 53 | 54 | #include "version.rc2" 55 | 56 | #ifndef NO_MANIFESTS 57 | 1 RT_MANIFEST "puttygen.mft" 58 | #endif /* NO_MANIFESTS */ 59 | -------------------------------------------------------------------------------- /rdb/git-commit-putty-bin: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # This is required to clear the windows compile timestamp, and, obviously, 5 | # it makes things smaller. 6 | 7 | for i in $(ls windows/*.exe) 8 | do 9 | j=$(basename $i .exe) 10 | i686-w64-mingw32-strip -p $i 11 | [ -f unix/$j ] && strip -p unix/$j 12 | done 13 | 14 | NCOMMIT=$( 15 | { 16 | { 17 | sed 's/^[ ]*//' < $(date +%s) +0000 46 | committer Makefile <> $(date +%s) +0000 47 | 48 | PuTTY binaries. 49 | " ; } | git hash-object -t commit -w --stdin ) 50 | 51 | # If 'binary' branch is missing create it quietly. 52 | [ "$(git show-ref --hash refs/heads/binary)" = "" ] && 53 | git update-ref refs/heads/binary $NCOMMIT 54 | 55 | # Only update if the tree changed. 56 | [ "$(git log -1 --format=%T $NCOMMIT)" != "$(git log -1 --format=%T refs/heads/binary)" ] && { 57 | git update-ref refs/heads/binary $NCOMMIT 58 | echo Updated refs/heads/binary 59 | } 60 | 61 | exit 0 62 | -------------------------------------------------------------------------------- /sshbpp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Abstraction of the binary packet protocols used in SSH. 3 | */ 4 | 5 | #ifndef PUTTY_SSHBPP_H 6 | #define PUTTY_SSHBPP_H 7 | 8 | typedef struct BinaryPacketProtocol BinaryPacketProtocol; 9 | 10 | struct BinaryPacketProtocolVtable { 11 | void (*free)(BinaryPacketProtocol *); 12 | void (*handle_input)(BinaryPacketProtocol *); 13 | PktOut *(*new_pktout)(int type); 14 | void (*format_packet)(BinaryPacketProtocol *, PktOut *); 15 | }; 16 | 17 | struct BinaryPacketProtocol { 18 | const struct BinaryPacketProtocolVtable *vt; 19 | bufchain *in_raw, *out_raw; 20 | PacketQueue *in_pq; 21 | PacketLogSettings *pls; 22 | void *logctx; 23 | 24 | int seen_disconnect; 25 | char *error; 26 | }; 27 | 28 | #define ssh_bpp_free(bpp) ((bpp)->vt->free(bpp)) 29 | #define ssh_bpp_handle_input(bpp) ((bpp)->vt->handle_input(bpp)) 30 | #define ssh_bpp_new_pktout(bpp, type) ((bpp)->vt->new_pktout(type)) 31 | #define ssh_bpp_format_packet(bpp, pkt) ((bpp)->vt->format_packet(bpp, pkt)) 32 | 33 | BinaryPacketProtocol *ssh1_bpp_new(void); 34 | void ssh1_bpp_new_cipher(BinaryPacketProtocol *bpp, 35 | const struct ssh_cipher *cipher, 36 | const void *session_key); 37 | void ssh1_bpp_start_compression(BinaryPacketProtocol *bpp); 38 | 39 | BinaryPacketProtocol *ssh2_bpp_new(void); 40 | void ssh2_bpp_new_outgoing_crypto( 41 | BinaryPacketProtocol *bpp, 42 | const struct ssh2_cipher *cipher, const void *ckey, const void *iv, 43 | const struct ssh_mac *mac, int etm_mode, const void *mac_key, 44 | const struct ssh_compress *compression); 45 | void ssh2_bpp_new_incoming_crypto( 46 | BinaryPacketProtocol *bpp, 47 | const struct ssh2_cipher *cipher, const void *ckey, const void *iv, 48 | const struct ssh_mac *mac, int etm_mode, const void *mac_key, 49 | const struct ssh_compress *compression); 50 | 51 | BinaryPacketProtocol *ssh2_bare_bpp_new(void); 52 | 53 | #endif /* PUTTY_SSHBPP_H */ 54 | -------------------------------------------------------------------------------- /pinger.c: -------------------------------------------------------------------------------- 1 | /* 2 | * pinger.c: centralised module that deals with sending TS_PING 3 | * keepalives, to avoid replicating this code in multiple backends. 4 | */ 5 | 6 | #include "putty.h" 7 | 8 | struct pinger_tag { 9 | int interval; 10 | int pending; 11 | unsigned long when_set, next; 12 | Backend *back; 13 | void *backhandle; 14 | }; 15 | 16 | static void pinger_schedule(Pinger pinger); 17 | 18 | static void pinger_timer(void *ctx, unsigned long now) 19 | { 20 | Pinger pinger = (Pinger)ctx; 21 | 22 | if (pinger->pending && now == pinger->next) { 23 | pinger->back->special(pinger->backhandle, TS_PING); 24 | pinger->pending = FALSE; 25 | pinger_schedule(pinger); 26 | } 27 | } 28 | 29 | static void pinger_schedule(Pinger pinger) 30 | { 31 | unsigned long next; 32 | 33 | if (!pinger->interval) { 34 | pinger->pending = FALSE; /* cancel any pending ping */ 35 | return; 36 | } 37 | 38 | next = schedule_timer(pinger->interval * TICKSPERSEC, 39 | pinger_timer, pinger); 40 | if (!pinger->pending || 41 | (next - pinger->when_set) < (pinger->next - pinger->when_set)) { 42 | pinger->next = next; 43 | pinger->when_set = timing_last_clock(); 44 | pinger->pending = TRUE; 45 | } 46 | } 47 | 48 | Pinger pinger_new(Conf *conf, Backend *back, void *backhandle) 49 | { 50 | Pinger pinger = snew(struct pinger_tag); 51 | 52 | pinger->interval = conf_get_int(conf, CONF_ping_interval); 53 | pinger->pending = FALSE; 54 | pinger->back = back; 55 | pinger->backhandle = backhandle; 56 | pinger_schedule(pinger); 57 | 58 | return pinger; 59 | } 60 | 61 | void pinger_reconfig(Pinger pinger, Conf *oldconf, Conf *newconf) 62 | { 63 | int newinterval = conf_get_int(newconf, CONF_ping_interval); 64 | if (conf_get_int(oldconf, CONF_ping_interval) != newinterval) { 65 | pinger->interval = newinterval; 66 | pinger_schedule(pinger); 67 | } 68 | } 69 | 70 | void pinger_free(Pinger pinger) 71 | { 72 | expire_timer_context(pinger); 73 | sfree(pinger); 74 | } 75 | -------------------------------------------------------------------------------- /windows/README-msi.txt: -------------------------------------------------------------------------------- 1 | PuTTY README 2 | ============ 3 | 4 | This is the README file for the PuTTY MSI installer distribution. If 5 | you're reading this, you've probably just run our installer and 6 | installed PuTTY on your system. 7 | 8 | What should I do next? 9 | ---------------------- 10 | 11 | If you want to use PuTTY to connect to other computers, or use PSFTP 12 | to transfer files, you should just be able to run them from the 13 | Start menu. 14 | 15 | If you want to use the command-line file transfer utility PSCP, you 16 | will need to run this from a Command Prompt or equivalent, because it 17 | will not do anything useful without command-line options telling it 18 | what files to copy to and from where. You can do this by just running 19 | the command 'pscp' from a Command Prompt, if you used the installer's 20 | option to put the PuTTY installation directory on your PATH. 21 | Alternatively, you can always run pscp.exe by its full pathname, e.g. 22 | "C:\Program Files\PuTTY\pscp.exe". 23 | 24 | (Note that a Command Prompt that was already open before you ran the 25 | installer will not have inherited the update of PATH.) 26 | 27 | Some versions of Windows will refuse to run HTML Help files (.CHM) 28 | if they are installed on a network drive. If you have installed 29 | PuTTY on a network drive, you might want to check that the help file 30 | works properly. If not, see http://support.microsoft.com/kb/896054 31 | for information on how to solve this problem. 32 | 33 | What do I do if it doesn't work? 34 | -------------------------------- 35 | 36 | The PuTTY home web site is 37 | 38 | https://www.chiark.greenend.org.uk/~sgtatham/putty/ 39 | 40 | Here you will find our list of known bugs and pending feature 41 | requests. If your problem is not listed in there, or in the FAQ, or 42 | in the manuals, read the Feedback page to find out how to report 43 | bugs to us. PLEASE read the Feedback page carefully: it is there to 44 | save you time as well as us. Do not send us one-line bug reports 45 | telling us `it doesn't work'. 46 | -------------------------------------------------------------------------------- /windows/version.rc2: -------------------------------------------------------------------------------- 1 | /* 2 | * Standard Windows version information. 3 | * (For inclusion in other .rc files with appropriate macro definitions.) 4 | * FIXME: This file is called '.rc2' rather than '.rc' to avoid MSVC trying 5 | * to compile it on its own when using the project files. Nicer solutions 6 | * welcome. 7 | */ 8 | 9 | #include "version.h" 10 | #include "licence.h" 11 | 12 | /* 13 | * The actual VERSIONINFO resource. 14 | */ 15 | VS_VERSION_INFO VERSIONINFO 16 | /* (None of this "fixed" info appears to be trivially user-visible on 17 | * Win98SE. The binary version does show up on Win2K.) */ 18 | FILEVERSION BINARY_VERSION 19 | PRODUCTVERSION BINARY_VERSION /* version of whole suite */ 20 | FILEFLAGSMASK VS_FF_DEBUG | VS_FF_PRERELEASE | VS_FF_PRIVATEBUILD 21 | FILEFLAGS 0x0L 22 | #if defined DEBUG 23 | | VS_FF_DEBUG 24 | #endif 25 | #if defined SNAPSHOT || defined PRERELEASE 26 | | VS_FF_PRERELEASE 27 | #elif !defined RELEASE 28 | | VS_FF_PRIVATEBUILD 29 | #endif 30 | FILEOS VOS__WINDOWS32 31 | FILETYPE VFT_APP 32 | FILESUBTYPE 0x0L /* n/a for VFT_APP */ 33 | BEGIN 34 | /* (On Win98SE and Win2K, we can see most of this on the Version tab 35 | * in the file properties in Explorer.) */ 36 | BLOCK "StringFileInfo" 37 | BEGIN 38 | /* "lang-charset" LLLLCCCC = (UK English, Unicode) */ 39 | BLOCK "080904B0" 40 | BEGIN 41 | VALUE "CompanyName", "Simon Tatham" /* required :/ */ 42 | VALUE "ProductName", "PuTTY suite" 43 | VALUE "FileDescription", APPDESC 44 | VALUE "InternalName", APPNAME 45 | VALUE "OriginalFilename", APPNAME 46 | VALUE "FileVersion", TEXTVER 47 | VALUE "ProductVersion", TEXTVER 48 | VALUE "LegalCopyright", "Copyright \251 " SHORT_COPYRIGHT_DETAILS "." 49 | #if (!defined SNAPSHOT) && (!defined RELEASE) && (!defined PRERELEASE) 50 | /* Only if VS_FF_PRIVATEBUILD. */ 51 | VALUE "PrivateBuild", TEXTVER /* NBI */ 52 | #endif 53 | END 54 | END 55 | BLOCK "VarFileInfo" 56 | BEGIN 57 | /* Once again -- same meanings -- apparently necessary */ 58 | VALUE "Translation", 0x809, 1200 59 | END 60 | END 61 | -------------------------------------------------------------------------------- /sshcr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Coroutine mechanics used in PuTTY's SSH code. 3 | */ 4 | 5 | #ifndef PUTTY_SSHCR_H 6 | #define PUTTY_SSHCR_H 7 | 8 | /* 9 | * If these macros look impenetrable to you, you might find it helpful 10 | * to read 11 | * 12 | * https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html 13 | * 14 | * which explains the theory behind these macros. 15 | * 16 | * In particular, if you are getting `case expression not constant' 17 | * errors when building with MS Visual Studio, this is because MS's 18 | * Edit and Continue debugging feature causes their compiler to 19 | * violate ANSI C. To disable Edit and Continue debugging: 20 | * 21 | * - right-click ssh.c in the FileView 22 | * - click Settings 23 | * - select the C/C++ tab and the General category 24 | * - under `Debug info:', select anything _other_ than `Program 25 | * Database for Edit and Continue'. 26 | */ 27 | 28 | #define crBegin(v) { int *crLine = &v; switch(v) { case 0:; 29 | #define crBeginState crBegin(s->crLine) 30 | #define crStateP(t, v) \ 31 | struct t *s; \ 32 | if (!(v)) { s = (v) = snew(struct t); s->crLine = 0; } \ 33 | s = (v); 34 | #define crState(t) crStateP(t, ssh->t) 35 | #define crFinish(z) } *crLine = 0; return (z); } 36 | #define crFinishV } *crLine = 0; return; } 37 | #define crFinishFree(z) } sfree(s); return (z); } 38 | #define crFinishFreeV } sfree(s); return; } 39 | #define crReturn(z) \ 40 | do {\ 41 | *crLine =__LINE__; return (z); case __LINE__:;\ 42 | } while (0) 43 | #define crReturnV \ 44 | do {\ 45 | *crLine=__LINE__; return; case __LINE__:;\ 46 | } while (0) 47 | #define crStop(z) do{ *crLine = 0; return (z); }while(0) 48 | #define crStopV do{ *crLine = 0; return; }while(0) 49 | #define crWaitUntil(c) do { crReturn(0); } while (!(c)) 50 | #define crWaitUntilV(c) do { crReturnV; } while (!(c)) 51 | #define crMaybeWaitUntil(c) do { while (!(c)) crReturn(0); } while (0) 52 | #define crMaybeWaitUntilV(c) do { while (!(c)) crReturnV; } while (0) 53 | 54 | #endif /* PUTTY_SSHCR_H */ 55 | -------------------------------------------------------------------------------- /sshecdsag.c: -------------------------------------------------------------------------------- 1 | /* 2 | * EC key generation. 3 | */ 4 | 5 | #include "ssh.h" 6 | 7 | /* Forward reference from sshecc.c */ 8 | struct ec_point *ecp_mul(const struct ec_point *a, const Bignum b); 9 | 10 | int ec_generate(struct ec_key *key, int bits, progfn_t pfn, 11 | void *pfnparam) 12 | { 13 | struct ec_point *publicKey; 14 | 15 | if (!ec_nist_alg_and_curve_by_bits(bits, &key->publicKey.curve, 16 | &key->sshk)) 17 | return 0; 18 | 19 | key->privateKey = bignum_random_in_range(One, key->publicKey.curve->w.n); 20 | if (!key->privateKey) return 0; 21 | 22 | publicKey = ec_public(key->privateKey, key->publicKey.curve); 23 | if (!publicKey) { 24 | freebn(key->privateKey); 25 | key->privateKey = NULL; 26 | return 0; 27 | } 28 | 29 | key->publicKey.x = publicKey->x; 30 | key->publicKey.y = publicKey->y; 31 | key->publicKey.z = NULL; 32 | sfree(publicKey); 33 | 34 | return 1; 35 | } 36 | 37 | int ec_edgenerate(struct ec_key *key, int bits, progfn_t pfn, 38 | void *pfnparam) 39 | { 40 | struct ec_point *publicKey; 41 | 42 | if (!ec_ed_alg_and_curve_by_bits(bits, &key->publicKey.curve, 43 | &key->sshk)) 44 | return 0; 45 | 46 | { 47 | /* EdDSA secret keys are just 32 bytes of hash preimage; the 48 | * 64-byte SHA-512 hash of that key will be used when signing, 49 | * but the form of the key stored on disk is the preimage 50 | * only. */ 51 | Bignum privMax = bn_power_2(bits); 52 | if (!privMax) return 0; 53 | key->privateKey = bignum_random_in_range(Zero, privMax); 54 | freebn(privMax); 55 | if (!key->privateKey) return 0; 56 | } 57 | 58 | publicKey = ec_public(key->privateKey, key->publicKey.curve); 59 | if (!publicKey) { 60 | freebn(key->privateKey); 61 | key->privateKey = NULL; 62 | return 0; 63 | } 64 | 65 | key->publicKey.x = publicKey->x; 66 | key->publicKey.y = publicKey->y; 67 | key->publicKey.z = NULL; 68 | sfree(publicKey); 69 | 70 | return 1; 71 | } 72 | -------------------------------------------------------------------------------- /windows/pageant.rc: -------------------------------------------------------------------------------- 1 | /* 2 | * Windows resources for Pageant. 3 | */ 4 | 5 | #include "rcstuff.h" 6 | 7 | #define APPNAME "Pageant" 8 | #define APPDESC "PuTTY SSH authentication agent" 9 | 10 | 200 ICON "pageant.ico" 11 | 201 ICON "pageants.ico" 12 | 13 | 210 DIALOG DISCARDABLE 0, 0, 140, 60 14 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 15 | CAPTION "Pageant: Enter Passphrase" 16 | FONT 8, "MS Shell Dlg" 17 | BEGIN 18 | CTEXT "Enter passphrase for key", 100, 10, 6, 120, 8 19 | CTEXT "", 101, 10, 16, 120, 8 20 | EDITTEXT 102, 10, 26, 120, 12, ES_PASSWORD | ES_AUTOHSCROLL 21 | DEFPUSHBUTTON "O&K", IDOK, 20, 42, 40, 14 22 | PUSHBUTTON "&Cancel", IDCANCEL, 80, 42, 40, 14 23 | END 24 | 25 | 211 DIALOG DISCARDABLE 0, 0, 330, 200 26 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 27 | CAPTION "Pageant Key List" 28 | FONT 8, "MS Shell Dlg" 29 | BEGIN 30 | LISTBOX 100, 10, 10, 310, 155, 31 | LBS_EXTENDEDSEL | LBS_HASSTRINGS | LBS_USETABSTOPS | WS_VSCROLL | WS_TABSTOP 32 | PUSHBUTTON "&Add Key", 101, 75, 162, 60, 14 33 | PUSHBUTTON "&Remove Key", 102, 195, 162, 60, 14 34 | PUSHBUTTON "&Help", 103, 10, 182, 50, 14 35 | DEFPUSHBUTTON "&Close", IDOK, 270, 182, 50, 14 36 | END 37 | 38 | /* Accelerators used: cl */ 39 | 213 DIALOG DISCARDABLE 140, 40, 270, 106 40 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 41 | CAPTION "About Pageant" 42 | FONT 8, "MS Shell Dlg" 43 | BEGIN 44 | DEFPUSHBUTTON "&Close", IDOK, 216, 88, 48, 14 45 | PUSHBUTTON "View &Licence", 101, 6, 88, 70, 14 46 | PUSHBUTTON "Visit &Web Site", 102, 140, 88, 70, 14 47 | EDITTEXT 1000, 10, 6, 250, 80, ES_READONLY | ES_MULTILINE | ES_CENTER, WS_EX_STATICEDGE 48 | END 49 | 50 | /* No accelerators used */ 51 | 214 DIALOG DISCARDABLE 50, 50, 326, 231 52 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 53 | CAPTION "PuTTY Licence" 54 | FONT 8, "MS Shell Dlg" 55 | BEGIN 56 | DEFPUSHBUTTON "OK", IDOK, 148, 211, 44, 14 57 | 58 | EDITTEXT 1000, 10, 10, 306, 192, ES_READONLY | ES_MULTILINE | ES_LEFT, WS_EX_STATICEDGE 59 | END 60 | 61 | #include "version.rc2" 62 | 63 | #ifndef NO_MANIFESTS 64 | 1 RT_MANIFEST "pageant.mft" 65 | #endif /* NO_MANIFESTS */ 66 | -------------------------------------------------------------------------------- /windows/win_res.rc2: -------------------------------------------------------------------------------- 1 | /* 2 | * Windows resources shared between PuTTY and PuTTYtel, to be #include'd 3 | * after defining appropriate macros. 4 | * Note that many of these strings mention PuTTY. Due to restrictions in 5 | * VC's handling of string concatenation, this can't easily be fixed. 6 | * It's fixed up at runtime. 7 | * FIXME: This file is called '.rc2' rather than '.rc' to avoid MSVC trying 8 | * to compile it on its own when using the project files. Nicer solutions 9 | * welcome. 10 | */ 11 | 12 | #include "win_res.h" 13 | 14 | IDI_MAINICON ICON "putty.ico" 15 | 16 | IDI_CFGICON ICON "puttycfg.ico" 17 | 18 | /* Accelerators used: clw */ 19 | IDD_ABOUTBOX DIALOG DISCARDABLE 140, 40, 270, 136 20 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 21 | CAPTION "About PuTTY" 22 | FONT 8, "MS Shell Dlg" 23 | BEGIN 24 | DEFPUSHBUTTON "&Close", IDOK, 216, 118, 48, 14 25 | PUSHBUTTON "View &Licence", IDA_LICENCE, 6, 118, 70, 14 26 | PUSHBUTTON "Visit &Web Site", IDA_WEB, 140, 118, 70, 14 27 | EDITTEXT IDA_TEXT, 10, 6, 250, 110, ES_READONLY | ES_MULTILINE | ES_CENTER, WS_EX_STATICEDGE 28 | END 29 | 30 | /* Accelerators used: aco */ 31 | IDD_MAINBOX DIALOG DISCARDABLE 0, 0, 300, 252 32 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 33 | CAPTION "PuTTY Configuration" 34 | FONT 8, "MS Shell Dlg" 35 | CLASS "PuTTYConfigBox" 36 | BEGIN 37 | END 38 | 39 | /* Accelerators used: co */ 40 | IDD_LOGBOX DIALOG DISCARDABLE 100, 20, 300, 119 41 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 42 | CAPTION "PuTTY Event Log" 43 | FONT 8, "MS Shell Dlg" 44 | BEGIN 45 | DEFPUSHBUTTON "&Close", IDOK, 135, 102, 44, 14 46 | PUSHBUTTON "C&opy", IDN_COPY, 81, 102, 44, 14 47 | LISTBOX IDN_LIST, 3, 3, 294, 95, LBS_HASSTRINGS | LBS_USETABSTOPS | WS_VSCROLL | LBS_EXTENDEDSEL 48 | END 49 | 50 | /* No accelerators used */ 51 | IDD_LICENCEBOX DIALOG DISCARDABLE 50, 50, 326, 231 52 | STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU 53 | CAPTION "PuTTY Licence" 54 | FONT 8, "MS Shell Dlg" 55 | BEGIN 56 | DEFPUSHBUTTON "OK", IDOK, 148, 211, 44, 14 57 | 58 | EDITTEXT IDA_TEXT, 10, 10, 306, 192, ES_READONLY | ES_MULTILINE | ES_LEFT, WS_EX_STATICEDGE 59 | END 60 | 61 | #include "version.rc2" 62 | -------------------------------------------------------------------------------- /rdb/mk_pcodes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/ksh 2 | 3 | TMP=/tmp/mk_x 4 | [ "$1" = "" ] && LOCAL=0.71-rdb 5 | 6 | [ -e ${TMP}1 -o -e ${TMP}2 -o -e ${TMP}3 -o -e ${TMP}4 -o -e ${TMP}5 -o -e x.ed ] && 7 | { echo Temp file exists ; exit 1; } 8 | 9 | : > x.ed 10 | j=0.45 11 | echo 0i > x.ed 12 | expand PuTTY-Codes-$j.txt >> x.ed 13 | echo . >> x.ed 14 | 15 | for i in 0.49 0.50 0.52 0.53 0.54 0.58 0.63 0.71 ${LOCAL} 16 | do 17 | GL="`git log -1 $i --format=$i\ --\ %ai 2>/dev/null`" 18 | if [ "$GL" != "" ] 19 | then echo "VERSION $GL" 20 | else echo "VERSION $i" 21 | fi 22 | 23 | x="$i" 24 | [ "$x" = "0.71-rdb" ] && x=RDB 25 | 26 | expand PuTTY-Codes-$j.txt | 27 | awk > ${TMP}1 -v i=$x \ 28 | '{ 29 | str=$0 30 | if (str != "") str=substr($0 " ",1,76) i 31 | print str; 32 | }' 33 | 34 | expand PuTTY-Codes-$i.txt | 35 | awk > ${TMP}2 -v i=$x \ 36 | '{ 37 | str=$0 38 | if (str != "") str=substr($0 " ",1,76) i 39 | print str; 40 | }' 41 | 42 | diff -e ${TMP}1 ${TMP}2 >> x.ed 43 | 44 | diff -e PuTTY-Codes-$i.txt PuTTY-Codes-$j.txt | grep '^..........' > ${TMP}5 45 | if [ -s ${TMP}5 ] 46 | then 47 | { 48 | echo 49 | echo BEFORE VERSION $i 50 | cat ${TMP}5 51 | [ -f ${TMP}3 ] && cat ${TMP}3 52 | } > ${TMP}4 53 | mv ${TMP}4 ${TMP}3 54 | fi 55 | 56 | j=$i 57 | done 58 | 59 | echo 1i >> x.ed 60 | cat >> x.ed <<\! 61 | ANSI and VTxxx codes understood by PuTTY 62 | 63 | The basic emulation for PuTTY is that of an eight bit VT102 with 64 | cherry picked features from other ANSI terminals. As such it only 65 | understands seven bit ECMA-35 but adds onto that numerous 8 bit 66 | "codepages" and UTF-8. 67 | 68 | PuTTY Releases 69 | 70 | ! 71 | for i in 0.45 0.49 0.50 0.52 0.53 0.54 0.58 0.63 0.71 ; do echo ' '$i `git log -1 $i --format=%ai | sed 's/..:.*//'` ; done >> x.ed 72 | echo >> x.ed 73 | echo . >> x.ed 74 | 75 | echo wq PuTTY-Codes.txt >> x.ed 76 | ed < x.ed 77 | 78 | { 79 | echo 80 | echo Items changed from previous versions 81 | echo ------------------------------------ 82 | cat ${TMP}3 83 | } >> PuTTY-Codes.txt 84 | 85 | rm ${TMP}1 ${TMP}2 ${TMP}3 ${TMP}5 x.ed 86 | -------------------------------------------------------------------------------- /unix/gtkcols.h: -------------------------------------------------------------------------------- 1 | /* 2 | * gtkcols.h - header file for a columns-based widget container 3 | * capable of supporting the PuTTY portable dialog box layout 4 | * mechanism. 5 | */ 6 | 7 | #ifndef COLUMNS_H 8 | #define COLUMNS_H 9 | 10 | #include 11 | #include 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif /* __cplusplus */ 16 | 17 | #define TYPE_COLUMNS (columns_get_type()) 18 | #define COLUMNS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TYPE_COLUMNS, Columns)) 19 | #define COLUMNS_CLASS(klass) \ 20 | (G_TYPE_CHECK_CLASS_CAST((klass), TYPE_COLUMNS, ColumnsClass)) 21 | #define IS_COLUMNS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TYPE_COLUMNS)) 22 | #define IS_COLUMNS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TYPE_COLUMNS)) 23 | 24 | typedef struct Columns_tag Columns; 25 | typedef struct ColumnsClass_tag ColumnsClass; 26 | typedef struct ColumnsChild_tag ColumnsChild; 27 | 28 | struct Columns_tag { 29 | GtkContainer container; 30 | /* private after here */ 31 | GList *children; /* this holds ColumnsChild structures */ 32 | GList *taborder; /* this just holds GtkWidgets */ 33 | gint spacing; 34 | }; 35 | 36 | struct ColumnsClass_tag { 37 | GtkContainerClass parent_class; 38 | }; 39 | 40 | struct ColumnsChild_tag { 41 | /* If `widget' is non-NULL, this entry represents an actual widget. */ 42 | GtkWidget *widget; 43 | gint colstart, colspan; 44 | gboolean force_left; /* for recalcitrant GtkLabels */ 45 | ColumnsChild *same_height_as; 46 | /* Otherwise, this entry represents a change in the column setup. */ 47 | gint ncols; 48 | gint *percentages; 49 | gint x, y, w, h; /* used during an individual size computation */ 50 | }; 51 | 52 | GType columns_get_type(void); 53 | GtkWidget *columns_new(gint spacing); 54 | void columns_set_cols(Columns *cols, gint ncols, const gint *percentages); 55 | void columns_add(Columns *cols, GtkWidget *child, 56 | gint colstart, gint colspan); 57 | void columns_taborder_last(Columns *cols, GtkWidget *child); 58 | void columns_force_left_align(Columns *cols, GtkWidget *child); 59 | void columns_force_same_height(Columns *cols, GtkWidget *ch1, GtkWidget *ch2); 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif /* __cplusplus */ 64 | 65 | #endif /* COLUMNS_H */ 66 | -------------------------------------------------------------------------------- /unix/uxputty.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Unix PuTTY main program. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define MAY_REFER_TO_GTK_IN_HEADERS 14 | 15 | #include "putty.h" 16 | #include "storage.h" 17 | 18 | #include "gtkcompat.h" 19 | 20 | /* 21 | * Stubs to avoid uxpty.c needing to be linked in. 22 | */ 23 | const int use_pty_argv = FALSE; 24 | char **pty_argv; /* never used */ 25 | char *pty_osx_envrestore_prefix; 26 | 27 | /* 28 | * Clean up and exit. 29 | */ 30 | void cleanup_exit(int code) 31 | { 32 | /* 33 | * Clean up. 34 | */ 35 | sk_cleanup(); 36 | random_save_seed(); 37 | exit(code); 38 | } 39 | 40 | Backend *select_backend(Conf *conf) 41 | { 42 | Backend *back = backend_from_proto(conf_get_int(conf, CONF_protocol)); 43 | assert(back != NULL); 44 | return back; 45 | } 46 | 47 | void initial_config_box(Conf *conf, post_dialog_fn_t after, void *afterctx) 48 | { 49 | char *title = dupcat(appname, " Configuration", NULL); 50 | create_config_box(title, conf, FALSE, 0, after, afterctx); 51 | sfree(title); 52 | } 53 | 54 | const int use_event_log = 1, new_session = 1, saved_sessions = 1; 55 | const int dup_check_launchable = 1; 56 | 57 | char *make_default_wintitle(char *hostname) 58 | { 59 | return dupcat(hostname, " - ", appname, NULL); 60 | } 61 | 62 | /* 63 | * X11-forwarding-related things suitable for Gtk app. 64 | */ 65 | 66 | char *platform_get_x_display(void) { 67 | const char *display; 68 | /* Try to take account of --display and what have you. */ 69 | if (!(display = gdk_get_display())) 70 | /* fall back to traditional method */ 71 | display = getenv("DISPLAY"); 72 | return dupstr(display); 73 | } 74 | 75 | const int share_can_be_downstream = TRUE; 76 | const int share_can_be_upstream = TRUE; 77 | 78 | void setup(int single) 79 | { 80 | sk_init(); 81 | flags = FLAG_VERBOSE | FLAG_INTERACTIVE; 82 | cmdline_tooltype |= TOOLTYPE_HOST_ARG | TOOLTYPE_PORT_ARG; 83 | default_protocol = be_default_protocol; 84 | /* Find the appropriate default port. */ 85 | { 86 | Backend *b = backend_from_proto(default_protocol); 87 | default_port = 0; /* illegal */ 88 | if (b) 89 | default_port = b->default_port; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /charset/toucs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * toucs.c - convert charsets to Unicode. 3 | */ 4 | 5 | #include "charset.h" 6 | #include "internal.h" 7 | 8 | struct unicode_emit_param { 9 | wchar_t *output; 10 | int outlen; 11 | const wchar_t *errstr; 12 | int errlen; 13 | int stopped; 14 | }; 15 | 16 | static void unicode_emit(void *ctx, long int output) 17 | { 18 | struct unicode_emit_param *param = (struct unicode_emit_param *)ctx; 19 | wchar_t outval; 20 | wchar_t const *p; 21 | int outlen; 22 | 23 | if (output == ERROR) { 24 | if (param->errstr) { 25 | p = param->errstr; 26 | outlen = param->errlen; 27 | } else { 28 | outval = 0xFFFD; /* U+FFFD REPLACEMENT CHARACTER */ 29 | p = &outval; 30 | outlen = 1; 31 | } 32 | } else { 33 | outval = output; 34 | p = &outval; 35 | outlen = 1; 36 | } 37 | 38 | if (param->outlen >= outlen) { 39 | while (outlen > 0) { 40 | *param->output++ = *p++; 41 | param->outlen--; 42 | outlen--; 43 | } 44 | } else { 45 | param->stopped = 1; 46 | } 47 | } 48 | 49 | int charset_to_unicode(const char **input, int *inlen, 50 | wchar_t *output, int outlen, 51 | int charset, charset_state *state, 52 | const wchar_t *errstr, int errlen) 53 | { 54 | charset_spec const *spec = charset_find_spec(charset); 55 | charset_state localstate; 56 | struct unicode_emit_param param; 57 | 58 | param.output = output; 59 | param.outlen = outlen; 60 | param.errstr = errstr; 61 | param.errlen = errlen; 62 | param.stopped = 0; 63 | 64 | if (!state) { 65 | localstate.s0 = 0; 66 | } else { 67 | localstate = *state; /* structure copy */ 68 | } 69 | 70 | while (*inlen > 0) { 71 | int lenbefore = param.output - output; 72 | spec->read(spec, (unsigned char)**input, &localstate, 73 | unicode_emit, ¶m); 74 | if (param.stopped) { 75 | /* 76 | * The emit function has _tried_ to output some 77 | * characters, but ran up against the end of the 78 | * buffer. Leave immediately, and return what happened 79 | * _before_ attempting to process this character. 80 | */ 81 | return lenbefore; 82 | } 83 | if (state) 84 | *state = localstate; /* structure copy */ 85 | (*input)++; 86 | (*inlen)--; 87 | } 88 | 89 | return param.output - output; 90 | } 91 | -------------------------------------------------------------------------------- /windows/winsecur.h: -------------------------------------------------------------------------------- 1 | /* 2 | * winsecur.h: some miscellaneous security-related helper functions, 3 | * defined in winsecur.c, that use the advapi32 library. Also 4 | * centralises the machinery for dynamically loading that library. 5 | */ 6 | 7 | #if !defined NO_SECURITY 8 | 9 | #include 10 | 11 | #ifndef WINSECUR_GLOBAL 12 | #define WINSECUR_GLOBAL extern 13 | #endif 14 | 15 | /* 16 | * Functions loaded from advapi32.dll. 17 | */ 18 | DECL_WINDOWS_FUNCTION(WINSECUR_GLOBAL, BOOL, OpenProcessToken, 19 | (HANDLE, DWORD, PHANDLE)); 20 | DECL_WINDOWS_FUNCTION(WINSECUR_GLOBAL, BOOL, GetTokenInformation, 21 | (HANDLE, TOKEN_INFORMATION_CLASS, 22 | LPVOID, DWORD, PDWORD)); 23 | DECL_WINDOWS_FUNCTION(WINSECUR_GLOBAL, BOOL, InitializeSecurityDescriptor, 24 | (PSECURITY_DESCRIPTOR, DWORD)); 25 | DECL_WINDOWS_FUNCTION(WINSECUR_GLOBAL, BOOL, SetSecurityDescriptorOwner, 26 | (PSECURITY_DESCRIPTOR, PSID, BOOL)); 27 | DECL_WINDOWS_FUNCTION(WINSECUR_GLOBAL, DWORD, GetSecurityInfo, 28 | (HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION, 29 | PSID *, PSID *, PACL *, PACL *, 30 | PSECURITY_DESCRIPTOR *)); 31 | DECL_WINDOWS_FUNCTION(WINSECUR_GLOBAL, DWORD, SetSecurityInfo, 32 | (HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION, 33 | PSID, PSID, PACL, PACL)); 34 | DECL_WINDOWS_FUNCTION(WINSECUR_GLOBAL, DWORD, SetEntriesInAclA, 35 | (ULONG, PEXPLICIT_ACCESS, PACL, PACL *)); 36 | int got_advapi(void); 37 | 38 | /* 39 | * Find the SID describing the current user. The return value (if not 40 | * NULL for some error-related reason) is smalloced. 41 | */ 42 | PSID get_user_sid(void); 43 | 44 | /* 45 | * Construct a PSECURITY_DESCRIPTOR of the type used for named pipe 46 | * servers, i.e. allowing access only to the current user id and also 47 | * only local (i.e. not over SMB) connections. 48 | * 49 | * If this function returns TRUE, then 'psd' and 'acl' will have been 50 | * filled in with memory allocated using LocalAlloc (and hence must be 51 | * freed later using LocalFree). If it returns FALSE, then instead 52 | * 'error' has been filled with a dynamically allocated error message. 53 | */ 54 | int make_private_security_descriptor(DWORD permissions, 55 | PSECURITY_DESCRIPTOR *psd, 56 | PACL *acl, 57 | char **error); 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /charset/fromucs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * fromucs.c - convert Unicode to other character sets. 3 | */ 4 | 5 | #include "charset.h" 6 | #include "internal.h" 7 | 8 | struct charset_emit_param { 9 | char *output; 10 | int outlen; 11 | const char *errstr; 12 | int errlen; 13 | int stopped; 14 | }; 15 | 16 | static void charset_emit(void *ctx, long int output) 17 | { 18 | struct charset_emit_param *param = (struct charset_emit_param *)ctx; 19 | char outval; 20 | char const *p; 21 | int outlen; 22 | 23 | if (output == ERROR) { 24 | p = param->errstr; 25 | outlen = param->errlen; 26 | } else { 27 | outval = output; 28 | p = &outval; 29 | outlen = 1; 30 | } 31 | 32 | if (param->outlen >= outlen) { 33 | while (outlen > 0) { 34 | *param->output++ = *p++; 35 | param->outlen--; 36 | outlen--; 37 | } 38 | } else { 39 | param->stopped = 1; 40 | } 41 | } 42 | 43 | int charset_from_unicode(const wchar_t **input, int *inlen, 44 | char *output, int outlen, 45 | int charset, charset_state *state, 46 | const char *errstr, int errlen) 47 | { 48 | charset_spec const *spec = charset_find_spec(charset); 49 | charset_state localstate; 50 | struct charset_emit_param param; 51 | 52 | param.output = output; 53 | param.outlen = outlen; 54 | param.stopped = 0; 55 | 56 | /* 57 | * charset_emit will expect a valid errstr. 58 | */ 59 | if (!errstr) { 60 | /* *shrug* this is good enough, and consistent across all SBCS... */ 61 | param.errstr = "."; 62 | param.errlen = 1; 63 | } 64 | param.errstr = errstr; 65 | param.errlen = errlen; 66 | 67 | if (!state) { 68 | localstate.s0 = 0; 69 | } else { 70 | localstate = *state; /* structure copy */ 71 | } 72 | state = &localstate; 73 | 74 | while (*inlen > 0) { 75 | int lenbefore = param.output - output; 76 | spec->write(spec, **input, &localstate, charset_emit, ¶m); 77 | if (param.stopped) { 78 | /* 79 | * The emit function has _tried_ to output some 80 | * characters, but ran up against the end of the 81 | * buffer. Leave immediately, and return what happened 82 | * _before_ attempting to process this character. 83 | */ 84 | return lenbefore; 85 | } 86 | if (state) 87 | *state = localstate; /* structure copy */ 88 | (*input)++; 89 | (*inlen)--; 90 | } 91 | return param.output - output; 92 | } 93 | -------------------------------------------------------------------------------- /rdb/dbcs_chars.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh - 2 | 3 | # CP10001:Lead Bytes: 0x81 0x9f 0xe0 0xfc 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 4 | # CP10002:Lead Bytes: 0x81 0xfc 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 5 | # CP10003:Lead Bytes: 0xa1 0xac 0xb0 0xc8 0xca 0xfd 0x00 0x00 0x00 0x00 0x00 0x00 6 | # CP10008:Lead Bytes: 0xa1 0xa9 0xb0 0xf7 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 7 | # CP1361 :Lead Bytes: 0x84 0xd3 0xd8 0xde 0xe0 0xf9 0x00 0x00 0x00 0x00 0x00 0x00 8 | # CP20000:Lead Bytes: 0xa1 0xfe 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 9 | # CP20001:Lead Bytes: 0x81 0x84 0x91 0xd8 0xdf 0xfc 0x00 0x00 0x00 0x00 0x00 0x00 10 | # CP20002:Lead Bytes: 0x81 0xaf 0xdd 0xfe 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 11 | # CP20003:Lead Bytes: 0x81 0x84 0x87 0x87 0x89 0xe8 0xf9 0xfb 0x00 0x00 0x00 0x00 12 | # CP20004:Lead Bytes: 0xa1 0xfe 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 13 | # CP20005:Lead Bytes: 0x8d 0xf5 0xf9 0xfc 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 14 | # CP20261:Lead Bytes: 0xc1 0xcf 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 15 | # CP20932:Lead Bytes: 0x8e 0x8e 0xa1 0xfe 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 16 | # CP20936:Lead Bytes: 0xa1 0xa9 0xb0 0xf7 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 17 | # CP51949:Lead Bytes: 0xa1 0xac 0xb0 0xc8 0xca 0xfd 0x00 0x00 0x00 0x00 0x00 0x00 18 | # CP932 :Lead Bytes: 0x81 0x9f 0xe0 0xfc 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 19 | # CP936 :Lead Bytes: 0x81 0xfe 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 20 | # CP949 :Lead Bytes: 0x81 0xfe 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 21 | # CP950 :Lead Bytes: 0x81 0xfe 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 22 | 23 | 24 | mawk ' 25 | BEGIN{ 26 | widespace = 1; 27 | 28 | { 29 | page = 0; 30 | if (widespace) printf("\033%%@") 31 | printf("Characters starting at 0x%04x", 32); 32 | for(i=32; i<256; i++) { 33 | if (i%16 == 0) printf("\n%04x: ", page*256 + i); 34 | if (i == 127) 35 | ; 36 | else 37 | printf(" %c ", i); 38 | } 39 | printf("\n"); 40 | } 41 | 42 | 43 | for (page=129; page < 255; page++) { 44 | printf("Characters starting at 0x%04x", page*256 + 64); 45 | for(i=64; i<256; i++) { 46 | if (i%16 == 0) printf("\n%04x: ", page*256 + i); 47 | if (i == 127) 48 | ; 49 | else 50 | printf("%c%c", page, i); 51 | if (widespace) printf("\033%%G\xe3\x80\x80\033%%@") 52 | else printf(" "); 53 | } 54 | printf("\n"); 55 | } 56 | } 57 | ' 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PuTTY Patched 2 | ============= 3 | 4 | This is a mirror of Simon's git repository with my PuTTY 5 | patches in the putty-rdb branch. 6 | 7 | The [master branch](https://github.com/rdebath/PuTTY/tree/master) of this 8 | repository is a clone of the master from Simon's PuTTY repo at 9 | [git://git.tartarus.org/simon/putty.git](http://tartarus.org/~simon-git/gitweb/?p=putty.git) 10 | and I am pushing Binaries to [here](https://github.com/rdebath/PuTTY/tree/binary). 11 | 12 | *NOTE* ... 13 | I'm pushing to this repository using rebase to keep each patch as a single commit. 14 | 15 | Bugfixes 16 | ======== 17 | * Fix WM_NETEVENT delayed processing. 18 | * Repair handling of WM_NETEVENT (part 2) 19 | * Repair GTK timer handling 20 | * Minimise, maximise, etc are as annoying as other terminal resize operations. 21 | * Adjust DEC-MCS character set. 22 | * This is a fix for the direct to font DBCS cursor. 23 | * Windows codepages do not have C1 controls 24 | * Fix the scoasc translation on unix 25 | * Function x11font_draw_text uses the UCS2 character set 26 | * SCO Ansi Keyboard correction 27 | * Make sure all ISO-2022 codes are checked. 28 | * Timer starvation fix 29 | * Fix support of Windows 256 colour palettes. 30 | 31 | Performance Improvements 32 | ======================== 33 | * Pango font performance update 34 | * Optimisation to delete windows code on unix 35 | * Windows font drawing change. 36 | * Don't let dopaint eat too much CPU 37 | * Remove unneeded special case code for proportional fonts. 38 | 39 | Small Features 40 | ============== 41 | * Add XTerm extensions for VTTEST and reverse BS 42 | * Add new interpretation for XTerm SGR 38/48 43 | * Add XTerm/Konsole truecolour mode. 44 | * Line character set for Window title on windows. 45 | * Add wcwidth override sequence 46 | * Add Ansi REP sequence and SCO CSI = g 47 | * Add DIM, CONCEAL, BGBOLD and Blink control. 48 | * Add Linux default attribute set. 49 | * Adding better support for Windows MBCS (codepages) 50 | * Add Linux default attribute set. Comments 51 | * Reconfigure PuTTY colour scheme from Unix host. 52 | 53 | Large Features 54 | ============== 55 | * UTF-8 processing update 56 | 57 | Code Cleanups 58 | ============= 59 | * Changes to the internal usage of unicode areas for character set conversion. 60 | * Clean up VT52 leftovers from the 256 colours patch 61 | * Waaay overkill on uuid generation 62 | * Changes for compiling under MinGW 63 | 64 | Obviously, some of these will depend on earlier changes *plus* I am only 65 | testing the full set so partial sets may have significant bugs. 66 | -------------------------------------------------------------------------------- /unix/x11misc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * x11misc.c: miscellaneous stuff for dealing directly with X servers. 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "putty.h" 12 | 13 | #ifndef NOT_X_WINDOWS 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include "x11misc.h" 20 | 21 | /* ---------------------------------------------------------------------- 22 | * Error handling mechanism which permits us to ignore specific X11 23 | * errors from particular requests. We maintain a list of upcoming 24 | * potential error events that we want to not treat as fatal errors. 25 | */ 26 | 27 | static int (*orig_x11_error_handler)(Display *thisdisp, XErrorEvent *err); 28 | 29 | struct x11_err_to_ignore { 30 | Display *display; 31 | unsigned char error_code; 32 | unsigned long serial; 33 | }; 34 | 35 | struct x11_err_to_ignore *errs; 36 | 37 | int nerrs, errsize; 38 | 39 | static int x11_error_handler(Display *thisdisp, XErrorEvent *err) 40 | { 41 | int i; 42 | for (i = 0; i < nerrs; i++) { 43 | if (thisdisp == errs[i].display && 44 | err->serial == errs[i].serial && 45 | err->error_code == errs[i].error_code) { 46 | /* Ok, this is an error we're happy to ignore */ 47 | return 0; 48 | } 49 | } 50 | 51 | return (*orig_x11_error_handler)(thisdisp, err); 52 | } 53 | 54 | void x11_ignore_error(Display *disp, unsigned char errcode) 55 | { 56 | /* 57 | * Install our error handler, if we haven't already. 58 | */ 59 | if (!orig_x11_error_handler) 60 | orig_x11_error_handler = XSetErrorHandler(x11_error_handler); 61 | 62 | /* 63 | * This is as good a moment as any to winnow the ignore list based 64 | * on requests we know to have been processed. 65 | */ 66 | { 67 | unsigned long last = LastKnownRequestProcessed(disp); 68 | int i, j; 69 | for (i = j = 0; i < nerrs; i++) { 70 | if (errs[i].display == disp && errs[i].serial <= last) 71 | continue; 72 | errs[j++] = errs[i]; 73 | } 74 | nerrs = j; 75 | } 76 | 77 | if (nerrs >= errsize) { 78 | errsize = nerrs * 5 / 4 + 16; 79 | errs = sresize(errs, errsize, struct x11_err_to_ignore); 80 | } 81 | errs[nerrs].display = disp; 82 | errs[nerrs].error_code = errcode; 83 | errs[nerrs].serial = NextRequest(disp); 84 | nerrs++; 85 | } 86 | 87 | #endif 88 | 89 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | all: man index.html 2 | 3 | # Decide on the versionid policy. 4 | # 5 | # If the user has passed in $(VERSION) on the command line (`make 6 | # VERSION="Release 0.56"'), we use that as an explicit version string. 7 | # Otherwise, we use `svnversion' to examine the checked-out 8 | # documentation source, and if that returns a single revision number 9 | # then we invent a version string reflecting just that number. Failing 10 | # _that_, we resort to versionids.but which gives 'version 11 | # unavailable'. 12 | # 13 | # So here, we define VERSION using svnversion if it isn't already 14 | # defined ... 15 | ifndef VERSION 16 | SVNVERSION=$(shell test -d .svn && svnversion .) 17 | BADCHARS=$(findstring :,$(SVNVERSION))$(findstring S,$(SVNVERSION)) 18 | ifeq ($(BADCHARS),) 19 | ifneq ($(SVNVERSION),) 20 | ifneq ($(SVNVERSION),exported) 21 | VERSION=Built from revision $(patsubst M,,$(SVNVERSION)) 22 | endif 23 | endif 24 | endif 25 | endif 26 | # ... and now, we condition our build behaviour on whether or not 27 | # VERSION _is_ defined. 28 | ifdef VERSION 29 | VERSIONIDS=vstr 30 | vstr.but: FORCE 31 | printf '\\versionid $(VERSION)\n' > vstr.but 32 | FORCE:; 33 | else 34 | VERSIONIDS=vids 35 | endif 36 | 37 | CHAPTERS := $(SITE) copy blurb intro gs using config pscp psftp plink 38 | CHAPTERS += pubkey pageant errors faq feedback licence udp pgpkeys sshnames 39 | CHAPTERS += index $(VERSIONIDS) 40 | 41 | INPUTS = $(patsubst %,%.but,$(CHAPTERS)) 42 | 43 | # This is temporary. Hack it locally or something. 44 | HALIBUT = halibut 45 | 46 | index.html: $(INPUTS) 47 | $(HALIBUT) --text --html --winhelp --chm $(INPUTS) 48 | 49 | # During formal builds it's useful to be able to build these ones alone. 50 | putty.hlp: $(INPUTS) 51 | $(HALIBUT) --winhelp $(INPUTS) 52 | putty.chm: $(INPUTS) 53 | $(HALIBUT) --chm $(INPUTS) 54 | 55 | putty.info: $(INPUTS) 56 | $(HALIBUT) --info $(INPUTS) 57 | 58 | MKMAN = $(HALIBUT) --man=$@ mancfg.but $< 59 | MANPAGES = putty.1 puttygen.1 plink.1 pscp.1 psftp.1 puttytel.1 pterm.1 \ 60 | pageant.1 61 | man: $(MANPAGES) 62 | 63 | putty.1: man-putt.but mancfg.but; $(MKMAN) 64 | puttygen.1: man-pg.but mancfg.but; $(MKMAN) 65 | plink.1: man-pl.but mancfg.but; $(MKMAN) 66 | pscp.1: man-pscp.but mancfg.but; $(MKMAN) 67 | psftp.1: man-psft.but mancfg.but; $(MKMAN) 68 | puttytel.1: man-ptel.but mancfg.but; $(MKMAN) 69 | pterm.1: man-pter.but mancfg.but; $(MKMAN) 70 | pageant.1: man-pag.but mancfg.but; $(MKMAN) 71 | 72 | mostlyclean: 73 | rm -f *.html *.txt *.hlp *.cnt *.1 *.info vstr.but *.hh[pck] 74 | clean: mostlyclean 75 | rm -f *.chm 76 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.pyc 3 | .dirstamp 4 | .deps 5 | .DS_Store 6 | /*.pdb 7 | /*.ilk 8 | /*.res 9 | /*.RES 10 | /*.pch 11 | /*.rsp 12 | /*.obj 13 | /*.exe 14 | /*.ncb 15 | /*.plg 16 | /*.dsw 17 | /*.opt 18 | /*.dsp 19 | /*.tds 20 | /*.td2 21 | /*.map 22 | /Makefile.mgw 23 | /Makefile.vc 24 | /Makefile.lcc 25 | /MSVC 26 | /*.log 27 | /*.GID 28 | /local 29 | /Output 30 | /pageant 31 | /plink 32 | /pscp 33 | /psftp 34 | /putty 35 | /puttytel 36 | /puttygen 37 | /pterm 38 | /puttyapp 39 | /ptermapp 40 | /osxlaunch 41 | /unix/PuTTY.app 42 | /unix/Pterm.app 43 | /fuzzterm 44 | /testbn 45 | /cgtest 46 | /*.DSA 47 | /*.RSA 48 | /*.cnt 49 | /*.hlp 50 | /.bmake 51 | /build.log 52 | /build.out 53 | /uxconfig.h 54 | /empty.h 55 | /config.status 56 | /Makefile.am 57 | /Makefile.in 58 | /Makefile 59 | /compile 60 | /config.status 61 | /configure 62 | /stamp-h1 63 | /aclocal.m4 64 | /ar-lib 65 | /autom4te.cache 66 | /depcomp 67 | /install-sh 68 | /local 69 | /missing 70 | /uxconfig.in 71 | /uxconfig.h 72 | /licence.h 73 | /*.a 74 | /charset/sbcsdat.c 75 | /contrib/cygtermd/cygtermd.exe 76 | /doc/*.html 77 | /doc/*.txt 78 | /doc/*.cnt 79 | /doc/*.hlp 80 | /doc/*.gid 81 | /doc/*.GID 82 | /doc/*.chm 83 | /doc/*.log 84 | /doc/*.1 85 | /doc/*.info 86 | /doc/vstr.but 87 | /doc/*.hhp 88 | /doc/*.hhc 89 | /doc/*.hhk 90 | /doc/licence.but 91 | /doc/copy.but 92 | /icons/*.pam 93 | /icons/*.png 94 | /icons/*.ico 95 | /icons/*.icns 96 | /icons/*.xpm 97 | /icons/*.c 98 | /testdata/bignum.txt 99 | /unix/Makefile.gtk 100 | /unix/Makefile.ux 101 | /unix/Makefile.local 102 | /unix/empty.h 103 | /unix/plink 104 | /unix/pterm 105 | /unix/putty 106 | /unix/puttytel 107 | /unix/psftp 108 | /unix/pscp 109 | /unix/puttygen 110 | /unix/stamp-h1 111 | /unix/*.log 112 | /unix/.deps 113 | /windows/*.pdb 114 | /windows/*.ilk 115 | /windows/*.res 116 | /windows/*.RES 117 | /windows/*.pch 118 | /windows/*.rsp 119 | /windows/*.obj 120 | /windows/*.exe 121 | /windows/*.ncb 122 | /windows/*.plg 123 | /windows/*.dsw 124 | /windows/*.opt 125 | /windows/*.dsp 126 | /windows/*.tds 127 | /windows/*.td2 128 | /windows/*.map 129 | /windows/Makefile.clangcl 130 | /windows/Makefile.mgw 131 | /windows/Makefile.vc 132 | /windows/Makefile.lcc 133 | /windows/MSVC 134 | /windows/DEVCPP 135 | /windows/VS2010 136 | /windows/VS2012 137 | /windows/*.log 138 | /windows/*.GID 139 | /windows/local 140 | /windows/Output 141 | /windows/*.DSA 142 | /windows/*.RSA 143 | /windows/*.cnt 144 | /windows/*.hlp 145 | /windows/.bmake 146 | /windows/*.sln 147 | /windows/*.suo 148 | /windows/*.msi 149 | /windows/*.wixobj 150 | /windows/*.wixpdb 151 | -------------------------------------------------------------------------------- /unix/uxcfg.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uxcfg.c - the Unix-specific parts of the PuTTY configuration 3 | * box. 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | #include "putty.h" 10 | #include "dialog.h" 11 | #include "storage.h" 12 | 13 | void unix_setup_config_box(struct controlbox *b, int midsession, int protocol) 14 | { 15 | struct controlset *s; 16 | union control *c; 17 | 18 | /* 19 | * The Conf structure contains two Unix-specific elements which 20 | * are not configured in here: stamp_utmp and login_shell. This 21 | * is because pterm does not put up a configuration box right at 22 | * the start, which is the only time when these elements would 23 | * be useful to configure. 24 | */ 25 | 26 | /* 27 | * On Unix, we don't have a drop-down list for the printer 28 | * control. 29 | */ 30 | s = ctrl_getset(b, "Terminal", "printing", "Remote-controlled printing"); 31 | assert(s->ncontrols == 1 && s->ctrls[0]->generic.type == CTRL_EDITBOX); 32 | s->ctrls[0]->editbox.has_list = 0; 33 | 34 | /* 35 | * Unix supports a local-command proxy. This also means we must 36 | * adjust the text on the `Telnet command' control. 37 | */ 38 | if (!midsession) { 39 | int i; 40 | s = ctrl_getset(b, "Connection/Proxy", "basics", NULL); 41 | for (i = 0; i < s->ncontrols; i++) { 42 | c = s->ctrls[i]; 43 | if (c->generic.type == CTRL_RADIO && 44 | c->generic.context.i == CONF_proxy_type) { 45 | assert(c->generic.handler == conf_radiobutton_handler); 46 | c->radio.nbuttons++; 47 | c->radio.buttons = 48 | sresize(c->radio.buttons, c->radio.nbuttons, char *); 49 | c->radio.buttons[c->radio.nbuttons-1] = 50 | dupstr("Local"); 51 | c->radio.buttondata = 52 | sresize(c->radio.buttondata, c->radio.nbuttons, intorptr); 53 | c->radio.buttondata[c->radio.nbuttons-1] = I(PROXY_CMD); 54 | break; 55 | } 56 | } 57 | 58 | for (i = 0; i < s->ncontrols; i++) { 59 | c = s->ctrls[i]; 60 | if (c->generic.type == CTRL_EDITBOX && 61 | c->generic.context.i == CONF_proxy_telnet_command) { 62 | assert(c->generic.handler == conf_editbox_handler); 63 | sfree(c->generic.label); 64 | c->generic.label = dupstr("Telnet command, or local" 65 | " proxy command"); 66 | break; 67 | } 68 | } 69 | } 70 | 71 | /* 72 | * Serial back end is available on Unix. However, we have to 73 | * mask out a couple of the configuration options: mark and 74 | * space parity are not conveniently supported, and neither is 75 | * DSR/DTR flow control. 76 | */ 77 | if (!midsession || (protocol == PROT_SERIAL)) 78 | ser_setup_config_box(b, midsession, 0x07, 0x07); 79 | } 80 | -------------------------------------------------------------------------------- /doc/sshnames.but: -------------------------------------------------------------------------------- 1 | \A{sshnames} SSH-2 names specified for PuTTY 2 | 3 | There are various parts of the SSH-2 protocol where things are specified 4 | using a textual name. Names ending in \cw{@putty.projects.tartarus.org} 5 | are reserved for allocation by the PuTTY team. Allocated names are 6 | documented here. 7 | 8 | \H{sshnames-channel} Connection protocol channel request names 9 | 10 | These names can be sent in a \cw{SSH_MSG_CHANNEL_REQUEST} message. 11 | 12 | \dt \cw{simple@putty.projects.tartarus.org} 13 | 14 | \dd This is sent by a client to announce that it will not have more than 15 | one channel open at a time in the current connection (that one being 16 | the one the request is sent on). The intention is that the server, 17 | knowing this, can set the window on that one channel to something very 18 | large, and leave flow control to TCP. There is no message-specific data. 19 | 20 | \dt \cw{winadj@putty.projects.tartarus.org} 21 | 22 | \dd PuTTY sends this request along with some 23 | \cw{SSH_MSG_CHANNEL_WINDOW_ADJUST} messages as part of its window-size 24 | tuning. It can be sent on any type of channel. There is no 25 | message-specific data. Servers MUST treat it as an unrecognised request 26 | and respond with \cw{SSH_MSG_CHANNEL_FAILURE}. 27 | 28 | \lcont{ 29 | (Some SSH servers get confused by this message, so there is a 30 | bug-compatibility mode for disabling it. See \k{config-ssh-bug-winadj}.) 31 | } 32 | 33 | \H{sshnames-kex} Key exchange method names 34 | 35 | \dt \cw{rsa-sha1-draft-00@putty.projects.tartarus.org} 36 | 37 | \dt \cw{rsa-sha256-draft-00@putty.projects.tartarus.org} 38 | 39 | \dt \cw{rsa1024-sha1-draft-01@putty.projects.tartarus.org} 40 | 41 | \dt \cw{rsa1024-sha256-draft-01@putty.projects.tartarus.org} 42 | 43 | \dt \cw{rsa2048-sha256-draft-01@putty.projects.tartarus.org} 44 | 45 | \dt \cw{rsa1024-sha1-draft-02@putty.projects.tartarus.org} 46 | 47 | \dt \cw{rsa2048-sha512-draft-02@putty.projects.tartarus.org} 48 | 49 | \dt \cw{rsa1024-sha1-draft-03@putty.projects.tartarus.org} 50 | 51 | \dt \cw{rsa2048-sha256-draft-03@putty.projects.tartarus.org} 52 | 53 | \dt \cw{rsa1024-sha1-draft-04@putty.projects.tartarus.org} 54 | 55 | \dt \cw{rsa2048-sha256-draft-04@putty.projects.tartarus.org} 56 | 57 | \dd These appeared in various drafts of what eventually became RFC\_4432. 58 | They have been superseded by \cw{rsa1024-sha1} and \cw{rsa2048-sha256}. 59 | 60 | \H{sshnames-encrypt} Encryption algorithm names 61 | 62 | \dt \cw{arcfour128-draft-00@putty.projects.tartarus.org} 63 | 64 | \dt \cw{arcfour256-draft-00@putty.projects.tartarus.org} 65 | 66 | \dd These were used in drafts of what eventually became RFC\_4345. 67 | They have been superseded by \cw{arcfour128} and \cw{arcfour256}. 68 | -------------------------------------------------------------------------------- /defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * defs.h: initial definitions for PuTTY. 3 | * 4 | * The rule about this header file is that it can't depend on any 5 | * other header file in this code base. This is where we define 6 | * things, as much as we can, that other headers will want to refer 7 | * to, such as opaque structure types and their associated typedefs, 8 | * or macros that are used by other headers. 9 | */ 10 | 11 | #ifndef PUTTY_DEFS_H 12 | #define PUTTY_DEFS_H 13 | 14 | #include 15 | 16 | #ifndef FALSE 17 | #define FALSE 0 18 | #endif 19 | #ifndef TRUE 20 | #define TRUE 1 21 | #endif 22 | 23 | typedef struct conf_tag Conf; 24 | typedef struct backend_tag Backend; 25 | typedef struct terminal_tag Terminal; 26 | 27 | typedef struct Filename Filename; 28 | typedef struct FontSpec FontSpec; 29 | 30 | typedef struct bufchain_tag bufchain; 31 | 32 | typedef struct strbuf strbuf; 33 | 34 | struct RSAKey; 35 | 36 | #include 37 | typedef uint32_t uint32; 38 | 39 | typedef struct BinarySink BinarySink; 40 | typedef struct BinarySource BinarySource; 41 | 42 | typedef struct SockAddr_tag *SockAddr; 43 | 44 | typedef struct Socket_vtable Socket_vtable; 45 | typedef struct Plug_vtable Plug_vtable; 46 | 47 | /* Note indirection: for historical reasons (it used to be closer to 48 | * the OS socket type), the type that most code uses for a socket is 49 | * 'Socket', not 'Socket *'. So an implementation of Socket or Plug 50 | * has a 'const Socket *' field for the vtable pointer, and the 51 | * 'Socket' type returned to client code is a pointer to _that_ in 52 | * turn. */ 53 | typedef const Socket_vtable **Socket; 54 | typedef const Plug_vtable **Plug; 55 | 56 | /* 57 | * A small structure wrapping up a (pointer, length) pair so that it 58 | * can be conveniently passed to or from a function. 59 | */ 60 | typedef struct ptrlen { 61 | const void *ptr; 62 | size_t len; 63 | } ptrlen; 64 | 65 | typedef struct logblank_t logblank_t; 66 | 67 | /* Do a compile-time type-check of 'to_check' (without evaluating it), 68 | * as a side effect of returning the value 'to_return'. Note that 69 | * although this macro double-*expands* to_return, it always 70 | * *evaluates* exactly one copy of it, so it's side-effect safe. */ 71 | #define TYPECHECK(to_check, to_return) \ 72 | (sizeof(to_check) ? (to_return) : (to_return)) 73 | 74 | /* Return a pointer to the object of structure type 'type' whose field 75 | * with name 'field' is pointed at by 'object'. */ 76 | #define FROMFIELD(object, type, field) \ 77 | TYPECHECK(object == &((type *)0)->field, \ 78 | ((type *)(((char *)(object)) - offsetof(type, field)))) 79 | 80 | #endif /* PUTTY_DEFS_H */ 81 | -------------------------------------------------------------------------------- /puttymem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PuTTY memory-handling header. 3 | */ 4 | 5 | #ifndef PUTTY_PUTTYMEM_H 6 | #define PUTTY_PUTTYMEM_H 7 | 8 | #include /* for size_t */ 9 | #include /* for memcpy() */ 10 | 11 | 12 | /* #define MALLOC_LOG do this if you suspect putty of leaking memory */ 13 | #ifdef MALLOC_LOG 14 | #define smalloc(z) (mlog(__FILE__,__LINE__), safemalloc(z,1)) 15 | #define snmalloc(z,s) (mlog(__FILE__,__LINE__), safemalloc(z,s)) 16 | #define srealloc(y,z) (mlog(__FILE__,__LINE__), saferealloc(y,z,1)) 17 | #define snrealloc(y,z,s) (mlog(__FILE__,__LINE__), saferealloc(y,z,s)) 18 | #define sfree(z) (mlog(__FILE__,__LINE__), safefree(z)) 19 | void mlog(char *, int); 20 | #else 21 | #define smalloc(z) safemalloc(z,1) 22 | #define snmalloc safemalloc 23 | #define srealloc(y,z) saferealloc(y,z,1) 24 | #define snrealloc saferealloc 25 | #define sfree safefree 26 | #endif 27 | 28 | void *safemalloc(size_t, size_t); 29 | void *saferealloc(void *, size_t, size_t); 30 | void safefree(void *); 31 | 32 | /* 33 | * Direct use of smalloc within the code should be avoided where 34 | * possible, in favour of these type-casting macros which ensure 35 | * you don't mistakenly allocate enough space for one sort of 36 | * structure and assign it to a different sort of pointer. 37 | * 38 | * The nasty trick in sresize with sizeof arranges for the compiler, 39 | * in passing, to type-check the expression ((type *)0 == (ptr)), i.e. 40 | * to type-check that the input pointer is a pointer to the correct 41 | * type. The construction sizeof(stuff) ? (b) : (b) looks like a 42 | * violation of the first principle of safe macros, but in fact it's 43 | * OK - although it _expands_ the macro parameter more than once, it 44 | * only _evaluates_ it once, so it's still side-effect safe. 45 | */ 46 | #define snew(type) ((type *)snmalloc(1, sizeof(type))) 47 | #define snewn(n, type) ((type *)snmalloc((n), sizeof(type))) 48 | #define sresize(ptr, n, type) \ 49 | ((type *)snrealloc(sizeof((type *)0 == (ptr)) ? (ptr) : (ptr), \ 50 | (n), sizeof(type))) 51 | 52 | /* 53 | * For cases where you want to allocate a struct plus a subsidiary 54 | * data buffer in one step, this macro lets you add a constant to the 55 | * amount malloced. 56 | * 57 | * Since the return value is already cast to the struct type, a 58 | * pointer to that many bytes of extra data can be conveniently 59 | * obtained by simply adding 1 to the returned pointer! 60 | * snew_plus_get_aux is a handy macro that does that and casts the 61 | * result to void *, so you can assign it straight to wherever you 62 | * wanted it. 63 | */ 64 | #define snew_plus(type, extra) ((type *)snmalloc(1, sizeof(type) + (extra))) 65 | #define snew_plus_get_aux(ptr) ((void *)((ptr) + 1)) 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /charset/xenc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * xenc.c - translate our internal character set codes to and from 3 | * X11 character encoding names. 4 | * 5 | */ 6 | 7 | #include 8 | #include "charset.h" 9 | #include "internal.h" 10 | 11 | static const struct { 12 | const char *name; 13 | int charset; 14 | } xencs[] = { 15 | /* 16 | * Officially registered encoding names. This list is derived 17 | * from the font encodings section of 18 | * 19 | * http://ftp.x.org/pub/DOCS/registry 20 | * 21 | * Where multiple encoding names map to the same encoding id 22 | * (such as iso8859-15 and fcd8859-15), the first is considered 23 | * canonical and will be returned when translating the id to a 24 | * string. 25 | */ 26 | { "iso8859-1", CS_ISO8859_1 }, 27 | { "iso8859-2", CS_ISO8859_2 }, 28 | { "iso8859-3", CS_ISO8859_3 }, 29 | { "iso8859-4", CS_ISO8859_4 }, 30 | { "iso8859-5", CS_ISO8859_5 }, 31 | { "iso8859-6", CS_ISO8859_6 }, 32 | { "iso8859-7", CS_ISO8859_7 }, 33 | { "iso8859-8", CS_ISO8859_8 }, 34 | { "iso8859-9", CS_ISO8859_9 }, 35 | { "iso8859-10", CS_ISO8859_10 }, 36 | { "iso8859-13", CS_ISO8859_13 }, 37 | { "iso8859-14", CS_ISO8859_14 }, 38 | { "iso8859-15", CS_ISO8859_15 }, 39 | { "fcd8859-15", CS_ISO8859_15 }, 40 | { "hp-roman8", CS_HP_ROMAN8 }, 41 | { "koi8-r", CS_KOI8_R }, 42 | /* 43 | * Unofficial encoding names found in the wild. 44 | */ 45 | { "iso8859-16", CS_ISO8859_16 }, 46 | { "koi8-u", CS_KOI8_U }, 47 | { "ibm-cp437", CS_CP437 }, 48 | { "ibm-cp850", CS_CP850 }, 49 | { "ibm-cp852", CS_CP852 }, 50 | { "ibm-cp866", CS_CP866 }, 51 | { "microsoft-cp1250", CS_CP1250 }, 52 | { "microsoft-cp1251", CS_CP1251 }, 53 | { "microsoft-cp1252", CS_CP1252 }, 54 | { "microsoft-cp1253", CS_CP1253 }, 55 | { "microsoft-cp1254", CS_CP1254 }, 56 | { "microsoft-cp1255", CS_CP1255 }, 57 | { "microsoft-cp1256", CS_CP1256 }, 58 | { "microsoft-cp1257", CS_CP1257 }, 59 | { "microsoft-cp1258", CS_CP1258 }, 60 | { "mac-roman", CS_MAC_ROMAN }, 61 | { "viscii1.1-1", CS_VISCII }, 62 | { "viscii1-1", CS_VISCII }, 63 | }; 64 | 65 | const char *charset_to_xenc(int charset) 66 | { 67 | int i; 68 | 69 | for (i = 0; i < (int)lenof(xencs); i++) 70 | if (charset == xencs[i].charset) 71 | return xencs[i].name; 72 | 73 | return NULL; /* not found */ 74 | } 75 | 76 | int charset_from_xenc(const char *name) 77 | { 78 | int i; 79 | 80 | for (i = 0; i < (int)lenof(xencs); i++) { 81 | const char *p, *q; 82 | p = name; 83 | q = xencs[i].name; 84 | while (*p || *q) { 85 | if (tolower((unsigned char)*p) != tolower((unsigned char)*q)) 86 | break; 87 | p++; q++; 88 | } 89 | if (!*p && !*q) 90 | return xencs[i].charset; 91 | } 92 | 93 | return CS_NONE; /* not found */ 94 | } 95 | -------------------------------------------------------------------------------- /ssh1censor.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Packet-censoring code for SSH-1, used to identify sensitive fields 3 | * like passwords so that the logging system can avoid writing them 4 | * into log files. 5 | */ 6 | 7 | #include 8 | 9 | #include "putty.h" 10 | #include "ssh.h" 11 | 12 | int ssh1_censor_packet( 13 | const PacketLogSettings *pls, int type, int sender_is_client, 14 | ptrlen pkt, logblank_t *blanks) 15 | { 16 | int nblanks = 0; 17 | ptrlen str; 18 | BinarySource src[1]; 19 | 20 | BinarySource_BARE_INIT(src, pkt.ptr, pkt.len); 21 | 22 | if (pls->omit_data && 23 | (type == SSH1_SMSG_STDOUT_DATA || 24 | type == SSH1_SMSG_STDERR_DATA || 25 | type == SSH1_CMSG_STDIN_DATA || 26 | type == SSH1_MSG_CHANNEL_DATA)) { 27 | /* "Session data" packets - omit the data string. */ 28 | if (type == SSH1_MSG_CHANNEL_DATA) 29 | get_uint32(src); /* skip channel id */ 30 | str = get_string(src); 31 | if (!get_err(src)) { 32 | assert(nblanks < MAX_BLANKS); 33 | blanks[nblanks].offset = src->pos - str.len; 34 | blanks[nblanks].type = PKTLOG_OMIT; 35 | blanks[nblanks].len = str.len; 36 | nblanks++; 37 | } 38 | } 39 | 40 | if (sender_is_client && pls->omit_passwords) { 41 | if (type == SSH1_CMSG_AUTH_PASSWORD || 42 | type == SSH1_CMSG_AUTH_TIS_RESPONSE || 43 | type == SSH1_CMSG_AUTH_CCARD_RESPONSE) { 44 | /* If this is a password or similar packet, blank the 45 | * password(s). */ 46 | assert(nblanks < MAX_BLANKS); 47 | blanks[nblanks].offset = 0; 48 | blanks[nblanks].len = pkt.len; 49 | blanks[nblanks].type = PKTLOG_BLANK; 50 | nblanks++; 51 | } else if (type == SSH1_CMSG_X11_REQUEST_FORWARDING) { 52 | /* 53 | * If this is an X forwarding request packet, blank the 54 | * fake auth data. 55 | * 56 | * Note that while we blank the X authentication data 57 | * here, we don't take any special action to blank the 58 | * start of an X11 channel, so using MIT-MAGIC-COOKIE-1 59 | * and actually opening an X connection without having 60 | * session blanking enabled is likely to leak your cookie 61 | * into the log. 62 | */ 63 | get_string(src); /* skip protocol name */ 64 | str = get_string(src); 65 | if (!get_err(src)) { 66 | assert(nblanks < MAX_BLANKS); 67 | blanks[nblanks].offset = src->pos - str.len; 68 | blanks[nblanks].type = PKTLOG_BLANK; 69 | blanks[nblanks].len = str.len; 70 | nblanks++; 71 | } 72 | } 73 | } 74 | 75 | return nblanks; 76 | } 77 | -------------------------------------------------------------------------------- /unix/putty.bundle: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 38 | ${env:PUTTY_GTK_PREFIX_FROM_MAKEFILE} 39 | 40 | 41 | gtk+-3.0 42 | 48 | ${project}/../osxlaunch 49 | 50 | 51 | ${project}/putty.plist 52 | 53 | 54 | ${project}/../puttyapp 55 | 56 | 57 | 58 | ${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/immodules/*.so 59 | 60 | 61 | 62 | ${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/printbackends/*.so 63 | 64 | 65 | 66 | ${prefix}/share/themes/Adwaita 67 | 68 | 69 | 70 | ${project}/../icons/PuTTY.icns 71 | 72 | 73 | 74 | Adwaita 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /sessprep.c: -------------------------------------------------------------------------------- 1 | /* 2 | * sessprep.c: centralise some preprocessing done on Conf objects 3 | * before launching them. 4 | */ 5 | 6 | #include "putty.h" 7 | 8 | void prepare_session(Conf *conf) 9 | { 10 | char *hostbuf = dupstr(conf_get_str(conf, CONF_host)); 11 | char *host = hostbuf; 12 | char *p, *q; 13 | 14 | /* 15 | * Trim leading whitespace from the hostname. 16 | */ 17 | host += strspn(host, " \t"); 18 | 19 | /* 20 | * See if host is of the form user@host, and separate out the 21 | * username if so. 22 | */ 23 | if (host[0] != '\0') { 24 | /* 25 | * Use strrchr, in case the _username_ in turn is of the form 26 | * user@host, which has been known. 27 | */ 28 | char *atsign = strrchr(host, '@'); 29 | if (atsign) { 30 | *atsign = '\0'; 31 | conf_set_str(conf, CONF_username, host); 32 | host = atsign + 1; 33 | } 34 | } 35 | 36 | /* 37 | * Trim a colon suffix off the hostname if it's there, and discard 38 | * the text after it. 39 | * 40 | * The exact reason why we _ignore_ this text, rather than 41 | * treating it as a port number, is unfortunately lost in the 42 | * mists of history: the commit which originally introduced this 43 | * change on 2001-05-06 was clear on _what_ it was doing but 44 | * didn't bother to explain _why_. But I [SGT, 2017-12-03] suspect 45 | * it has to do with priority order: what should a saved session 46 | * do if its CONF_host contains 'server.example.com:123' and its 47 | * CONF_port contains 456? If CONF_port contained the _default_ 48 | * port number then it might be a good guess that the colon suffix 49 | * on the host name was intended to override that, but you don't 50 | * really want to get into making heuristic judgments on that 51 | * basis. 52 | * 53 | * (Then again, you could just as easily make the same argument 54 | * about whether a 'user@' prefix on the host name should override 55 | * CONF_username, which this code _does_ do. I don't have a good 56 | * answer, sadly. Both these pieces of behaviour have been around 57 | * for years and it would probably cause subtle breakage in all 58 | * sorts of long-forgotten scripting to go changing things around 59 | * now.) 60 | * 61 | * In order to protect unbracketed IPv6 address literals against 62 | * this treatment, we do not make this change at all if there's 63 | * _more_ than one (un-IPv6-bracketed) colon. 64 | */ 65 | p = host_strchr(host, ':'); 66 | if (p && p != host_strrchr(host, ':')) { 67 | *p = '\0'; 68 | } 69 | 70 | /* 71 | * Remove any remaining whitespace. 72 | */ 73 | p = hostbuf; 74 | q = host; 75 | while (*q) { 76 | if (*q != ' ' && *q != '\t') 77 | *p++ = *q; 78 | q++; 79 | } 80 | *p = '\0'; 81 | 82 | conf_set_str(conf, CONF_host, hostbuf); 83 | sfree(hostbuf); 84 | } 85 | -------------------------------------------------------------------------------- /rdb/ITU-T-T.416-P41.txt: -------------------------------------------------------------------------------- 1 | 2 | A parameter substring for values 38 or 48 may be divided by one or more 3 | separators (03/10) into parameter elements, denoted as Pe. The format 4 | of such a parameter sub-string is indicated as: 5 | 6 | Pe : P ... 7 | 8 | Each parameter element consists of zero, one or more bit combinations from 9 | 03/00 to 03/09, representing the digits 0 to 9. An empty parameter element 10 | represents a default value for this parameter element. Empty parameter 11 | elements at the end of the parameter substring need not be included. 12 | The first parameter element indicates a choice between: 13 | 14 | 0 implementation defined (only applicable for the 15 | character foreground colour) 16 | 1 transparent; 17 | 2 direct colour in RGB space; 18 | 3 direct colour in CMY space; 19 | 4 direct colour in CMYK space; 20 | 5 indexed colour. 21 | 22 | If the first parameter has the value 0 or 1, there are no additional 23 | parameter elements. 24 | 25 | If the first parameter element has the value 5, then there is a second 26 | parameter element specifying the index into the colour table given by 27 | the attribute “content colour table” applying to the object with 28 | which the content is associated. 29 | 30 | If the first parameter element has the value 2, 3, or 4, the second 31 | parameter element specifies a colour space identifier referring to a 32 | colour space definition in the document profile. 33 | 34 | If the first parameter element has the value 2, the parameter elements 35 | 3, 4, and 5, are three integers for red, green, and blue colour 36 | components. Parameter 6 has no meaning. 37 | 38 | If the first parameter has the value 3, the parameter elements 3, 39 | 4, and 5 and three integers for cyan, magenta, and yellow colour 40 | components. Parameter 6 has no meaning. 41 | 42 | If the first parameter has the value 4, the parameter elements 3, 4, 43 | 5, and 6, are four integers for cyan, magenta, yellow, and black colour 44 | components. 45 | 46 | If the first parameter element has the value 2, 3, or 4, the parameter 47 | element 7 may be used to specify a tolerance value (an integer) and the 48 | parameter element 8 may be used to specify a colour space associated 49 | with the tolerance (0 for CIELUV, 1 for CIELAB). 50 | 51 | NOTE 3 – The “colour space id” component will refer 52 | to the applicable colour space description in the document 53 | profile which may contain colour scaling data that describe 54 | the scale and offset to be applied to the specified colour 55 | components in the character content. Appropriate use of 56 | scaling and offsets may be required to map all colour values 57 | required into the integer encoding space provided. This may 58 | be particularly important if concatenated content requires the 59 | insertion of such SGR sequences by the content layout process. 60 | 61 | 62 | ITU-T Rec. T.416 (1993 E) Page:41 63 | -------------------------------------------------------------------------------- /ldiscucs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ldisc.c: PuTTY line discipline. Sits between the input coming 3 | * from keypresses in the window, and the output channel leading to 4 | * the back end. Implements echo and/or local line editing, 5 | * depending on what's currently configured. 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | #include "putty.h" 12 | #include "terminal.h" 13 | #include "ldisc.h" 14 | 15 | void lpage_send(void *handle, 16 | int codepage, const char *buf, int len, int interactive) 17 | { 18 | Ldisc ldisc = (Ldisc)handle; 19 | wchar_t *widebuffer = 0; 20 | int widesize = 0; 21 | int wclen; 22 | 23 | if (codepage < 0) { 24 | ldisc_send(ldisc, buf, len, interactive); 25 | return; 26 | } 27 | 28 | widesize = len * 2; 29 | widebuffer = snewn(widesize, wchar_t); 30 | 31 | wclen = mb_to_wc(codepage, 0, buf, len, widebuffer, widesize); 32 | luni_send(ldisc, widebuffer, wclen, interactive); 33 | 34 | sfree(widebuffer); 35 | } 36 | 37 | void luni_send(void *handle, const wchar_t *widebuf, int len, int interactive) 38 | { 39 | Ldisc ldisc = (Ldisc)handle; 40 | char *linebuffer; 41 | int linesize; 42 | int i; 43 | char *p; 44 | 45 | /* UTF-8 is now upto 4 bytes/char as is GB18030. Largest windows MBCS 46 | * is 5 bytes/character */ 47 | linesize = len * 5; 48 | linebuffer = snewn(linesize, char); 49 | 50 | if (in_utf(ldisc->term)) { 51 | /* UTF is a simple algorithm */ 52 | for (p = linebuffer, i = 0; i < len; i++) { 53 | unsigned long ch = widebuf[i]; 54 | 55 | if (IS_SURROGATE(ch)) { 56 | #ifdef PLATFORM_IS_UTF16 57 | if (i+1 < len) { 58 | unsigned long ch2 = widebuf[i+1]; 59 | if (IS_SURROGATE_PAIR(ch, ch2)) { 60 | ch = FROM_SURROGATES(ch, ch2); 61 | i++; 62 | } 63 | } else 64 | #endif 65 | { 66 | /* Unrecognised UTF-16 sequence */ 67 | ch = '.'; 68 | } 69 | } 70 | 71 | if (ch < 0x80) { 72 | *p++ = (char) (ch); 73 | } else if (ch < 0x800) { 74 | *p++ = (char) (0xC0 | (ch >> 6)); 75 | *p++ = (char) (0x80 | (ch & 0x3F)); 76 | } else if (ch < 0x10000) { 77 | *p++ = (char) (0xE0 | (ch >> 12)); 78 | *p++ = (char) (0x80 | ((ch >> 6) & 0x3F)); 79 | *p++ = (char) (0x80 | (ch & 0x3F)); 80 | } else { 81 | *p++ = (char) (0xF0 | (ch >> 18)); 82 | *p++ = (char) (0x80 | ((ch >> 12) & 0x3F)); 83 | *p++ = (char) (0x80 | ((ch >> 6) & 0x3F)); 84 | *p++ = (char) (0x80 | (ch & 0x3F)); 85 | } 86 | } 87 | } else { 88 | int rv; 89 | if (ldisc->term->ucsdata->line_codepage == CP_UTF8) { 90 | rv = wc_to_mb(CP_ISO8859_1, 0, widebuf, len, 91 | linebuffer, linesize, NULL, NULL, ldisc->term->ucsdata); 92 | } else 93 | rv = wc_to_mb(ldisc->term->ucsdata->line_codepage, 0, widebuf, len, 94 | linebuffer, linesize, NULL, NULL, ldisc->term->ucsdata); 95 | if (rv >= 0) 96 | p = linebuffer + rv; 97 | else 98 | p = linebuffer; 99 | } 100 | if (p > linebuffer) 101 | ldisc_send(ldisc, linebuffer, p - linebuffer, interactive); 102 | 103 | sfree(linebuffer); 104 | } 105 | -------------------------------------------------------------------------------- /rdb/Missing-patches/rdb24bit/0008-Add-flag-to-reduce-scrollback-memory-consumption.patch: -------------------------------------------------------------------------------- 1 | From 512ed1518808fceede2afcc596c25cde7d6f4faf Mon Sep 17 00:00:00 2001 2 | From: Robert de Bath 3 | Date: Sun, 20 Dec 2015 20:29:06 +0000 4 | Subject: [PATCH 08/71] Add flag to reduce scrollback memory consumption 5 | 6 | when there are no combining characters. 7 | --- 8 | putty.h | 1 + 9 | terminal.c | 22 ++++++++++++++++++---- 10 | 2 files changed, 19 insertions(+), 4 deletions(-) 11 | 12 | diff --git a/putty.h b/putty.h 13 | index e622e80..de831c5 100644 14 | --- a/putty.h 15 | +++ b/putty.h 16 | @@ -72,6 +72,7 @@ typedef struct terminal_tag Terminal; 17 | #define LATTR_TOP 0x00000002UL 18 | #define LATTR_BOT 0x00000003UL 19 | #define LATTR_MODE 0x00000003UL 20 | +#define LATTR_HASCC 0x00000004UL 21 | #define LATTR_HASTC 0x00000008UL 22 | #define LATTR_WRAPPED 0x00000010UL /* this line wraps to next */ 23 | #define LATTR_WRAPPED2 0x00000020UL /* with WRAPPED: CJK wide character 24 | diff --git a/terminal.c b/terminal.c 25 | index d938be0..66552ce 100644 26 | --- a/terminal.c 27 | +++ b/terminal.c 28 | @@ -673,7 +673,7 @@ static unsigned char *compressline(termline *ldata) 29 | { 30 | struct buf buffer = { NULL, 0, 0 }, *b = &buffer; 31 | #if !defined(COMBI_COLOUR) && !defined(THIN_TC24) 32 | - int has_tc = 0; 33 | + int has_tc = 0, has_cc = 0; 34 | { 35 | int i, c = ldata->cols; 36 | for(i=0; ichars[i].cc_next) { 43 | + has_cc = 1; 44 | + break; 45 | + } 46 | + } 47 | } 48 | #endif 49 | 50 | @@ -704,7 +710,7 @@ static unsigned char *compressline(termline *ldata) 51 | */ 52 | { 53 | #if !defined(COMBI_COLOUR) && !defined(THIN_TC24) 54 | - int n = ldata->lattr | (has_tc?LATTR_HASTC:0); 55 | + int n = ldata->lattr | (has_tc?LATTR_HASTC:0) | (has_cc?LATTR_HASCC:0); 56 | #else 57 | int n = ldata->lattr; 58 | #endif 59 | @@ -730,10 +736,13 @@ static unsigned char *compressline(termline *ldata) 60 | */ 61 | makerle(b, ldata, makeliteral_chr); 62 | makerle(b, ldata, makeliteral_attr); 63 | - makerle(b, ldata, makeliteral_cc); 64 | #if !defined(COMBI_COLOUR) && !defined(THIN_TC24) 65 | + if (has_cc) 66 | + makerle(b, ldata, makeliteral_cc); 67 | if (has_tc) 68 | makerle(b, ldata, makeliteral_t416); 69 | +#else 70 | + makerle(b, ldata, makeliteral_cc); 71 | #endif 72 | 73 | /* 74 | @@ -985,12 +994,17 @@ static termline *decompressline(unsigned char *data, int *bytes_used) 75 | */ 76 | readrle(b, ldata, readliteral_chr); 77 | readrle(b, ldata, readliteral_attr); 78 | - readrle(b, ldata, readliteral_cc); 79 | #if !defined(COMBI_COLOUR) && !defined(THIN_TC24) 80 | + if (ldata->lattr & LATTR_HASCC) { 81 | + ldata->lattr &= ~LATTR_HASCC; 82 | + readrle(b, ldata, readliteral_cc); 83 | + } 84 | if (ldata->lattr & LATTR_HASTC) { 85 | ldata->lattr &= ~LATTR_HASTC; 86 | readrle(b, ldata, readliteral_t416); 87 | } 88 | +#else 89 | + readrle(b, ldata, readliteral_cc); 90 | #endif 91 | 92 | /* Return the number of bytes read, for diagnostic purposes. */ 93 | -- 94 | 2.1.4 95 | 96 | -------------------------------------------------------------------------------- /charset/sbcsgen.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl -w 2 | 3 | # This script generates sbcsdat.c (the data for all the SBCSes) from its 4 | # source form sbcs.dat. 5 | 6 | $infile = "sbcs.dat"; 7 | $outfile = "sbcsdat.c"; 8 | 9 | open FOO, $infile; 10 | open BAR, ">$outfile"; 11 | select BAR; 12 | 13 | print "/*\n"; 14 | print " * sbcsdat.c - data definitions for single-byte character sets.\n"; 15 | print " *\n"; 16 | print " * Generated by sbcsgen.pl from sbcs.dat.\n"; 17 | print " * You should edit those files rather than editing this one.\n"; 18 | print " */\n"; 19 | print "\n"; 20 | print "#ifndef ENUM_CHARSETS\n"; 21 | print "\n"; 22 | print "#include \"charset.h\"\n"; 23 | print "#include \"internal.h\"\n"; 24 | print "\n"; 25 | 26 | my $charsetname = undef; 27 | my @vals = (); 28 | 29 | my @charsetnames = (); 30 | my @sortpriority = (); 31 | 32 | while () { 33 | chomp; 34 | if (/^charset (.*)$/) { 35 | $charsetname = $1; 36 | @vals = (); 37 | @sortpriority = map { 0 } 0..255; 38 | } elsif (/^sortpriority ([^-]*)-([^-]*) (.*)$/) { 39 | for ($i = hex $1; $i <= hex $2; $i++) { 40 | $sortpriority[$i] += $3; 41 | } 42 | } elsif (/^[0-9a-fA-FX]/) { 43 | push @vals, map { $_ eq "XXXX" ? -1 : hex $_ } split / +/, $_; 44 | if (scalar @vals > 256) { 45 | die "$infile:$.: charset $charsetname has more than 256 values\n"; 46 | } elsif (scalar @vals == 256) { 47 | &outcharset($charsetname, \@vals, \@sortpriority); 48 | push @charsetnames, $charsetname; 49 | $charsetname = undef; 50 | @vals = (); 51 | @sortpriority = map { 0 } 0..255; 52 | } 53 | } 54 | } 55 | 56 | print "#else /* ENUM_CHARSETS */\n"; 57 | print "\n"; 58 | 59 | foreach $i (@charsetnames) { 60 | print "ENUM_CHARSET($i)\n"; 61 | } 62 | 63 | print "\n"; 64 | print "#endif /* ENUM_CHARSETS */\n"; 65 | 66 | sub outcharset($$$) { 67 | my ($name, $vals, $sortpriority) = @_; 68 | my ($prefix, $i, @sorted); 69 | 70 | print "static const sbcs_data data_$name = {\n"; 71 | print " {\n"; 72 | $prefix = " "; 73 | @sorted = (); 74 | for ($i = 0; $i < 256; $i++) { 75 | if ($vals->[$i] < 0) { 76 | printf "%sERROR ", $prefix; 77 | } else { 78 | printf "%s0x%04x", $prefix, $vals->[$i]; 79 | die "ooh? $i\n" unless defined $sortpriority->[$i]; 80 | push @sorted, [$i, $vals->[$i], 0+$sortpriority->[$i]]; 81 | } 82 | if ($i % 8 == 7) { 83 | $prefix = ",\n "; 84 | } else { 85 | $prefix = ", "; 86 | } 87 | } 88 | print "\n },\n {\n"; 89 | @sorted = sort { ($a->[1] == $b->[1] ? 90 | $b->[2] <=> $a->[2] : 91 | $a->[1] <=> $b->[1]) || 92 | $a->[0] <=> $b->[0] } @sorted; 93 | $prefix = " "; 94 | $uval = -1; 95 | for ($i = $j = 0; $i < scalar @sorted; $i++) { 96 | next if ($uval == $sorted[$i]->[1]); # low-priority alternative 97 | $uval = $sorted[$i]->[1]; 98 | printf "%s0x%02x", $prefix, $sorted[$i]->[0]; 99 | if ($j % 8 == 7) { 100 | $prefix = ",\n "; 101 | } else { 102 | $prefix = ", "; 103 | } 104 | $j++; 105 | } 106 | printf "\n },\n %d\n", $j; 107 | print "};\n"; 108 | print "const charset_spec charset_$name = {\n" . 109 | " $name, read_sbcs, write_sbcs, &data_$name\n};\n\n"; 110 | } 111 | -------------------------------------------------------------------------------- /licence.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl -w 2 | 3 | # This script generates licence.h (containing the PuTTY licence in the 4 | # form of macros expanding to C string literals) from the LICENCE 5 | # master file. It also regenerates the licence-related Halibut input 6 | # files. 7 | 8 | use File::Basename; 9 | 10 | # Read the input file. 11 | $infile = "LICENCE"; 12 | open my $in, $infile or die "$infile: open: $!\n"; 13 | my @lines = (); 14 | while (<$in>) { 15 | chomp; 16 | push @lines, $_; 17 | } 18 | close $in; 19 | 20 | # Format into paragraphs. 21 | my @paras = (); 22 | my $para = undef; 23 | for my $line (@lines) { 24 | if ($line eq "") { 25 | $para = undef; 26 | } elsif (!defined $para) { 27 | push @paras, $line; 28 | $para = \$paras[$#paras]; 29 | } else { 30 | $$para .= " " . $line; 31 | } 32 | } 33 | 34 | # Get the copyright years and short form of copyright holder. 35 | die "bad format of first paragraph\n" 36 | unless $paras[0] =~ m!copyright ([^\.]*)\.!i; 37 | $shortdetails = $1; 38 | 39 | # Write out licence.h. 40 | 41 | $outfile = "licence.h"; 42 | open my $out, ">", $outfile or die "$outfile: open: $!\n"; 43 | select $out; 44 | 45 | print "/*\n"; 46 | print " * $outfile - macro definitions for the PuTTY licence.\n"; 47 | print " *\n"; 48 | print " * Generated by @{[basename __FILE__]} from $infile.\n"; 49 | print " * You should edit those files rather than editing this one.\n"; 50 | print " */\n"; 51 | print "\n"; 52 | 53 | print "#define LICENCE_TEXT(parsep) \\\n"; 54 | for my $i (0..$#paras) { 55 | my $lit = &stringlit($paras[$i]); 56 | print " parsep \\\n" if $i > 0; 57 | print " \"$lit\""; 58 | print " \\" if $i < $#paras; 59 | print "\n"; 60 | } 61 | print "\n"; 62 | 63 | printf "#define SHORT_COPYRIGHT_DETAILS \"%s\"\n", &stringlit($shortdetails); 64 | 65 | sub stringlit { 66 | my ($lit) = @_; 67 | $lit =~ s!\\!\\\\!g; 68 | $lit =~ s!"!\\"!g; 69 | return $lit; 70 | } 71 | 72 | close $out; 73 | 74 | # Write out doc/licence.but. 75 | 76 | $outfile = "doc/licence.but"; 77 | open $out, ">", $outfile or die "$outfile: open: $!\n"; 78 | select $out; 79 | 80 | print "\\# Generated by @{[basename __FILE__]} from $infile.\n"; 81 | print "\\# You should edit those files rather than editing this one.\n\n"; 82 | 83 | print "\\A{licence} PuTTY \\ii{Licence}\n\n"; 84 | 85 | for my $i (0..$#paras) { 86 | my $para = &halibutescape($paras[$i]); 87 | if ($i == 0) { 88 | $para =~ s!copyright!\\i{copyright}!; # index term in paragraph 1 89 | } 90 | print "$para\n\n"; 91 | } 92 | 93 | close $out; 94 | 95 | # And write out doc/copy.but, which defines a macro used in the manual 96 | # preamble blurb. 97 | 98 | $outfile = "doc/copy.but"; 99 | open $out, ">", $outfile or die "$outfile: open: $!\n"; 100 | select $out; 101 | 102 | print "\\# Generated by @{[basename __FILE__]} from $infile.\n"; 103 | print "\\# You should edit those files rather than editing this one.\n\n"; 104 | 105 | printf "\\define{shortcopyrightdetails} %s\n\n", 106 | &halibutescape($shortdetails); 107 | 108 | close $out; 109 | 110 | sub halibutescape { 111 | my ($text) = @_; 112 | $text =~ s![\\{}]!\\$&!g; # Halibut escaping 113 | $text =~ s!"([^"]*)"!\\q{$1}!g; # convert quoted strings to \q{} 114 | return $text; 115 | } 116 | -------------------------------------------------------------------------------- /unix/uxsel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * uxsel.c 3 | * 4 | * This module is a sort of all-purpose interchange for file 5 | * descriptors. At one end it talks to uxnet.c and pty.c and 6 | * anything else which might have one or more fds that need 7 | * select()-type things doing to them during an extended program 8 | * run; at the other end it talks to pterm.c or uxplink.c or 9 | * anything else which might have its own means of actually doing 10 | * those select()-type things. 11 | */ 12 | 13 | #include 14 | 15 | #include "putty.h" 16 | #include "tree234.h" 17 | 18 | struct fd { 19 | int fd; 20 | int rwx; /* 4=except 2=write 1=read */ 21 | uxsel_callback_fn callback; 22 | uxsel_id *id; /* for uxsel_input_remove */ 23 | }; 24 | 25 | static tree234 *fds; 26 | 27 | static int uxsel_fd_cmp(void *av, void *bv) 28 | { 29 | struct fd *a = (struct fd *)av; 30 | struct fd *b = (struct fd *)bv; 31 | if (a->fd < b->fd) 32 | return -1; 33 | if (a->fd > b->fd) 34 | return +1; 35 | return 0; 36 | } 37 | static int uxsel_fd_findcmp(void *av, void *bv) 38 | { 39 | int *a = (int *)av; 40 | struct fd *b = (struct fd *)bv; 41 | if (*a < b->fd) 42 | return -1; 43 | if (*a > b->fd) 44 | return +1; 45 | return 0; 46 | } 47 | 48 | void uxsel_init(void) 49 | { 50 | fds = newtree234(uxsel_fd_cmp); 51 | } 52 | 53 | /* 54 | * Here is the interface to fd-supplying modules. They supply an 55 | * fd, a set of read/write/execute states, and a callback function 56 | * for when the fd satisfies one of those states. Repeated calls to 57 | * uxsel_set on the same fd are perfectly legal and serve to change 58 | * the rwx state (typically you only want to select an fd for 59 | * writing when you actually have pending data you want to write to 60 | * it!). 61 | */ 62 | 63 | void uxsel_set(int fd, int rwx, uxsel_callback_fn callback) 64 | { 65 | struct fd *newfd; 66 | 67 | assert(fd >= 0); 68 | 69 | uxsel_del(fd); 70 | 71 | if (rwx) { 72 | newfd = snew(struct fd); 73 | newfd->fd = fd; 74 | newfd->rwx = rwx; 75 | newfd->callback = callback; 76 | newfd->id = uxsel_input_add(fd, rwx); 77 | add234(fds, newfd); 78 | } 79 | } 80 | 81 | void uxsel_del(int fd) 82 | { 83 | struct fd *oldfd = find234(fds, &fd, uxsel_fd_findcmp); 84 | if (oldfd) { 85 | if (oldfd->id) 86 | uxsel_input_remove(oldfd->id); 87 | del234(fds, oldfd); 88 | sfree(oldfd); 89 | } 90 | } 91 | 92 | /* 93 | * And here is the interface to select-functionality-supplying 94 | * modules. 95 | */ 96 | 97 | int next_fd(int *state, int *rwx) 98 | { 99 | struct fd *fd; 100 | fd = index234(fds, (*state)++); 101 | if (fd) { 102 | *rwx = fd->rwx; 103 | return fd->fd; 104 | } else 105 | return -1; 106 | } 107 | 108 | int first_fd(int *state, int *rwx) 109 | { 110 | *state = 0; 111 | return next_fd(state, rwx); 112 | } 113 | 114 | void select_result(int fd, int event) 115 | { 116 | struct fd *fdstruct = find234(fds, &fd, uxsel_fd_findcmp); 117 | /* 118 | * Apparently this can sometimes be NULL. Can't see how, but I 119 | * assume it means I need to ignore the event since it's on an 120 | * fd I've stopped being interested in. Sigh. 121 | */ 122 | if (fdstruct) 123 | fdstruct->callback(fd, event); 124 | } 125 | -------------------------------------------------------------------------------- /charset/internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * internal.h - internal header stuff for the charset library. 3 | */ 4 | 5 | #ifndef charset_internal_h 6 | #define charset_internal_h 7 | 8 | /* This invariably comes in handy */ 9 | #define lenof(x) ( sizeof((x)) / sizeof(*(x)) ) 10 | 11 | /* This is an invalid Unicode value used to indicate an error. */ 12 | #define ERROR 0xFFFFL /* Unicode value representing error */ 13 | 14 | typedef struct charset_spec charset_spec; 15 | typedef struct sbcs_data sbcs_data; 16 | 17 | struct charset_spec { 18 | int charset; /* numeric identifier */ 19 | 20 | /* 21 | * A function to read the character set and output Unicode 22 | * characters. The `emit' function expects to get Unicode chars 23 | * passed to it; it should be sent ERROR for any encoding error 24 | * on the input. 25 | */ 26 | void (*read)(charset_spec const *charset, long int input_chr, 27 | charset_state *state, 28 | void (*emit)(void *ctx, long int output), void *emitctx); 29 | /* 30 | * A function to read Unicode characters and output in this 31 | * character set. The `emit' function expects to get byte 32 | * values passed to it; it should be sent ERROR for any 33 | * non-representable characters on the input. 34 | */ 35 | void (*write)(charset_spec const *charset, long int input_chr, 36 | charset_state *state, 37 | void (*emit)(void *ctx, long int output), void *emitctx); 38 | void const *data; 39 | }; 40 | 41 | /* 42 | * This is the format of `data' used by the SBCS read and write 43 | * functions; so it's the format used in all SBCS definitions. 44 | */ 45 | struct sbcs_data { 46 | /* 47 | * This is a simple mapping table converting each SBCS position 48 | * to a Unicode code point. Some positions may contain ERROR, 49 | * indicating that that byte value is not defined in the SBCS 50 | * in question and its occurrence in input is an error. 51 | */ 52 | unsigned long sbcs2ucs[256]; 53 | 54 | /* 55 | * This lookup table is used to convert Unicode back to the 56 | * SBCS. It consists of the valid byte values in the SBCS, 57 | * sorted in order of their Unicode translation. So given a 58 | * Unicode value U, you can do a binary search on this table 59 | * using the above table as a lookup: when testing the Xth 60 | * position in this table, you branch according to whether 61 | * sbcs2ucs[ucs2sbcs[X]] is less than, greater than, or equal 62 | * to U. 63 | * 64 | * Note that since there may be fewer than 256 valid byte 65 | * values in a particular SBCS, we must supply the length of 66 | * this table as well as the contents. 67 | */ 68 | unsigned char ucs2sbcs[256]; 69 | int nvalid; 70 | }; 71 | 72 | /* 73 | * Prototypes for internal library functions. 74 | */ 75 | charset_spec const *charset_find_spec(int charset); 76 | void read_sbcs(charset_spec const *charset, long int input_chr, 77 | charset_state *state, 78 | void (*emit)(void *ctx, long int output), void *emitctx); 79 | void write_sbcs(charset_spec const *charset, long int input_chr, 80 | charset_state *state, 81 | void (*emit)(void *ctx, long int output), void *emitctx); 82 | 83 | /* 84 | * Placate compiler warning about unused parameters, of which we 85 | * expect to have some in this library. 86 | */ 87 | #define UNUSEDARG(x) ( (x) = (x) ) 88 | 89 | #endif /* charset_internal_h */ 90 | -------------------------------------------------------------------------------- /windows/winnpc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Windows support module which deals with being a named-pipe client. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | #define DEFINE_PLUG_METHOD_MACROS 9 | #include "tree234.h" 10 | #include "putty.h" 11 | #include "network.h" 12 | #include "proxy.h" 13 | #include "ssh.h" 14 | 15 | #if !defined NO_SECURITY 16 | 17 | #include "winsecur.h" 18 | 19 | Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, HANDLE stderr_H, 20 | Plug plug, int overlapped); 21 | 22 | Socket new_named_pipe_client(const char *pipename, Plug plug) 23 | { 24 | HANDLE pipehandle; 25 | PSID usersid, pipeowner; 26 | PSECURITY_DESCRIPTOR psd; 27 | char *err; 28 | Socket ret; 29 | 30 | assert(strncmp(pipename, "\\\\.\\pipe\\", 9) == 0); 31 | assert(strchr(pipename + 9, '\\') == NULL); 32 | 33 | while (1) { 34 | pipehandle = CreateFile(pipename, GENERIC_READ | GENERIC_WRITE, 35 | 0, NULL, OPEN_EXISTING, 36 | FILE_FLAG_OVERLAPPED, NULL); 37 | 38 | if (pipehandle != INVALID_HANDLE_VALUE) 39 | break; 40 | 41 | if (GetLastError() != ERROR_PIPE_BUSY) { 42 | err = dupprintf("Unable to open named pipe '%s': %s", 43 | pipename, win_strerror(GetLastError())); 44 | ret = new_error_socket(err, plug); 45 | sfree(err); 46 | return ret; 47 | } 48 | 49 | /* 50 | * If we got ERROR_PIPE_BUSY, wait for the server to 51 | * create a new pipe instance. (Since the server is 52 | * expected to be winnps.c, which will do that immediately 53 | * after a previous connection is accepted, that shouldn't 54 | * take excessively long.) 55 | */ 56 | if (!WaitNamedPipe(pipename, NMPWAIT_USE_DEFAULT_WAIT)) { 57 | err = dupprintf("Error waiting for named pipe '%s': %s", 58 | pipename, win_strerror(GetLastError())); 59 | ret = new_error_socket(err, plug); 60 | sfree(err); 61 | return ret; 62 | } 63 | } 64 | 65 | if ((usersid = get_user_sid()) == NULL) { 66 | CloseHandle(pipehandle); 67 | err = dupprintf("Unable to get user SID"); 68 | ret = new_error_socket(err, plug); 69 | sfree(err); 70 | return ret; 71 | } 72 | 73 | if (p_GetSecurityInfo(pipehandle, SE_KERNEL_OBJECT, 74 | OWNER_SECURITY_INFORMATION, 75 | &pipeowner, NULL, NULL, NULL, 76 | &psd) != ERROR_SUCCESS) { 77 | err = dupprintf("Unable to get named pipe security information: %s", 78 | win_strerror(GetLastError())); 79 | ret = new_error_socket(err, plug); 80 | sfree(err); 81 | CloseHandle(pipehandle); 82 | return ret; 83 | } 84 | 85 | if (!EqualSid(pipeowner, usersid)) { 86 | err = dupprintf("Owner of named pipe '%s' is not us", pipename); 87 | ret = new_error_socket(err, plug); 88 | sfree(err); 89 | CloseHandle(pipehandle); 90 | LocalFree(psd); 91 | return ret; 92 | } 93 | 94 | LocalFree(psd); 95 | 96 | return make_handle_socket(pipehandle, pipehandle, NULL, plug, TRUE); 97 | } 98 | 99 | #endif /* !defined NO_SECURITY */ 100 | -------------------------------------------------------------------------------- /ssharcf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Arcfour (RC4) implementation for PuTTY. 3 | * 4 | * Coded from Schneier. 5 | */ 6 | 7 | #include 8 | #include "ssh.h" 9 | 10 | typedef struct { 11 | unsigned char i, j, s[256]; 12 | } ArcfourContext; 13 | 14 | static void arcfour_block(void *handle, void *vblk, int len) 15 | { 16 | unsigned char *blk = (unsigned char *)vblk; 17 | ArcfourContext *ctx = (ArcfourContext *)handle; 18 | unsigned k; 19 | unsigned char tmp, i, j, *s; 20 | 21 | s = ctx->s; 22 | i = ctx->i; j = ctx->j; 23 | for (k = 0; (int)k < len; k++) { 24 | i = (i + 1) & 0xff; 25 | j = (j + s[i]) & 0xff; 26 | tmp = s[i]; s[i] = s[j]; s[j] = tmp; 27 | blk[k] ^= s[(s[i]+s[j]) & 0xff]; 28 | } 29 | ctx->i = i; ctx->j = j; 30 | } 31 | 32 | static void arcfour_setkey(ArcfourContext *ctx, unsigned char const *key, 33 | unsigned keybytes) 34 | { 35 | unsigned char tmp, k[256], *s; 36 | unsigned i, j; 37 | 38 | s = ctx->s; 39 | assert(keybytes <= 256); 40 | ctx->i = ctx->j = 0; 41 | for (i = 0; i < 256; i++) { 42 | s[i] = i; 43 | k[i] = key[i % keybytes]; 44 | } 45 | j = 0; 46 | for (i = 0; i < 256; i++) { 47 | j = (j + s[i] + k[i]) & 0xff; 48 | tmp = s[i]; s[i] = s[j]; s[j] = tmp; 49 | } 50 | } 51 | 52 | /* -- Interface with PuTTY -- */ 53 | 54 | /* 55 | * We don't implement Arcfour in SSH-1 because it's utterly insecure in 56 | * several ways. See CERT Vulnerability Notes VU#25309, VU#665372, 57 | * and VU#565052. 58 | * 59 | * We don't implement the "arcfour" algorithm in SSH-2 because it doesn't 60 | * stir the cipher state before emitting keystream, and hence is likely 61 | * to leak data about the key. 62 | */ 63 | 64 | static void *arcfour_make_context(void) 65 | { 66 | return snew(ArcfourContext); 67 | } 68 | 69 | static void arcfour_free_context(void *handle) 70 | { 71 | sfree(handle); 72 | } 73 | 74 | static void arcfour_stir(ArcfourContext *ctx) 75 | { 76 | unsigned char *junk = snewn(1536, unsigned char); 77 | memset(junk, 0, 1536); 78 | arcfour_block(ctx, junk, 1536); 79 | smemclr(junk, 1536); 80 | sfree(junk); 81 | } 82 | 83 | static void arcfour128_key(void *handle, const void *key) 84 | { 85 | ArcfourContext *ctx = (ArcfourContext *)handle; 86 | arcfour_setkey(ctx, key, 16); 87 | arcfour_stir(ctx); 88 | } 89 | 90 | static void arcfour256_key(void *handle, const void *key) 91 | { 92 | ArcfourContext *ctx = (ArcfourContext *)handle; 93 | arcfour_setkey(ctx, key, 32); 94 | arcfour_stir(ctx); 95 | } 96 | 97 | static void arcfour_iv(void *handle, const void *iv) 98 | { 99 | 100 | } 101 | 102 | const struct ssh2_cipher ssh_arcfour128_ssh2 = { 103 | arcfour_make_context, arcfour_free_context, arcfour_iv, arcfour128_key, 104 | arcfour_block, arcfour_block, NULL, NULL, 105 | "arcfour128", 106 | 1, 128, 16, 0, "Arcfour-128", 107 | NULL 108 | }; 109 | 110 | const struct ssh2_cipher ssh_arcfour256_ssh2 = { 111 | arcfour_make_context, arcfour_free_context, arcfour_iv, arcfour256_key, 112 | arcfour_block, arcfour_block, NULL, NULL, 113 | "arcfour256", 114 | 1, 256, 32, 0, "Arcfour-256", 115 | NULL 116 | }; 117 | 118 | static const struct ssh2_cipher *const arcfour_list[] = { 119 | &ssh_arcfour256_ssh2, 120 | &ssh_arcfour128_ssh2, 121 | }; 122 | 123 | const struct ssh2_ciphers ssh2_arcfour = { 124 | sizeof(arcfour_list) / sizeof(*arcfour_list), 125 | arcfour_list 126 | }; 127 | -------------------------------------------------------------------------------- /proxy.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Network proxy abstraction in PuTTY 3 | * 4 | * A proxy layer, if necessary, wedges itself between the 5 | * network code and the higher level backend. 6 | * 7 | * Supported proxies: HTTP CONNECT, generic telnet, SOCKS 4 & 5 8 | */ 9 | 10 | #ifndef PUTTY_PROXY_H 11 | #define PUTTY_PROXY_H 12 | 13 | #define PROXY_ERROR_GENERAL 8000 14 | #define PROXY_ERROR_UNEXPECTED 8001 15 | 16 | typedef struct ProxySocket ProxySocket; 17 | 18 | struct ProxySocket { 19 | const char *error; 20 | 21 | Socket sub_socket; 22 | Plug plug; 23 | SockAddr remote_addr; 24 | int remote_port; 25 | 26 | bufchain pending_output_data; 27 | bufchain pending_oob_output_data; 28 | int pending_flush; 29 | bufchain pending_input_data; 30 | int pending_eof; 31 | 32 | #define PROXY_STATE_NEW -1 33 | #define PROXY_STATE_ACTIVE 0 34 | 35 | int state; /* proxy states greater than 0 are implementation 36 | * dependent, but represent various stages/states 37 | * of the initialization/setup/negotiation with the 38 | * proxy server. 39 | */ 40 | int freeze; /* should we freeze the underlying socket when 41 | * we are done with the proxy negotiation? this 42 | * simply caches the value of sk_set_frozen calls. 43 | */ 44 | 45 | #define PROXY_CHANGE_NEW -1 46 | #define PROXY_CHANGE_CLOSING 0 47 | #define PROXY_CHANGE_SENT 1 48 | #define PROXY_CHANGE_RECEIVE 2 49 | #define PROXY_CHANGE_ACCEPTING 3 50 | 51 | /* something has changed (a call from the sub socket 52 | * layer into our Proxy Plug layer, or we were just 53 | * created, etc), so the proxy layer needs to handle 54 | * this change (the type of which is the second argument) 55 | * and further the proxy negotiation process. 56 | */ 57 | 58 | int (*negotiate) (ProxySocket * /* this */, int /* change type */); 59 | 60 | /* current arguments of plug handlers 61 | * (for use by proxy's negotiate function) 62 | */ 63 | 64 | /* closing */ 65 | const char *closing_error_msg; 66 | int closing_error_code; 67 | int closing_calling_back; 68 | 69 | /* receive */ 70 | int receive_urgent; 71 | char *receive_data; 72 | int receive_len; 73 | 74 | /* sent */ 75 | int sent_bufsize; 76 | 77 | /* accepting */ 78 | accept_fn_t accepting_constructor; 79 | accept_ctx_t accepting_ctx; 80 | 81 | /* configuration, used to look up proxy settings */ 82 | Conf *conf; 83 | 84 | /* CHAP transient data */ 85 | int chap_num_attributes; 86 | int chap_num_attributes_processed; 87 | int chap_current_attribute; 88 | int chap_current_datalen; 89 | 90 | const Socket_vtable *sockvt; 91 | const Plug_vtable *plugvt; 92 | }; 93 | 94 | extern void proxy_activate (ProxySocket *); 95 | 96 | extern int proxy_http_negotiate (ProxySocket *, int); 97 | extern int proxy_telnet_negotiate (ProxySocket *, int); 98 | extern int proxy_socks4_negotiate (ProxySocket *, int); 99 | extern int proxy_socks5_negotiate (ProxySocket *, int); 100 | 101 | /* 102 | * This may be reused by local-command proxies on individual 103 | * platforms. 104 | */ 105 | char *format_telnet_command(SockAddr addr, int port, Conf *conf); 106 | 107 | /* 108 | * These are implemented in cproxy.c or nocproxy.c, depending on 109 | * whether encrypted proxy authentication is available. 110 | */ 111 | extern void proxy_socks5_offerencryptedauth(BinarySink *); 112 | extern int proxy_socks5_handlechap (ProxySocket *); 113 | extern int proxy_socks5_selectchap(ProxySocket *); 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /contrib/gdb.py: -------------------------------------------------------------------------------- 1 | import gdb 2 | import re 3 | import gdb.printing 4 | 5 | class PuTTYBignumPrettyPrinter(gdb.printing.PrettyPrinter): 6 | "Pretty-print PuTTY's Bignum type." 7 | name = "Bignum" 8 | 9 | def __init__(self, val): 10 | super(PuTTYBignumPrettyPrinter, self).__init__(self.name) 11 | self.val = val 12 | 13 | def to_string(self): 14 | type_BignumInt = gdb.lookup_type("BignumInt") 15 | type_BignumIntPtr = type_BignumInt.pointer() 16 | BIGNUM_INT_BITS = 8 * type_BignumInt.sizeof 17 | array = self.val.cast(type_BignumIntPtr) 18 | aget = lambda i: int(array[i]) & ((1 << BIGNUM_INT_BITS)-1) 19 | 20 | try: 21 | length = aget(0) 22 | value = 0 23 | for i in range(length): 24 | value |= aget(i+1) << (BIGNUM_INT_BITS * i) 25 | return "Bignum({:#x})".format(value) 26 | 27 | except gdb.MemoryError: 28 | address = int(array) 29 | if address == 0: 30 | return "Bignum(NULL)".format(address) 31 | return "Bignum(invalid @ {:#x})".format(address) 32 | 33 | rcpp = gdb.printing.RegexpCollectionPrettyPrinter("PuTTY") 34 | rcpp.add_printer(PuTTYBignumPrettyPrinter.name, "^Bignum$", 35 | PuTTYBignumPrettyPrinter) 36 | 37 | gdb.printing.register_pretty_printer(None, rcpp) 38 | 39 | class MemDumpCommand(gdb.Command): 40 | """Print a hex+ASCII dump of object EXP. 41 | 42 | EXP must be an expression whose value resides in memory. The 43 | contents of the memory it occupies are printed in a standard hex 44 | dump format, with each line showing an offset relative to the 45 | address of EXP, then the hex byte values of the memory at that 46 | offset, and then a translation into ASCII of the same bytes (with 47 | values outside the printable ASCII range translated as '.'). 48 | 49 | To dump a number of bytes from a particular address, it's useful 50 | to use the gdb expression extensions {TYPE} and @LENGTH. For 51 | example, if 'ptr' and 'len' are variables giving an address and a 52 | length in bytes, then the command 53 | 54 | memdump {char} ptr @ len 55 | 56 | will dump the range of memory described by those two variables.""" 57 | 58 | def __init__(self): 59 | super(MemDumpCommand, self).__init__( 60 | "memdump", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION) 61 | 62 | def invoke(self, cmdline, from_tty): 63 | expr = gdb.parse_and_eval(cmdline) 64 | try: 65 | start, size = int(expr.address), expr.type.sizeof 66 | except gdb.error as e: 67 | sys.stderr.write(str(e)) 68 | return 69 | except (TypeError, AttributeError): 70 | sys.stderr.write("expression must identify an object in memory") 71 | return 72 | 73 | width = 16 74 | line_ptr_type = gdb.lookup_type( 75 | "unsigned char").const().array(width).pointer() 76 | 77 | dumpaddr = 0 78 | while size > 0: 79 | line = gdb.Value(start).cast(line_ptr_type).dereference() 80 | thislinelen = min(size, width) 81 | start += thislinelen 82 | size -= thislinelen 83 | 84 | dumpline = [None, " "] + [" "] * width + [" "] + [""] * width 85 | 86 | dumpline[0] = "{:08x}".format(dumpaddr) 87 | dumpaddr += thislinelen 88 | 89 | for i in range(thislinelen): 90 | ch = int(line[i]) & 0xFF 91 | dumpline[2+i] = " {:02x}".format(ch) 92 | dumpline[3+width+i] = chr(ch) if 0x20 <= ch < 0x7F else "." 93 | 94 | sys.stdout.write("".join(dumpline) + "\n") 95 | 96 | MemDumpCommand() 97 | -------------------------------------------------------------------------------- /rdb/pickscript: -------------------------------------------------------------------------------- 1 | set -e 2 | P=`pwd` 3 | 4 | TMP=/tmp/picker 5 | G="$TMP.git" 6 | S="$TMP.safe" 7 | rm -rf "$G" ||: 8 | rm -rf "$S" ||: 9 | 10 | mkdir "$G" "$S" 11 | 12 | cd "$G" 13 | git init 14 | git fetch "$P" origin/master:temp 15 | 16 | next_commit() { 17 | git checkout $1 18 | cp -a * "$S"/. 19 | 20 | git checkout picker 21 | 22 | rm -rf * 23 | mv "$S"/* . 24 | git add -A 25 | git commit -a --allow-empty -m "Hashes $PREV..$1" 26 | 27 | PREV="$1" 28 | } 29 | 30 | PREV=49ff9f4 31 | git checkout -f -B picker $PREV 32 | 33 | next_commit 976e778 34 | next_commit 7658b29 35 | next_commit ad994ba 36 | next_commit 1840103 37 | next_commit 097d5ff 38 | next_commit dc253b3 39 | next_commit 0afc496 40 | next_commit 1e0e962 41 | next_commit bb68baf 42 | next_commit 11eb75a 43 | next_commit e88b8d2 44 | next_commit 7524da6 45 | next_commit 0de1ac9 46 | next_commit a50da0e 47 | next_commit b62af0f 48 | next_commit 6744387 49 | next_commit 30e63c1 50 | next_commit fd7687a 51 | next_commit 82824e1 52 | next_commit b08895f 53 | next_commit 43be90e 54 | next_commit 5f6e443 55 | next_commit bea758a 56 | next_commit 342f287 57 | next_commit 13edf90 58 | next_commit 5c5ca11 59 | next_commit e162810 60 | next_commit 64ec5e0 61 | next_commit 06cf210 62 | next_commit 2496760 63 | next_commit 5a9711a 64 | next_commit e0252a4 65 | next_commit 1489299 66 | next_commit 7c2ea22 67 | next_commit 5133d2a 68 | next_commit 5bb3334 69 | next_commit 0f759e4 70 | next_commit 4df5d56 71 | next_commit 431f8db 72 | next_commit 854fae8 73 | next_commit 3c7557d 74 | next_commit 777f38e 75 | next_commit 9458377 76 | next_commit 81152e5 77 | next_commit 9a3b743 78 | next_commit 46b7cb6 79 | next_commit 291cbfc 80 | next_commit 612534a 81 | next_commit 10d3b73 82 | next_commit 1bdeff7 83 | next_commit acff0a6 84 | next_commit 675a5ba 85 | next_commit df006f3 86 | next_commit c01dff3 87 | next_commit 9f9d72e 88 | next_commit 9dd9860 89 | next_commit 48eafd6 90 | next_commit 758ac4c 91 | next_commit 323c3c7 92 | next_commit 557a99e 93 | next_commit 1f7f422 94 | next_commit 3dfb9ac 95 | next_commit d4e5b0d 96 | next_commit d61c6ca 97 | next_commit f594450 98 | next_commit 417421c 99 | next_commit 0eb3bf0 100 | next_commit 1446476 101 | next_commit eb319f9 102 | next_commit a063e52 103 | next_commit 43865aa 104 | next_commit aaeaae0 105 | next_commit 6c04165 106 | next_commit 4252cdb 107 | next_commit 8c803e7 108 | next_commit a815c3a 109 | next_commit 31c5784 110 | next_commit fbea11f 111 | next_commit 5c76a93 112 | next_commit 9c8a3cb 113 | next_commit 3a43bec 114 | next_commit e170041 115 | next_commit c445c74 116 | next_commit f7365a2 117 | next_commit 6056396 118 | next_commit 5936c55 119 | next_commit 72b659c 120 | next_commit 98c9469 121 | next_commit 7552ddb 122 | next_commit 986b8f8 123 | next_commit 07af4ed 124 | next_commit 503061e 125 | next_commit 1a009ab 126 | next_commit e3fe709 127 | next_commit f69b371 128 | next_commit 63b47ed 129 | next_commit 7707aa2 130 | next_commit c0e19ca 131 | next_commit 4f34059 132 | next_commit 19d1ad3 133 | next_commit b94a076 134 | next_commit 0629f1d 135 | next_commit 5171dcb 136 | next_commit 7924aa9 137 | next_commit 389eb4b 138 | next_commit b9cb75e 139 | next_commit f6b81af 140 | next_commit 1d20c1b 141 | next_commit 5471539 142 | next_commit af1460d 143 | next_commit 12702cb 144 | next_commit 7a5cb28 145 | next_commit 9022dcd 146 | next_commit 6627c1c 147 | next_commit fe16b57 148 | next_commit f14382c 149 | next_commit 3552f37 150 | next_commit f3230c8 151 | next_commit b003e5c 152 | next_commit 222c134 153 | next_commit a454399 154 | next_commit fa7b23c 155 | next_commit 5815d6a 156 | next_commit 5b7833c 157 | next_commit f08e2de 158 | next_commit 3e811b3 159 | next_commit 470337d 160 | -------------------------------------------------------------------------------- /callback.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Facility for queueing callback functions to be run from the 3 | * top-level event loop after the current top-level activity finishes. 4 | */ 5 | 6 | #include 7 | 8 | #include "putty.h" 9 | 10 | struct callback { 11 | struct callback *next; 12 | 13 | toplevel_callback_fn_t fn; 14 | void *ctx; 15 | }; 16 | 17 | struct callback *cbcurr = NULL, *cbhead = NULL, *cbtail = NULL; 18 | 19 | toplevel_callback_notify_fn_t notify_frontend = NULL; 20 | void *frontend = NULL; 21 | 22 | void request_callback_notifications(toplevel_callback_notify_fn_t fn, 23 | void *fr) 24 | { 25 | notify_frontend = fn; 26 | frontend = fr; 27 | } 28 | 29 | static void run_idempotent_callback(void *ctx) 30 | { 31 | struct IdempotentCallback *ic = (struct IdempotentCallback *)ctx; 32 | ic->queued = FALSE; 33 | ic->fn(ic->ctx); 34 | } 35 | 36 | void queue_idempotent_callback(struct IdempotentCallback *ic) 37 | { 38 | if (ic->queued) 39 | return; 40 | ic->queued = TRUE; 41 | queue_toplevel_callback(run_idempotent_callback, ic); 42 | } 43 | 44 | void delete_callbacks_for_context(void *ctx) 45 | { 46 | struct callback *newhead, *newtail; 47 | 48 | newhead = newtail = NULL; 49 | while (cbhead) { 50 | struct callback *cb = cbhead; 51 | cbhead = cbhead->next; 52 | if (cb->ctx == ctx || 53 | (cb->fn == run_idempotent_callback && 54 | ((struct IdempotentCallback *)cb->ctx)->ctx == ctx)) { 55 | sfree(cb); 56 | } else { 57 | if (!newhead) 58 | newhead = cb; 59 | else 60 | newtail->next = cb; 61 | 62 | newtail = cb; 63 | } 64 | } 65 | 66 | cbhead = newhead; 67 | cbtail = newtail; 68 | } 69 | 70 | void queue_toplevel_callback(toplevel_callback_fn_t fn, void *ctx) 71 | { 72 | struct callback *cb; 73 | 74 | cb = snew(struct callback); 75 | cb->fn = fn; 76 | cb->ctx = ctx; 77 | 78 | /* 79 | * If the front end has requested notification of pending 80 | * callbacks, and we didn't already have one queued, let it know 81 | * we do have one now. 82 | * 83 | * If cbcurr is non-NULL, i.e. we are actually in the middle of 84 | * executing a callback right now, then we count that as the queue 85 | * already having been non-empty. That saves the front end getting 86 | * a constant stream of needless re-notifications if the last 87 | * callback keeps re-scheduling itself. 88 | */ 89 | if (notify_frontend && !cbhead && !cbcurr) 90 | notify_frontend(frontend); 91 | 92 | if (cbtail) 93 | cbtail->next = cb; 94 | else 95 | cbhead = cb; 96 | cbtail = cb; 97 | cb->next = NULL; 98 | } 99 | 100 | int run_toplevel_callbacks(void) 101 | { 102 | int done_something = FALSE; 103 | 104 | if (cbhead) { 105 | /* 106 | * Transfer the head callback into cbcurr to indicate that 107 | * it's being executed. Then operations which transform the 108 | * queue, like delete_callbacks_for_context, can proceed as if 109 | * it's not there. 110 | */ 111 | cbcurr = cbhead; 112 | cbhead = cbhead->next; 113 | if (!cbhead) 114 | cbtail = NULL; 115 | 116 | /* 117 | * Now run the callback, and then clear it out of cbcurr. 118 | */ 119 | cbcurr->fn(cbcurr->ctx); 120 | sfree(cbcurr); 121 | cbcurr = NULL; 122 | 123 | done_something = TRUE; 124 | } 125 | return done_something; 126 | } 127 | 128 | int toplevel_callback_pending(void) 129 | { 130 | return cbcurr != NULL || cbhead != NULL; 131 | } 132 | -------------------------------------------------------------------------------- /windows/winhelp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * winhelp.c: centralised functions to launch Windows help files, 3 | * and to decide whether to use .HLP or .CHM help in any given 4 | * situation. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "putty.h" 13 | 14 | #ifndef NO_HTMLHELP 15 | #include 16 | #endif /* NO_HTMLHELP */ 17 | 18 | static int requested_help; 19 | static char *help_path; 20 | static int help_has_contents; 21 | #ifndef NO_HTMLHELP 22 | DECL_WINDOWS_FUNCTION(static, HWND, HtmlHelpA, (HWND, LPCSTR, UINT, DWORD_PTR)); 23 | static char *chm_path; 24 | #endif /* NO_HTMLHELP */ 25 | 26 | void init_help(void) 27 | { 28 | char b[2048], *p, *q, *r; 29 | FILE *fp; 30 | 31 | GetModuleFileName(NULL, b, sizeof(b) - 1); 32 | r = b; 33 | p = strrchr(b, '\\'); 34 | if (p && p >= r) r = p+1; 35 | q = strrchr(b, ':'); 36 | if (q && q >= r) r = q+1; 37 | strcpy(r, PUTTY_HELP_FILE); 38 | if ( (fp = fopen(b, "r")) != NULL) { 39 | help_path = dupstr(b); 40 | fclose(fp); 41 | } else 42 | help_path = NULL; 43 | strcpy(r, PUTTY_HELP_CONTENTS); 44 | if ( (fp = fopen(b, "r")) != NULL) { 45 | help_has_contents = TRUE; 46 | fclose(fp); 47 | } else 48 | help_has_contents = FALSE; 49 | 50 | #ifndef NO_HTMLHELP 51 | strcpy(r, PUTTY_CHM_FILE); 52 | if ( (fp = fopen(b, "r")) != NULL) { 53 | chm_path = dupstr(b); 54 | fclose(fp); 55 | } else 56 | chm_path = NULL; 57 | if (chm_path) { 58 | HINSTANCE dllHH = load_system32_dll("hhctrl.ocx"); 59 | GET_WINDOWS_FUNCTION(dllHH, HtmlHelpA); 60 | if (!p_HtmlHelpA) { 61 | sfree(chm_path); 62 | chm_path = NULL; 63 | if (dllHH) 64 | FreeLibrary(dllHH); 65 | } 66 | } 67 | #endif /* NO_HTMLHELP */ 68 | } 69 | 70 | void shutdown_help(void) 71 | { 72 | /* Nothing to do currently. 73 | * (If we were running HTML Help single-threaded, this is where we'd 74 | * call HH_UNINITIALIZE.) */ 75 | } 76 | 77 | int has_help(void) 78 | { 79 | /* 80 | * FIXME: it would be nice here to disregard help_path on 81 | * platforms that didn't have WINHLP32. But that's probably 82 | * unrealistic, since even Vista will have it if the user 83 | * specifically downloads it. 84 | */ 85 | return (help_path != NULL 86 | #ifndef NO_HTMLHELP 87 | || chm_path 88 | #endif /* NO_HTMLHELP */ 89 | ); 90 | } 91 | 92 | void launch_help(HWND hwnd, const char *topic) 93 | { 94 | if (topic) { 95 | int colonpos = strcspn(topic, ":"); 96 | 97 | #ifndef NO_HTMLHELP 98 | if (chm_path) { 99 | char *fname; 100 | assert(topic[colonpos] != '\0'); 101 | fname = dupprintf("%s::/%s.html>main", chm_path, 102 | topic + colonpos + 1); 103 | p_HtmlHelpA(hwnd, fname, HH_DISPLAY_TOPIC, 0); 104 | sfree(fname); 105 | } else 106 | #endif /* NO_HTMLHELP */ 107 | if (help_path) { 108 | char *cmd = dupprintf("JI(`',`%.*s')", colonpos, topic); 109 | WinHelp(hwnd, help_path, HELP_COMMAND, (ULONG_PTR)cmd); 110 | sfree(cmd); 111 | } 112 | } else { 113 | #ifndef NO_HTMLHELP 114 | if (chm_path) { 115 | p_HtmlHelpA(hwnd, chm_path, HH_DISPLAY_TOPIC, 0); 116 | } else 117 | #endif /* NO_HTMLHELP */ 118 | if (help_path) { 119 | WinHelp(hwnd, help_path, 120 | help_has_contents ? HELP_FINDER : HELP_CONTENTS, 0); 121 | } 122 | } 123 | requested_help = TRUE; 124 | } 125 | 126 | void quit_help(HWND hwnd) 127 | { 128 | if (requested_help) { 129 | #ifndef NO_HTMLHELP 130 | if (chm_path) { 131 | p_HtmlHelpA(NULL, NULL, HH_CLOSE_ALL, 0); 132 | } else 133 | #endif /* NO_HTMLHELP */ 134 | if (help_path) { 135 | WinHelp(hwnd, help_path, HELP_QUIT, 0); 136 | } 137 | requested_help = FALSE; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /be_misc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * be_misc.c: helper functions shared between main network backends. 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | #define DEFINE_PLUG_METHOD_MACROS 9 | #include "putty.h" 10 | #include "network.h" 11 | 12 | void backend_socket_log(void *frontend, int type, SockAddr addr, int port, 13 | const char *error_msg, int error_code, Conf *conf, 14 | int session_started) 15 | { 16 | char addrbuf[256], *msg; 17 | 18 | switch (type) { 19 | case 0: 20 | sk_getaddr(addr, addrbuf, lenof(addrbuf)); 21 | if (sk_addr_needs_port(addr)) { 22 | msg = dupprintf("Connecting to %s port %d", addrbuf, port); 23 | } else { 24 | msg = dupprintf("Connecting to %s", addrbuf); 25 | } 26 | break; 27 | case 1: 28 | sk_getaddr(addr, addrbuf, lenof(addrbuf)); 29 | msg = dupprintf("Failed to connect to %s: %s", addrbuf, error_msg); 30 | break; 31 | case 2: 32 | /* Proxy-related log messages have their own identifying 33 | * prefix already, put on by our caller. */ 34 | { 35 | int len, log_to_term; 36 | 37 | /* Suffix \r\n temporarily, so we can log to the terminal. */ 38 | msg = dupprintf("%s\r\n", error_msg); 39 | len = strlen(msg); 40 | assert(len >= 2); 41 | 42 | log_to_term = conf_get_int(conf, CONF_proxy_log_to_term); 43 | if (log_to_term == AUTO) 44 | log_to_term = session_started ? FORCE_OFF : FORCE_ON; 45 | if (log_to_term == FORCE_ON) 46 | from_backend(frontend, TRUE, msg, len); 47 | 48 | msg[len-2] = '\0'; /* remove the \r\n again */ 49 | } 50 | break; 51 | default: 52 | msg = NULL; /* shouldn't happen, but placate optimiser */ 53 | break; 54 | } 55 | 56 | if (msg) { 57 | logevent(frontend, msg); 58 | sfree(msg); 59 | } 60 | } 61 | 62 | void log_proxy_stderr(Plug plug, bufchain *buf, const void *vdata, int len) 63 | { 64 | const char *data = (const char *)vdata; 65 | int pos = 0; 66 | int msglen; 67 | const char *nlpos; 68 | char *msg, *fullmsg; 69 | 70 | /* 71 | * This helper function allows us to collect the data written to a 72 | * local proxy command's standard error in whatever size chunks we 73 | * happen to get from its pipe, and whenever we have a complete 74 | * line, we pass it to plug_log. 75 | * 76 | * Prerequisites: a plug to log to, and a bufchain stored 77 | * somewhere to collect the data in. 78 | */ 79 | 80 | while (pos < len && (nlpos = memchr(data+pos, '\n', len-pos)) != NULL) { 81 | /* 82 | * Found a newline in the current input buffer. Append it to 83 | * the bufchain (which may contain a partial line from last 84 | * time). 85 | */ 86 | bufchain_add(buf, data + pos, nlpos - (data + pos)); 87 | 88 | /* 89 | * Collect the resulting line of data and pass it to plug_log. 90 | */ 91 | msglen = bufchain_size(buf); 92 | msg = snewn(msglen+1, char); 93 | bufchain_fetch(buf, msg, msglen); 94 | bufchain_consume(buf, msglen); 95 | msg[msglen] = '\0'; 96 | fullmsg = dupprintf("proxy: %s", msg); 97 | plug_log(plug, 2, NULL, 0, fullmsg, 0); 98 | sfree(fullmsg); 99 | sfree(msg); 100 | 101 | /* 102 | * Advance past the newline. 103 | */ 104 | pos += nlpos+1 - (data + pos); 105 | } 106 | 107 | /* 108 | * Now any remaining data is a partial line, which we save for 109 | * next time. 110 | */ 111 | bufchain_add(buf, data + pos, len - pos); 112 | } 113 | -------------------------------------------------------------------------------- /unix/uxnoise.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Noise generation for PuTTY's cryptographic random number 3 | * generator. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "putty.h" 16 | #include "ssh.h" 17 | #include "storage.h" 18 | 19 | static int read_dev_urandom(char *buf, int len) 20 | { 21 | int fd; 22 | int ngot, ret; 23 | 24 | fd = open("/dev/urandom", O_RDONLY); 25 | if (fd < 0) 26 | return 0; 27 | 28 | ngot = 0; 29 | while (ngot < len) { 30 | ret = read(fd, buf+ngot, len-ngot); 31 | if (ret < 0) { 32 | close(fd); 33 | return 0; 34 | } 35 | ngot += ret; 36 | } 37 | 38 | close(fd); 39 | 40 | return 1; 41 | } 42 | 43 | /* 44 | * This function is called once, at PuTTY startup. It will do some 45 | * slightly silly things such as fetching an entire process listing 46 | * and scanning /tmp, load the saved random seed from disk, and 47 | * also read 32 bytes out of /dev/urandom. 48 | */ 49 | 50 | void noise_get_heavy(void (*func) (void *, int)) 51 | { 52 | char buf[512]; 53 | FILE *fp; 54 | int ret; 55 | int got_dev_urandom = 0; 56 | 57 | if (read_dev_urandom(buf, 32)) { 58 | got_dev_urandom = 1; 59 | func(buf, 32); 60 | } 61 | 62 | fp = popen("ps -axu 2>/dev/null", "r"); 63 | if (fp) { 64 | while ( (ret = fread(buf, 1, sizeof(buf), fp)) > 0) 65 | func(buf, ret); 66 | pclose(fp); 67 | } else if (!got_dev_urandom) { 68 | fprintf(stderr, "popen: %s\n" 69 | "Unable to access fallback entropy source\n", strerror(errno)); 70 | exit(1); 71 | } 72 | 73 | fp = popen("ls -al /tmp 2>/dev/null", "r"); 74 | if (fp) { 75 | while ( (ret = fread(buf, 1, sizeof(buf), fp)) > 0) 76 | func(buf, ret); 77 | pclose(fp); 78 | } else if (!got_dev_urandom) { 79 | fprintf(stderr, "popen: %s\n" 80 | "Unable to access fallback entropy source\n", strerror(errno)); 81 | exit(1); 82 | } 83 | 84 | read_random_seed(func); 85 | random_save_seed(); 86 | } 87 | 88 | void random_save_seed(void) 89 | { 90 | int len; 91 | void *data; 92 | 93 | if (random_active) { 94 | random_get_savedata(&data, &len); 95 | write_random_seed(data, len); 96 | sfree(data); 97 | } 98 | } 99 | 100 | /* 101 | * This function is called every time the random pool needs 102 | * stirring, and will acquire the system time. 103 | */ 104 | void noise_get_light(void (*func) (void *, int)) 105 | { 106 | struct timeval tv; 107 | gettimeofday(&tv, NULL); 108 | func(&tv, sizeof(tv)); 109 | } 110 | 111 | /* 112 | * This function is called on a timer, and grabs as much changeable 113 | * system data as it can quickly get its hands on. 114 | */ 115 | void noise_regular(void) 116 | { 117 | int fd; 118 | int ret; 119 | char buf[512]; 120 | struct rusage rusage; 121 | 122 | if ((fd = open("/proc/meminfo", O_RDONLY)) >= 0) { 123 | while ( (ret = read(fd, buf, sizeof(buf))) > 0) 124 | random_add_noise(buf, ret); 125 | close(fd); 126 | } 127 | if ((fd = open("/proc/stat", O_RDONLY)) >= 0) { 128 | while ( (ret = read(fd, buf, sizeof(buf))) > 0) 129 | random_add_noise(buf, ret); 130 | close(fd); 131 | } 132 | getrusage(RUSAGE_SELF, &rusage); 133 | random_add_noise(&rusage, sizeof(rusage)); 134 | } 135 | 136 | /* 137 | * This function is called on every keypress or mouse move, and 138 | * will add the current time to the noise pool. It gets the scan 139 | * code or mouse position passed in, and adds that too. 140 | */ 141 | void noise_ultralight(unsigned long data) 142 | { 143 | struct timeval tv; 144 | gettimeofday(&tv, NULL); 145 | random_add_noise(&tv, sizeof(tv)); 146 | random_add_noise(&data, sizeof(data)); 147 | } 148 | --------------------------------------------------------------------------------