X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=putty.h;h=fd2d0250650ca7268d48ecf72b6657c376f36a24;hb=510f49e405e71ba5c97875e7a019364e1ef5fac9;hp=bc400fb2fdde94e01cf433ef9816d3741a5f2424;hpb=71f0c7546dfa8930277c895b88f57585fd8ef854;p=PuTTY.git diff --git a/putty.h b/putty.h index bc400fb2..fd2d0250 100644 --- a/putty.h +++ b/putty.h @@ -31,6 +31,8 @@ typedef struct terminal_tag Terminal; * Fingerprints of the PGP master keys that can be used to establish a trust * path between an executable and other files. */ +#define PGP_MASTER_KEY_FP \ + "440D E3B5 B7A1 CA85 B3CC 1718 AB58 5DC6 0467 6F7C" #define PGP_RSA_MASTER_KEY_FP \ "8F 15 97 DA 25 30 AB 0D 88 D1 92 54 11 CF 0C 4C" #define PGP_DSA_MASTER_KEY_FP \ @@ -139,7 +141,7 @@ typedef struct terminal_tag Terminal; struct sesslist { int nsessions; - char **sessions; + const char **sessions; char *buffer; /* so memory can be freed later */ }; @@ -180,7 +182,14 @@ typedef enum { /* Pseudo-specials used for constructing the specials menu. */ TS_SEP, /* Separator */ TS_SUBMENU, /* Start a new submenu with specified name */ - TS_EXITMENU /* Exit current submenu or end of specials */ + TS_EXITMENU, /* Exit current submenu or end of specials */ + /* Starting point for protocols to invent special-action codes + * that can't live in this enum at all, e.g. because they change + * with every session. + * + * Of course, this must remain the last value in this + * enumeration. */ + TS_LOCALSTART } Telnet_Special; struct telnet_special { @@ -253,9 +262,22 @@ enum { KEX_DHGROUP14, KEX_DHGEX, KEX_RSA, + KEX_ECDH, KEX_MAX }; +enum { + /* + * SSH-2 host key algorithms + */ + HK_WARN, + HK_RSA, + HK_DSA, + HK_ECDSA, + HK_ED25519, + HK_MAX +}; + enum { /* * SSH ciphers (both SSH-1 and SSH-2) @@ -266,6 +288,7 @@ enum { CIPHER_AES, /* (SSH-2 only) */ CIPHER_DES, CIPHER_ARCFOUR, + CIPHER_CHACHA20, CIPHER_MAX /* no. ciphers (inc warn) */ }; @@ -275,9 +298,9 @@ enum { * three-way settings whose values are `always yes', `always * no', and `decide by some more complex automated means'. This * is true of line discipline options (local echo and line - * editing), proxy DNS, Close On Exit, and SSH server bug - * workarounds. Accordingly I supply a single enum here to deal - * with them all. + * editing), proxy DNS, proxy terminal logging, Close On Exit, and + * SSH server bug workarounds. Accordingly I supply a single enum + * here to deal with them all. */ FORCE_ON, FORCE_OFF, AUTO }; @@ -287,7 +310,7 @@ enum { * Proxy types. */ PROXY_NONE, PROXY_SOCKS4, PROXY_SOCKS5, - PROXY_HTTP, PROXY_TELNET, PROXY_CMD + PROXY_HTTP, PROXY_TELNET, PROXY_CMD, PROXY_FUZZ }; enum { @@ -358,7 +381,7 @@ struct keyvalwhere { * Two fields which define a string and enum value to be * equivalent to each other. */ - char *s; + const char *s; int v; /* @@ -415,13 +438,13 @@ enum { struct backend_tag { const char *(*init) (void *frontend_handle, void **backend_handle, - Conf *conf, char *host, int port, char **realhost, - int nodelay, int keepalive); + Conf *conf, const char *host, int port, + char **realhost, int nodelay, int keepalive); void (*free) (void *handle); /* back->reconfig() passes in a replacement configuration. */ void (*reconfig) (void *handle, Conf *conf); /* back->send() returns the current amount of buffered data. */ - int (*send) (void *handle, char *buf, int len); + int (*send) (void *handle, const char *buf, int len); /* back->sendbuffer() does the same thing but without attempting a send */ int (*sendbuffer) (void *handle); void (*size) (void *handle, int width, int height); @@ -441,7 +464,10 @@ struct backend_tag { */ void (*unthrottle) (void *handle, int); int (*cfg_info) (void *handle); - char *name; + /* Only implemented in the SSH protocol: check whether a + * connection-sharing upstream exists for a given configuration. */ + int (*test_for_upstream)(const char *host, int port, Conf *conf); + const char *name; int protocol; int default_port; }; @@ -588,9 +614,10 @@ void write_clip(void *frontend, wchar_t *, int *, int, int); void get_clip(void *frontend, wchar_t **, int *); void optimised_move(void *frontend, int, int, int); void set_raw_mouse_mode(void *frontend, int); -void connection_fatal(void *frontend, char *, ...); -void fatalbox(char *, ...); -void modalfatalbox(char *, ...); +void connection_fatal(void *frontend, const char *, ...); +void nonfatal(const char *, ...); +void fatalbox(const char *, ...); +void modalfatalbox(const char *, ...); #ifdef macintosh #pragma noreturn(fatalbox) #pragma noreturn(modalfatalbox) @@ -600,7 +627,7 @@ void begin_session(void *frontend); void sys_cursor(void *frontend, int x, int y); void request_paste(void *frontend); void frontend_keypress(void *frontend); -void ldisc_update(void *frontend, int echo, int edit); +void frontend_echoedit_update(void *frontend, int echo, int edit); /* It's the backend's responsibility to invoke this at the start of a * connection, if necessary; it can also invoke it later if the set of * special commands changes. It does not need to invoke it at session @@ -622,7 +649,7 @@ char *get_ttymode(void *frontend, const char *mode); * 0 = `user cancelled' (FIXME distinguish "give up entirely" and "next auth"?) * <0 = `please call back later with more in/inlen' */ -int get_userpass_input(prompts_t *p, unsigned char *in, int inlen); +int get_userpass_input(prompts_t *p, const unsigned char *in, int inlen); #define OPTIMISE_IS_SCROLL 1 void set_iconic(void *frontend, int iconic); @@ -644,6 +671,7 @@ enum { BUSY_CPU /* Locally busy (e.g. crypto); user interaction suspended */ }; void set_busy_status(void *frontend, int status); +int frontend_is_utf8(void *frontend); void cleanup_exit(int); @@ -673,12 +701,14 @@ void cleanup_exit(int); X(STR, NONE, proxy_username) \ X(STR, NONE, proxy_password) \ X(STR, NONE, proxy_telnet_command) \ + X(INT, NONE, proxy_log_to_term) \ /* SSH options */ \ X(STR, NONE, remote_cmd) \ X(STR, NONE, remote_cmd2) /* fallback if remote_cmd fails; never loaded or saved */ \ X(INT, NONE, nopty) \ X(INT, NONE, compression) \ X(INT, INT, ssh_kexlist) \ + X(INT, INT, ssh_hklist) \ X(INT, NONE, ssh_rekey_time) /* in minutes */ \ X(STR, NONE, ssh_rekey_data) /* string encoding e.g. "100K", "2M", "1G" */ \ X(INT, NONE, tryagent) \ @@ -686,7 +716,20 @@ void cleanup_exit(int); X(INT, NONE, change_username) /* allow username switching in SSH-2 */ \ X(INT, INT, ssh_cipherlist) \ X(FILENAME, NONE, keyfile) \ - X(INT, NONE, sshprot) /* use v1 or v2 when both available */ \ + /* \ + * Which SSH protocol to use. \ + * For historical reasons, the current legal values for CONF_sshprot \ + * are: \ + * 0 = SSH-1 only \ + * 3 = SSH-2 only \ + * We used to also support \ + * 1 = SSH-1 with fallback to SSH-2 \ + * 2 = SSH-2 with fallback to SSH-1 \ + * and we continue to use 0/3 in storage formats rather than the more \ + * obvious 1/2 to avoid surprises if someone saves a session and later \ + * downgrades PuTTY. So it's easier to use these numbers internally too. \ + */ \ + X(INT, NONE, sshprot) \ X(INT, NONE, ssh2_des_cbc) /* "des-cbc" unrecommended SSH-2 cipher */ \ X(INT, NONE, ssh_no_userauth) /* bypass "ssh-userauth" (SSH-2 only) */ \ X(INT, NONE, ssh_show_banner) /* show USERAUTH_BANNERs (SSH-2 only) */ \ @@ -728,6 +771,7 @@ void cleanup_exit(int); X(INT, NONE, no_remote_resize) /* disable remote resizing */ \ X(INT, NONE, no_alt_screen) /* disable alternate screen */ \ X(INT, NONE, no_remote_wintitle) /* disable remote retitling */ \ + X(INT, NONE, no_remote_clearscroll) /* disable ESC[3J */ \ X(INT, NONE, no_dbackspace) /* disable destructive backspace */ \ X(INT, NONE, no_remote_charset) /* disable remote charset config */ \ X(INT, NONE, remote_qtitle_action) /* remote win title query action */ \ @@ -748,6 +792,8 @@ void cleanup_exit(int); X(INT, NONE, erase_to_scrollback) \ X(INT, NONE, compose_key) \ X(INT, NONE, ctrlaltkeys) \ + X(INT, NONE, osx_option_meta) \ + X(INT, NONE, osx_command_meta) \ X(STR, NONE, wintitle) /* initial window title */ \ /* Terminal options */ \ X(INT, NONE, savelines) \ @@ -836,13 +882,24 @@ void cleanup_exit(int); X(INT, NONE, sshbug_rekey2) \ X(INT, NONE, sshbug_maxpkt2) \ X(INT, NONE, sshbug_ignore2) \ + X(INT, NONE, sshbug_oldgex2) \ X(INT, NONE, sshbug_winadj) \ + X(INT, NONE, sshbug_chanreq) \ /* \ * ssh_simple means that we promise never to open any channel \ * other than the main one, which means it can safely use a very \ * large window in SSH-2. \ */ \ X(INT, NONE, ssh_simple) \ + X(INT, NONE, ssh_connection_sharing) \ + X(INT, NONE, ssh_connection_sharing_upstream) \ + X(INT, NONE, ssh_connection_sharing_downstream) \ + /* + * ssh_manual_hostkeys is conceptually a set rather than a + * dictionary: the string subkeys are the important thing, and the + * actual values to which those subkeys map are all "". + */ \ + X(STR, STR, ssh_manual_hostkeys) \ /* Options for pterm. Should split out into platform-dependent part. */ \ X(INT, NONE, stamp_utmp) \ X(INT, NONE, login_shell) \ @@ -927,12 +984,12 @@ void random_destroy_seed(void); Backend *backend_from_name(const char *name); Backend *backend_from_proto(int proto); char *get_remote_username(Conf *conf); /* dynamically allocated */ -char *save_settings(char *section, Conf *conf); +char *save_settings(const char *section, Conf *conf); void save_open_settings(void *sesskey, Conf *conf); -void load_settings(char *section, Conf *conf); +void load_settings(const char *section, Conf *conf); void load_open_settings(void *sesskey, Conf *conf); void get_sesslist(struct sesslist *, int allocate); -void do_defaults(char *, Conf *); +void do_defaults(const char *, Conf *); void registry_cleanup(void); /* @@ -976,8 +1033,6 @@ void term_update(Terminal *); void term_invalidate(Terminal *); void term_blink(Terminal *, int set_cursor); void term_do_paste(Terminal *); -int term_paste_pending(Terminal *); -void term_paste(Terminal *); void term_nopaste(Terminal *); int term_ldisc(Terminal *, int option); void term_copyall(Terminal *); @@ -992,7 +1047,7 @@ void term_provide_logctx(Terminal *term, void *logctx); void term_set_focus(Terminal *term, int has_focus); char *term_get_ttymode(Terminal *term, const char *mode); int term_get_userpass_input(Terminal *term, prompts_t *p, - unsigned char *in, int inlen); + const unsigned char *in, int inlen); int format_arrow_key(char *buf, Terminal *term, int xkey, int ctrl); @@ -1015,9 +1070,10 @@ struct logblank_t { int type; }; void log_packet(void *logctx, int direction, int type, - char *texttype, const void *data, int len, + const char *texttype, const void *data, int len, int n_blanks, const struct logblank_t *blanks, - const unsigned long *sequence); + const unsigned long *sequence, + unsigned downstream_id, const char *additional_log_text); /* * Exports from testback.c @@ -1055,13 +1111,15 @@ extern Backend ssh_backend; void *ldisc_create(Conf *, Terminal *, Backend *, void *, void *); void ldisc_configure(void *, Conf *); void ldisc_free(void *); -void ldisc_send(void *handle, char *buf, int len, int interactive); +void ldisc_send(void *handle, const char *buf, int len, int interactive); +void ldisc_echoedit_update(void *handle); /* * Exports from ldiscucs.c. */ -void lpage_send(void *, int codepage, char *buf, int len, int interactive); -void luni_send(void *, wchar_t * widebuf, int len, int interactive); +void lpage_send(void *, int codepage, const char *buf, int len, + int interactive); +void luni_send(void *, const wchar_t * widebuf, int len, int interactive); /* * Exports from sshrand.c. @@ -1102,7 +1160,7 @@ void ser_setup_config_box(struct controlbox *b, int midsession, /* * Exports from version.c. */ -extern char ver[]; +extern const char ver[]; /* * Exports from unicode.c. @@ -1115,7 +1173,7 @@ int is_dbcs_leadbyte(int codepage, char byte); int mb_to_wc(int codepage, int flags, const char *mbstr, int mblen, wchar_t *wcstr, int wclen); int wc_to_mb(int codepage, int flags, const wchar_t *wcstr, int wclen, - char *mbstr, int mblen, char *defchr, int *defused, + char *mbstr, int mblen, const char *defchr, int *defused, struct unicode_data *ucsdata); wchar_t xlat_uskbd2cyrllic(int ch); int check_compose(int first, int second); @@ -1143,17 +1201,32 @@ void crypto_wrapup(); /* * Exports from pageantc.c. * - * agent_query returns 1 for here's-a-response, and 0 for query-in- - * progress. In the latter case there will be a call to `callback' - * at some future point, passing callback_ctx as the first + * agent_query returns NULL for here's-a-response, and non-NULL for + * query-in- progress. In the latter case there will be a call to + * `callback' at some future point, passing callback_ctx as the first * parameter and the actual reply data as the second and third. * * The response may be a NULL pointer (in either of the synchronous * or asynchronous cases), which indicates failure to receive a * response. + * + * When the return from agent_query is not NULL, it identifies the + * in-progress query in case it needs to be cancelled. If + * agent_cancel_query is called, then the pending query is destroyed + * and the callback will not be called. (E.g. if you're going to throw + * away the thing you were using as callback_ctx.) + * + * Passing a null pointer as callback forces agent_query to behave + * synchronously, i.e. it will block if necessary, and guarantee to + * return NULL. The wrapper function agent_query_synchronous() makes + * this easier. */ -int agent_query(void *in, int inlen, void **out, int *outlen, - void (*callback)(void *, void *, int), void *callback_ctx); +typedef struct agent_pending_query agent_pending_query; +agent_pending_query *agent_query( + void *in, int inlen, void **out, int *outlen, + void (*callback)(void *, void *, int), void *callback_ctx); +void agent_cancel_query(agent_pending_query *); +void agent_query_synchronous(void *in, int inlen, void **out, int *outlen); int agent_exists(void); /* @@ -1180,14 +1253,26 @@ void pgp_fingerprints(void); * back via the provided function with a result that's either 0 * or +1'. */ -int verify_ssh_host_key(void *frontend, char *host, int port, char *keytype, - char *keystr, char *fingerprint, +int verify_ssh_host_key(void *frontend, char *host, int port, + const char *keytype, char *keystr, char *fingerprint, void (*callback)(void *ctx, int result), void *ctx); /* - * askalg has the same set of return values as verify_ssh_host_key. + * have_ssh_host_key() just returns true if a key of that type is + * already cached and false otherwise. + */ +int have_ssh_host_key(const char *host, int port, const char *keytype); +/* + * askalg and askhk have the same set of return values as + * verify_ssh_host_key. + * + * (askhk is used in the case where we're using a host key below the + * warning threshold because that's all we have cached, but at least + * one acceptable algorithm is available that we don't have cached.) */ int askalg(void *frontend, const char *algtype, const char *algname, void (*callback)(void *ctx, int result), void *ctx); +int askhk(void *frontend, const char *algname, const char *betteralgs, + void (*callback)(void *ctx, int result), void *ctx); /* * askappend can return four values: * @@ -1204,7 +1289,8 @@ int askappend(void *frontend, Filename *filename, * that aren't equivalents to things in windlg.c et al. */ extern int console_batch_mode; -int console_get_userpass_input(prompts_t *p, unsigned char *in, int inlen); +int console_get_userpass_input(prompts_t *p, const unsigned char *in, + int inlen); void console_provide_logctx(void *logctx); int is_interactive(void); @@ -1224,16 +1310,21 @@ void printer_finish_job(printer_job *); * Exports from cmdline.c (and also cmdline_error(), which is * defined differently in various places and required _by_ * cmdline.c). + * + * Note that cmdline_process_param takes a const option string, but a + * writable argument string. That's not a mistake - that's so it can + * zero out password arguments in the hope of not having them show up + * avoidably in Unix 'ps'. */ -int cmdline_process_param(char *, char *, int, Conf *); +int cmdline_process_param(const char *, char *, int, Conf *); void cmdline_run_saved(Conf *); void cmdline_cleanup(void); -int cmdline_get_passwd_input(prompts_t *p, unsigned char *in, int inlen); +int cmdline_get_passwd_input(prompts_t *p, const unsigned char *in, int inlen); #define TOOLTYPE_FILETRANSFER 1 #define TOOLTYPE_NONNETWORK 2 extern int cmdline_tooltype; -void cmdline_error(char *, ...); +void cmdline_error(const char *, ...); /* * Exports from config.c. @@ -1291,7 +1382,8 @@ void filename_free(Filename *fn); int filename_serialise(const Filename *f, void *data); Filename *filename_deserialise(void *data, int maxsize, int *used); char *get_username(void); /* return value needs freeing */ -char *get_random_data(int bytes); /* used in cmdgen.c */ +char *get_random_data(int bytes, const char *device); /* used in cmdgen.c */ +char filename_char_sanitise(char c); /* rewrite special pathname chars */ /* * Exports and imports from timing.c. @@ -1383,11 +1475,42 @@ char *get_random_data(int bytes); /* used in cmdgen.c */ * GETTICKCOUNT() and compare the result with the returned `next' * value to find out how long you have to make your next wait().) */ -typedef void (*timer_fn_t)(void *ctx, long now); -long schedule_timer(int ticks, timer_fn_t fn, void *ctx); +typedef void (*timer_fn_t)(void *ctx, unsigned long now); +unsigned long schedule_timer(int ticks, timer_fn_t fn, void *ctx); void expire_timer_context(void *ctx); -int run_timers(long now, long *next); -void timer_change_notify(long next); +int run_timers(unsigned long now, unsigned long *next); +void timer_change_notify(unsigned long next); +unsigned long timing_last_clock(void); + +/* + * Exports from callback.c. + * + * This provides a method of queuing function calls to be run at the + * earliest convenience from the top-level event loop. Use it if + * you're deep in a nested chain of calls and want to trigger an + * action which will probably lead to your function being re-entered + * recursively if you just call the initiating function the normal + * way. + * + * Most front ends run the queued callbacks by simply calling + * run_toplevel_callbacks() after handling each event in their + * top-level event loop. However, if a front end doesn't have control + * over its own event loop (e.g. because it's using GTK) then it can + * instead request notifications when a callback is available, so that + * it knows to ask its delegate event loop to do the same thing. Also, + * if a front end needs to know whether a callback is pending without + * actually running it (e.g. so as to put a zero timeout on a select() + * call) then it can call toplevel_callback_pending(), which will + * return true if at least one callback is in the queue. + */ +typedef void (*toplevel_callback_fn_t)(void *ctx); +void queue_toplevel_callback(toplevel_callback_fn_t fn, void *ctx); +void run_toplevel_callbacks(void); +int toplevel_callback_pending(void); + +typedef void (*toplevel_callback_notify_fn_t)(void *frontend); +void request_callback_notifications(toplevel_callback_notify_fn_t notify, + void *frontend); /* * Define no-op macros for the jump list functions, on platforms that @@ -1401,12 +1524,14 @@ void timer_change_notify(long next); #endif /* SURROGATE PAIR */ -#ifndef IS_HIGH_SURROGATE #define HIGH_SURROGATE_START 0xd800 #define HIGH_SURROGATE_END 0xdbff #define LOW_SURROGATE_START 0xdc00 #define LOW_SURROGATE_END 0xdfff +/* These macros exist in the Windows API, so the environment may + * provide them. If not, define them in terms of the above. */ +#ifndef IS_HIGH_SURROGATE #define IS_HIGH_SURROGATE(wch) (((wch) >= HIGH_SURROGATE_START) && \ ((wch) <= HIGH_SURROGATE_END)) #define IS_LOW_SURROGATE(wch) (((wch) >= LOW_SURROGATE_START) && \