* 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 \
struct sesslist {
int nsessions;
- char **sessions;
+ const char **sessions;
char *buffer; /* so memory can be freed later */
};
/* 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 {
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)
CIPHER_AES, /* (SSH-2 only) */
CIPHER_DES,
CIPHER_ARCFOUR,
+ CIPHER_CHACHA20,
CIPHER_MAX /* no. ciphers (inc warn) */
};
* 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
};
* Proxy types.
*/
PROXY_NONE, PROXY_SOCKS4, PROXY_SOCKS5,
- PROXY_HTTP, PROXY_TELNET, PROXY_CMD
+ PROXY_HTTP, PROXY_TELNET, PROXY_CMD, PROXY_FUZZ
};
enum {
* Two fields which define a string and enum value to be
* equivalent to each other.
*/
- char *s;
+ const char *s;
int v;
/*
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);
*/
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;
};
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 nonfatal(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)
* 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);
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);
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) \
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) */ \
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 */ \
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) \
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) \
/* \
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);
/*
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);
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,
unsigned downstream_id, const char *additional_log_text);
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.
/*
* Exports from version.c.
*/
-extern char ver[];
+extern const char ver[];
/*
* Exports from unicode.c.
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);
/*
* 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);
/*
* 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:
*
* 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);
* 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.
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.
void expire_timer_context(void *ctx);
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.