Merge branch 'master' of https://github.com/openssh/openssh-portable into latestw
This commit is contained in:
commit
6fba3a2ae9
|
@ -26,6 +26,8 @@ ssh-keyscan
|
|||
ssh-keysign
|
||||
ssh-pkcs11-helper
|
||||
sshd
|
||||
!regress/misc/fuzz-harness/Makefile
|
||||
|
||||
# Ignores in Windows fork
|
||||
/bin/x64/Debug
|
||||
/contrib/win32/openssh/.vs/Win32-OpenSSH/v14
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
This file used to contain a description of the SSH agent protocol
|
||||
implemented by OpenSSH. It has since been superseded by
|
||||
https://tools.ietf.org/html/draft-miller-ssh-agent-00
|
||||
implemented by OpenSSH. It has since been superseded by an Internet-
|
||||
draft that is available from:
|
||||
|
||||
https://tools.ietf.org/html/draft-miller-ssh-agent-02
|
||||
|
|
2
README
2
README
|
@ -1,4 +1,4 @@
|
|||
See https://www.openssh.com/releasenotes.html#7.5p1 for the release notes.
|
||||
See https://www.openssh.com/releasenotes.html#7.6p1 for the release notes.
|
||||
|
||||
Please read https://www.openssh.com/report.html for bug reporting
|
||||
instructions and note that we do not use Github for bug reporting or
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth-options.c,v 1.73 2017/05/31 10:54:00 markus Exp $ */
|
||||
/* $OpenBSD: auth-options.c,v 1.74 2017/09/12 06:32:07 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -61,9 +61,13 @@ char *authorized_principals = NULL;
|
|||
|
||||
extern ServerOptions options;
|
||||
|
||||
/* XXX refactor to be stateless */
|
||||
|
||||
void
|
||||
auth_clear_options(void)
|
||||
{
|
||||
struct ssh *ssh = active_state; /* XXX */
|
||||
|
||||
no_agent_forwarding_flag = 0;
|
||||
no_port_forwarding_flag = 0;
|
||||
no_pty_flag = 0;
|
||||
|
@ -81,7 +85,7 @@ auth_clear_options(void)
|
|||
free(authorized_principals);
|
||||
authorized_principals = NULL;
|
||||
forced_tun_device = -1;
|
||||
channel_clear_permitted_opens();
|
||||
channel_clear_permitted_opens(ssh);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -117,6 +121,7 @@ match_flag(const char *opt, int allow_negate, char **optsp, const char *msg)
|
|||
/*
|
||||
* return 1 if access is granted, 0 if not.
|
||||
* side effect: sets key option flags
|
||||
* XXX remove side effects; fill structure instead.
|
||||
*/
|
||||
int
|
||||
auth_parse_options(struct passwd *pw, char *opts, const char *file,
|
||||
|
@ -380,7 +385,7 @@ auth_parse_options(struct passwd *pw, char *opts, const char *file,
|
|||
goto bad_option;
|
||||
}
|
||||
if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0)
|
||||
channel_add_permitted_opens(host, port);
|
||||
channel_add_permitted_opens(ssh, host, port);
|
||||
free(patterns);
|
||||
goto next_option;
|
||||
}
|
||||
|
|
3
auth.c
3
auth.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth.c,v 1.123 2017/08/18 05:36:45 djm Exp $ */
|
||||
/* $OpenBSD: auth.c,v 1.124 2017/09/12 06:32:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -592,6 +592,7 @@ getpwnamallow(const char *user)
|
|||
ci->user = user;
|
||||
parse_server_match_config(&options, ci);
|
||||
log_change_level(options.log_level);
|
||||
process_permitopen(ssh, &options);
|
||||
|
||||
#if defined(_AIX) && defined(HAVE_SETAUTHDB)
|
||||
aix_setauthdb(user);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: auth2-pubkey.c,v 1.70 2017/08/18 05:48:04 djm Exp $ */
|
||||
/* $OpenBSD: auth2-pubkey.c,v 1.71 2017/09/07 23:48:09 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -482,7 +482,7 @@ check_authkeys_file(FILE *f, char *file, struct sshkey *key, struct passwd *pw)
|
|||
char *cp, *key_options = NULL, *fp = NULL;
|
||||
const char *reason = NULL;
|
||||
|
||||
/* Always consume entrire file */
|
||||
/* Always consume entire file */
|
||||
if (found_key)
|
||||
continue;
|
||||
if (found != NULL)
|
||||
|
|
3299
channels.c
3299
channels.c
File diff suppressed because it is too large
Load Diff
191
channels.h
191
channels.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: channels.h,v 1.126 2017/05/30 14:23:52 markus Exp $ */
|
||||
/* $OpenBSD: channels.h,v 1.130 2017/09/21 19:16:53 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -57,23 +57,27 @@
|
|||
#define SSH_CHANNEL_UNIX_LISTENER 18 /* Listening on a domain socket. */
|
||||
#define SSH_CHANNEL_RUNIX_LISTENER 19 /* Listening to a R-style domain socket. */
|
||||
#define SSH_CHANNEL_MUX_PROXY 20 /* proxy channel for mux-slave */
|
||||
#define SSH_CHANNEL_MAX_TYPE 21
|
||||
#define SSH_CHANNEL_RDYNAMIC_OPEN 21 /* reverse SOCKS, parsing request */
|
||||
#define SSH_CHANNEL_RDYNAMIC_FINISH 22 /* reverse SOCKS, finishing connect */
|
||||
#define SSH_CHANNEL_MAX_TYPE 23
|
||||
|
||||
#define CHANNEL_CANCEL_PORT_STATIC -1
|
||||
|
||||
struct ssh;
|
||||
struct Channel;
|
||||
typedef struct Channel Channel;
|
||||
struct fwd_perm_list;
|
||||
|
||||
typedef void channel_open_fn(int, int, void *);
|
||||
typedef void channel_callback_fn(int, void *);
|
||||
typedef int channel_infilter_fn(struct Channel *, char *, int);
|
||||
typedef void channel_filter_cleanup_fn(int, void *);
|
||||
typedef u_char *channel_outfilter_fn(struct Channel *, u_char **, u_int *);
|
||||
typedef void channel_open_fn(struct ssh *, int, int, void *);
|
||||
typedef void channel_callback_fn(struct ssh *, int, void *);
|
||||
typedef int channel_infilter_fn(struct ssh *, struct Channel *, char *, int);
|
||||
typedef void channel_filter_cleanup_fn(struct ssh *, int, void *);
|
||||
typedef u_char *channel_outfilter_fn(struct ssh *, struct Channel *,
|
||||
u_char **, size_t *);
|
||||
|
||||
/* Channel success/failure callbacks */
|
||||
typedef void channel_confirm_cb(int, struct Channel *, void *);
|
||||
typedef void channel_confirm_abandon_cb(struct Channel *, void *);
|
||||
typedef void channel_confirm_cb(struct ssh *, int, struct Channel *, void *);
|
||||
typedef void channel_confirm_abandon_cb(struct ssh *, struct Channel *, void *);
|
||||
struct channel_confirm {
|
||||
TAILQ_ENTRY(channel_confirm) entry;
|
||||
channel_confirm_cb *cb;
|
||||
|
@ -90,12 +94,14 @@ struct channel_connect {
|
|||
};
|
||||
|
||||
/* Callbacks for mux channels back into client-specific code */
|
||||
typedef int mux_callback_fn(struct Channel *);
|
||||
typedef int mux_callback_fn(struct ssh *, struct Channel *);
|
||||
|
||||
struct Channel {
|
||||
int type; /* channel type/state */
|
||||
int self; /* my own channel identifier */
|
||||
int remote_id; /* channel identifier for remote peer */
|
||||
uint32_t remote_id; /* channel identifier for remote peer */
|
||||
int have_remote_id; /* non-zero if remote_id is valid */
|
||||
|
||||
u_int istate; /* input from channel (state of receive half) */
|
||||
u_int ostate; /* output to channel (state of transmit half) */
|
||||
int flags; /* close sent/rcvd */
|
||||
|
@ -116,11 +122,12 @@ struct Channel {
|
|||
* to a matching pre-select handler.
|
||||
* this way post-select handlers are not
|
||||
* accidentally called if a FD gets reused */
|
||||
Buffer input; /* data read from socket, to be sent over
|
||||
struct sshbuf *input; /* data read from socket, to be sent over
|
||||
* encrypted connection */
|
||||
Buffer output; /* data received over encrypted connection for
|
||||
struct sshbuf *output; /* data received over encrypted connection for
|
||||
* send on socket */
|
||||
Buffer extended;
|
||||
struct sshbuf *extended;
|
||||
|
||||
char *path;
|
||||
/* path for unix domain sockets, or host name for forwards */
|
||||
int listening_port; /* port being listened for forwards */
|
||||
|
@ -156,6 +163,7 @@ struct Channel {
|
|||
int datagram;
|
||||
|
||||
/* non-blocking connect */
|
||||
/* XXX make this a pointer so the structure can be opaque */
|
||||
struct channel_connect connect_ctx;
|
||||
|
||||
/* multiplexing protocol hook, called for each packet received */
|
||||
|
@ -195,44 +203,55 @@ struct Channel {
|
|||
#define CHAN_EOF_RCVD 0x08
|
||||
#define CHAN_LOCAL 0x10
|
||||
|
||||
#define CHAN_RBUF 16*1024
|
||||
/* Read buffer size */
|
||||
#define CHAN_RBUF (16*1024)
|
||||
|
||||
/* Hard limit on number of channels */
|
||||
#define CHANNELS_MAX_CHANNELS (16*1024)
|
||||
|
||||
/* check whether 'efd' is still in use */
|
||||
#define CHANNEL_EFD_INPUT_ACTIVE(c) \
|
||||
(c->extended_usage == CHAN_EXTENDED_READ && \
|
||||
(c->efd != -1 || \
|
||||
buffer_len(&c->extended) > 0))
|
||||
sshbuf_len(c->extended) > 0))
|
||||
#define CHANNEL_EFD_OUTPUT_ACTIVE(c) \
|
||||
(c->extended_usage == CHAN_EXTENDED_WRITE && \
|
||||
c->efd != -1 && (!(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD)) || \
|
||||
buffer_len(&c->extended) > 0))
|
||||
sshbuf_len(c->extended) > 0))
|
||||
|
||||
/* Add channel management structures to SSH transport instance */
|
||||
void channel_init_channels(struct ssh *ssh);
|
||||
|
||||
/* channel management */
|
||||
|
||||
Channel *channel_by_id(int);
|
||||
Channel *channel_by_remote_id(int);
|
||||
Channel *channel_lookup(int);
|
||||
Channel *channel_new(char *, int, int, int, int, u_int, u_int, int, char *, int);
|
||||
void channel_set_fds(int, int, int, int, int, int, int, u_int);
|
||||
void channel_free(Channel *);
|
||||
void channel_free_all(void);
|
||||
void channel_stop_listening(void);
|
||||
Channel *channel_by_id(struct ssh *, int);
|
||||
Channel *channel_by_remote_id(struct ssh *, u_int);
|
||||
Channel *channel_lookup(struct ssh *, int);
|
||||
Channel *channel_new(struct ssh *, char *, int, int, int, int,
|
||||
u_int, u_int, int, char *, int);
|
||||
void channel_set_fds(struct ssh *, int, int, int, int, int,
|
||||
int, int, u_int);
|
||||
void channel_free(struct ssh *, Channel *);
|
||||
void channel_free_all(struct ssh *);
|
||||
void channel_stop_listening(struct ssh *);
|
||||
|
||||
void channel_send_open(int);
|
||||
void channel_request_start(int, char *, int);
|
||||
void channel_register_cleanup(int, channel_callback_fn *, int);
|
||||
void channel_register_open_confirm(int, channel_open_fn *, void *);
|
||||
void channel_register_filter(int, channel_infilter_fn *,
|
||||
channel_outfilter_fn *, channel_filter_cleanup_fn *, void *);
|
||||
void channel_register_status_confirm(int, channel_confirm_cb *,
|
||||
channel_confirm_abandon_cb *, void *);
|
||||
void channel_cancel_cleanup(int);
|
||||
int channel_close_fd(int *);
|
||||
void channel_send_window_changes(void);
|
||||
void channel_send_open(struct ssh *, int);
|
||||
void channel_request_start(struct ssh *, int, char *, int);
|
||||
void channel_register_cleanup(struct ssh *, int,
|
||||
channel_callback_fn *, int);
|
||||
void channel_register_open_confirm(struct ssh *, int,
|
||||
channel_open_fn *, void *);
|
||||
void channel_register_filter(struct ssh *, int, channel_infilter_fn *,
|
||||
channel_outfilter_fn *, channel_filter_cleanup_fn *, void *);
|
||||
void channel_register_status_confirm(struct ssh *, int,
|
||||
channel_confirm_cb *, channel_confirm_abandon_cb *, void *);
|
||||
void channel_cancel_cleanup(struct ssh *, int);
|
||||
int channel_close_fd(struct ssh *, int *);
|
||||
void channel_send_window_changes(struct ssh *);
|
||||
|
||||
/* mux proxy support */
|
||||
|
||||
int channel_proxy_downstream(Channel *mc);
|
||||
int channel_proxy_downstream(struct ssh *, Channel *mc);
|
||||
int channel_proxy_upstream(Channel *, int, u_int32_t, struct ssh *);
|
||||
|
||||
/* protocol handler */
|
||||
|
@ -249,66 +268,72 @@ int channel_input_status_confirm(int, u_int32_t, struct ssh *);
|
|||
|
||||
/* file descriptor handling (read/write) */
|
||||
|
||||
void channel_prepare_select(fd_set **, fd_set **, int *, u_int*,
|
||||
time_t*, int);
|
||||
void channel_after_select(fd_set *, fd_set *);
|
||||
void channel_output_poll(void);
|
||||
void channel_prepare_select(struct ssh *, fd_set **, fd_set **, int *,
|
||||
u_int*, time_t*);
|
||||
void channel_after_select(struct ssh *, fd_set *, fd_set *);
|
||||
void channel_output_poll(struct ssh *);
|
||||
|
||||
int channel_not_very_much_buffered_data(void);
|
||||
void channel_close_all(void);
|
||||
int channel_still_open(void);
|
||||
char *channel_open_message(void);
|
||||
int channel_find_open(void);
|
||||
int channel_not_very_much_buffered_data(struct ssh *);
|
||||
void channel_close_all(struct ssh *);
|
||||
int channel_still_open(struct ssh *);
|
||||
char *channel_open_message(struct ssh *);
|
||||
int channel_find_open(struct ssh *);
|
||||
|
||||
/* tcp forwarding */
|
||||
struct Forward;
|
||||
struct ForwardOptions;
|
||||
void channel_set_af(int af);
|
||||
void channel_permit_all_opens(void);
|
||||
void channel_add_permitted_opens(char *, int);
|
||||
int channel_add_adm_permitted_opens(char *, int);
|
||||
void channel_disable_adm_local_opens(void);
|
||||
void channel_update_permitted_opens(int, int);
|
||||
void channel_clear_permitted_opens(void);
|
||||
void channel_clear_adm_permitted_opens(void);
|
||||
void channel_print_adm_permitted_opens(void);
|
||||
Channel *channel_connect_to_port(const char *, u_short, char *, char *, int *,
|
||||
const char **);
|
||||
Channel *channel_connect_to_path(const char *, char *, char *);
|
||||
Channel *channel_connect_stdio_fwd(const char*, u_short, int, int);
|
||||
Channel *channel_connect_by_listen_address(const char *, u_short,
|
||||
char *, char *);
|
||||
Channel *channel_connect_by_listen_path(const char *, char *, char *);
|
||||
int channel_request_remote_forwarding(struct Forward *);
|
||||
int channel_setup_local_fwd_listener(struct Forward *, struct ForwardOptions *);
|
||||
int channel_request_rforward_cancel(struct Forward *);
|
||||
int channel_setup_remote_fwd_listener(struct Forward *, int *, struct ForwardOptions *);
|
||||
int channel_cancel_rport_listener(struct Forward *);
|
||||
int channel_cancel_lport_listener(struct Forward *, int, struct ForwardOptions *);
|
||||
void channel_set_af(struct ssh *, int af);
|
||||
void channel_permit_all_opens(struct ssh *);
|
||||
void channel_add_permitted_opens(struct ssh *, char *, int);
|
||||
int channel_add_adm_permitted_opens(struct ssh *, char *, int);
|
||||
void channel_copy_adm_permitted_opens(struct ssh *,
|
||||
const struct fwd_perm_list *);
|
||||
void channel_disable_adm_local_opens(struct ssh *);
|
||||
void channel_update_permitted_opens(struct ssh *, int, int);
|
||||
void channel_clear_permitted_opens(struct ssh *);
|
||||
void channel_clear_adm_permitted_opens(struct ssh *);
|
||||
void channel_print_adm_permitted_opens(struct ssh *);
|
||||
Channel *channel_connect_to_port(struct ssh *, const char *, u_short,
|
||||
char *, char *, int *, const char **);
|
||||
Channel *channel_connect_to_path(struct ssh *, const char *, char *, char *);
|
||||
Channel *channel_connect_stdio_fwd(struct ssh *, const char*,
|
||||
u_short, int, int);
|
||||
Channel *channel_connect_by_listen_address(struct ssh *, const char *,
|
||||
u_short, char *, char *);
|
||||
Channel *channel_connect_by_listen_path(struct ssh *, const char *,
|
||||
char *, char *);
|
||||
int channel_request_remote_forwarding(struct ssh *, struct Forward *);
|
||||
int channel_setup_local_fwd_listener(struct ssh *, struct Forward *,
|
||||
struct ForwardOptions *);
|
||||
int channel_request_rforward_cancel(struct ssh *, struct Forward *);
|
||||
int channel_setup_remote_fwd_listener(struct ssh *, struct Forward *,
|
||||
int *, struct ForwardOptions *);
|
||||
int channel_cancel_rport_listener(struct ssh *, struct Forward *);
|
||||
int channel_cancel_lport_listener(struct ssh *, struct Forward *,
|
||||
int, struct ForwardOptions *);
|
||||
int permitopen_port(const char *);
|
||||
|
||||
/* x11 forwarding */
|
||||
|
||||
void channel_set_x11_refuse_time(u_int);
|
||||
int x11_connect_display(void);
|
||||
int x11_create_display_inet(int, int, int, u_int *, int **);
|
||||
void x11_request_forwarding_with_spoofing(int, const char *, const char *,
|
||||
const char *, int);
|
||||
void channel_set_x11_refuse_time(struct ssh *, u_int);
|
||||
int x11_connect_display(struct ssh *);
|
||||
int x11_create_display_inet(struct ssh *, int, int, int, u_int *, int **);
|
||||
void x11_request_forwarding_with_spoofing(struct ssh *, int,
|
||||
const char *, const char *, const char *, int);
|
||||
|
||||
/* channel close */
|
||||
|
||||
int chan_is_dead(Channel *, int);
|
||||
void chan_mark_dead(Channel *);
|
||||
int chan_is_dead(struct ssh *, Channel *, int);
|
||||
void chan_mark_dead(struct ssh *, Channel *);
|
||||
|
||||
/* channel events */
|
||||
|
||||
void chan_rcvd_oclose(Channel *);
|
||||
void chan_rcvd_eow(Channel *); /* SSH2-only */
|
||||
void chan_read_failed(Channel *);
|
||||
void chan_ibuf_empty(Channel *);
|
||||
|
||||
void chan_rcvd_ieof(Channel *);
|
||||
void chan_write_failed(Channel *);
|
||||
void chan_obuf_empty(Channel *);
|
||||
void chan_rcvd_oclose(struct ssh *, Channel *);
|
||||
void chan_rcvd_eow(struct ssh *, Channel *);
|
||||
void chan_read_failed(struct ssh *, Channel *);
|
||||
void chan_ibuf_empty(struct ssh *, Channel *);
|
||||
void chan_rcvd_ieof(struct ssh *, Channel *);
|
||||
void chan_write_failed(struct ssh *, Channel *);
|
||||
void chan_obuf_empty(struct ssh *, Channel *);
|
||||
|
||||
#endif
|
||||
|
|
216
clientloop.c
216
clientloop.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: clientloop.c,v 1.301 2017/07/14 03:18:21 dtucker Exp $ */
|
||||
/* $OpenBSD: clientloop.c,v 1.305 2017/09/19 04:24:22 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -177,6 +177,7 @@ struct channel_reply_ctx {
|
|||
};
|
||||
|
||||
/* Global request success/failure callbacks */
|
||||
/* XXX move to struct ssh? */
|
||||
struct global_confirm {
|
||||
TAILQ_ENTRY(global_confirm) entry;
|
||||
global_confirm_cb *cb;
|
||||
|
@ -244,13 +245,13 @@ get_current_time(void)
|
|||
* control master process, or if there is no ControlPersist timeout.
|
||||
*/
|
||||
static void
|
||||
set_control_persist_exit_time(void)
|
||||
set_control_persist_exit_time(struct ssh *ssh)
|
||||
{
|
||||
if (muxserver_sock == -1 || !options.control_persist
|
||||
|| options.control_persist_timeout == 0) {
|
||||
/* not using a ControlPersist timeout */
|
||||
control_persist_exit_time = 0;
|
||||
} else if (channel_still_open()) {
|
||||
} else if (channel_still_open(ssh)) {
|
||||
/* some client connections are still open */
|
||||
if (control_persist_exit_time > 0)
|
||||
debug2("%s: cancel scheduled exit", __func__);
|
||||
|
@ -288,8 +289,9 @@ client_x11_display_valid(const char *display)
|
|||
#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
|
||||
#define X11_TIMEOUT_SLACK 60
|
||||
int
|
||||
client_x11_get_proto(const char *display, const char *xauth_path,
|
||||
u_int trusted, u_int timeout, char **_proto, char **_data)
|
||||
client_x11_get_proto(struct ssh *ssh, const char *display,
|
||||
const char *xauth_path, u_int trusted, u_int timeout,
|
||||
char **_proto, char **_data)
|
||||
{
|
||||
char cmd[1024], line[512], xdisplay[512];
|
||||
char xauthfile[PATH_MAX], xauthdir[PATH_MAX];
|
||||
|
@ -373,7 +375,8 @@ client_x11_get_proto(const char *display, const char *xauth_path,
|
|||
x11_refuse_time = UINT_MAX;
|
||||
else
|
||||
x11_refuse_time = now + timeout;
|
||||
channel_set_x11_refuse_time(x11_refuse_time);
|
||||
channel_set_x11_refuse_time(ssh,
|
||||
x11_refuse_time);
|
||||
}
|
||||
if (system(cmd) == 0)
|
||||
generated = 1;
|
||||
|
@ -446,7 +449,7 @@ client_x11_get_proto(const char *display, const char *xauth_path,
|
|||
*/
|
||||
|
||||
static void
|
||||
client_check_window_change(void)
|
||||
client_check_window_change(struct ssh *ssh)
|
||||
{
|
||||
if (!received_window_change_signal)
|
||||
return;
|
||||
|
@ -455,7 +458,7 @@ client_check_window_change(void)
|
|||
|
||||
debug2("%s: changed", __func__);
|
||||
|
||||
channel_send_window_changes();
|
||||
channel_send_window_changes(ssh);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -466,7 +469,7 @@ client_global_request_reply(int type, u_int32_t seq, struct ssh *ssh)
|
|||
if ((gc = TAILQ_FIRST(&global_confirms)) == NULL)
|
||||
return 0;
|
||||
if (gc->cb != NULL)
|
||||
gc->cb(type, seq, gc->ctx);
|
||||
gc->cb(ssh, type, seq, gc->ctx);
|
||||
if (--gc->ref_count <= 0) {
|
||||
TAILQ_REMOVE(&global_confirms, gc, entry);
|
||||
explicit_bzero(gc, sizeof(*gc));
|
||||
|
@ -497,7 +500,8 @@ server_alive_check(void)
|
|||
* one of the file descriptors).
|
||||
*/
|
||||
static void
|
||||
client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
|
||||
client_wait_until_can_do_something(struct ssh *ssh,
|
||||
fd_set **readsetp, fd_set **writesetp,
|
||||
int *maxfdp, u_int *nallocp, int rekeying)
|
||||
{
|
||||
struct timeval tv, *tvp;
|
||||
|
@ -506,11 +510,11 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
|
|||
int ret;
|
||||
|
||||
/* Add any selections by the channel mechanism. */
|
||||
channel_prepare_select(readsetp, writesetp, maxfdp, nallocp,
|
||||
&minwait_secs, rekeying);
|
||||
channel_prepare_select(active_state, readsetp, writesetp, maxfdp,
|
||||
nallocp, &minwait_secs);
|
||||
|
||||
/* channel_prepare_select could have closed the last channel */
|
||||
if (session_closed && !channel_still_open() &&
|
||||
if (session_closed && !channel_still_open(ssh) &&
|
||||
!packet_have_data_to_write()) {
|
||||
/* clear mask since we did not call select() */
|
||||
memset(*readsetp, 0, *nallocp);
|
||||
|
@ -537,7 +541,7 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
|
|||
}
|
||||
if (options.rekey_interval > 0 && !rekeying)
|
||||
timeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout());
|
||||
set_control_persist_exit_time();
|
||||
set_control_persist_exit_time(ssh);
|
||||
if (control_persist_exit_time > 0) {
|
||||
timeout_secs = MINIMUM(timeout_secs,
|
||||
control_persist_exit_time - now);
|
||||
|
@ -596,13 +600,9 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
|
|||
|
||||
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
|
||||
|
||||
/*
|
||||
* Free (and clear) the buffer to reduce the amount of data that gets
|
||||
* written to swap.
|
||||
*/
|
||||
buffer_free(bin);
|
||||
buffer_free(bout);
|
||||
buffer_free(berr);
|
||||
sshbuf_reset(bin);
|
||||
sshbuf_reset(bout);
|
||||
sshbuf_reset(berr);
|
||||
|
||||
/* Send the suspend signal to the program itself. */
|
||||
kill(getpid(), SIGTSTP);
|
||||
|
@ -610,11 +610,6 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
|
|||
/* Reset window sizes in case they have changed */
|
||||
received_window_change_signal = 1;
|
||||
|
||||
/* OK, we have been continued by the user. Reinitialize buffers. */
|
||||
buffer_init(bin);
|
||||
buffer_init(bout);
|
||||
buffer_init(berr);
|
||||
|
||||
enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
|
||||
}
|
||||
|
||||
|
@ -668,7 +663,7 @@ client_process_net_input(fd_set *readset)
|
|||
}
|
||||
|
||||
static void
|
||||
client_status_confirm(int type, Channel *c, void *ctx)
|
||||
client_status_confirm(struct ssh *ssh, int type, Channel *c, void *ctx)
|
||||
{
|
||||
struct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx;
|
||||
char errmsg[256];
|
||||
|
@ -707,8 +702,7 @@ client_status_confirm(int type, Channel *c, void *ctx)
|
|||
* their stderr.
|
||||
*/
|
||||
if (tochan) {
|
||||
buffer_append(&c->extended, errmsg,
|
||||
strlen(errmsg));
|
||||
buffer_append(c->extended, errmsg, strlen(errmsg));
|
||||
} else
|
||||
error("%s", errmsg);
|
||||
if (cr->action == CONFIRM_TTY) {
|
||||
|
@ -719,23 +713,23 @@ client_status_confirm(int type, Channel *c, void *ctx)
|
|||
if (c->self == session_ident)
|
||||
leave_raw_mode(0);
|
||||
else
|
||||
mux_tty_alloc_failed(c);
|
||||
mux_tty_alloc_failed(ssh, c);
|
||||
} else if (cr->action == CONFIRM_CLOSE) {
|
||||
chan_read_failed(c);
|
||||
chan_write_failed(c);
|
||||
chan_read_failed(ssh, c);
|
||||
chan_write_failed(ssh, c);
|
||||
}
|
||||
}
|
||||
free(cr);
|
||||
}
|
||||
|
||||
static void
|
||||
client_abandon_status_confirm(Channel *c, void *ctx)
|
||||
client_abandon_status_confirm(struct ssh *ssh, Channel *c, void *ctx)
|
||||
{
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
client_expect_confirm(int id, const char *request,
|
||||
client_expect_confirm(struct ssh *ssh, int id, const char *request,
|
||||
enum confirm_action action)
|
||||
{
|
||||
struct channel_reply_ctx *cr = xcalloc(1, sizeof(*cr));
|
||||
|
@ -743,7 +737,7 @@ client_expect_confirm(int id, const char *request,
|
|||
cr->request_type = request;
|
||||
cr->action = action;
|
||||
|
||||
channel_register_status_confirm(id, client_status_confirm,
|
||||
channel_register_status_confirm(ssh, id, client_status_confirm,
|
||||
client_abandon_status_confirm, cr);
|
||||
}
|
||||
|
||||
|
@ -769,7 +763,7 @@ client_register_global_confirm(global_confirm_cb *cb, void *ctx)
|
|||
}
|
||||
|
||||
static void
|
||||
process_cmdline(void)
|
||||
process_cmdline(struct ssh *ssh)
|
||||
{
|
||||
void (*handler)(int);
|
||||
char *s, *cmd;
|
||||
|
@ -843,12 +837,12 @@ process_cmdline(void)
|
|||
goto out;
|
||||
}
|
||||
if (remote)
|
||||
ok = channel_request_rforward_cancel(&fwd) == 0;
|
||||
ok = channel_request_rforward_cancel(ssh, &fwd) == 0;
|
||||
else if (dynamic)
|
||||
ok = channel_cancel_lport_listener(&fwd,
|
||||
ok = channel_cancel_lport_listener(ssh, &fwd,
|
||||
0, &options.fwd_opts) > 0;
|
||||
else
|
||||
ok = channel_cancel_lport_listener(&fwd,
|
||||
ok = channel_cancel_lport_listener(ssh, &fwd,
|
||||
CHANNEL_CANCEL_PORT_STATIC,
|
||||
&options.fwd_opts) > 0;
|
||||
if (!ok) {
|
||||
|
@ -862,13 +856,13 @@ process_cmdline(void)
|
|||
goto out;
|
||||
}
|
||||
if (local || dynamic) {
|
||||
if (!channel_setup_local_fwd_listener(&fwd,
|
||||
if (!channel_setup_local_fwd_listener(ssh, &fwd,
|
||||
&options.fwd_opts)) {
|
||||
logit("Port forwarding failed.");
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (channel_request_remote_forwarding(&fwd) < 0) {
|
||||
if (channel_request_remote_forwarding(ssh, &fwd) < 0) {
|
||||
logit("Port forwarding failed.");
|
||||
goto out;
|
||||
}
|
||||
|
@ -945,7 +939,8 @@ print_escape_help(Buffer *b, int escape_char, int mux_client, int using_stderr)
|
|||
* Process the characters one by one.
|
||||
*/
|
||||
static int
|
||||
process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
|
||||
process_escapes(struct ssh *ssh, Channel *c,
|
||||
Buffer *bin, Buffer *bout, Buffer *berr,
|
||||
char *buf, int len)
|
||||
{
|
||||
char string[1024];
|
||||
|
@ -981,13 +976,15 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
|
|||
buffer_append(berr, string, strlen(string));
|
||||
|
||||
if (c && c->ctl_chan != -1) {
|
||||
chan_read_failed(c);
|
||||
chan_write_failed(c);
|
||||
if (c->detach_user)
|
||||
c->detach_user(c->self, NULL);
|
||||
chan_read_failed(ssh, c);
|
||||
chan_write_failed(ssh, c);
|
||||
if (c->detach_user) {
|
||||
c->detach_user(ssh,
|
||||
c->self, NULL);
|
||||
}
|
||||
c->type = SSH_CHANNEL_ABANDONED;
|
||||
buffer_clear(&c->input);
|
||||
chan_ibuf_empty(c);
|
||||
buffer_clear(c->input);
|
||||
chan_ibuf_empty(ssh, c);
|
||||
return 0;
|
||||
} else
|
||||
quit_pending = 1;
|
||||
|
@ -1025,7 +1022,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
|
|||
snprintf(string, sizeof string,
|
||||
"%cB\r\n", efc->escape_char);
|
||||
buffer_append(berr, string, strlen(string));
|
||||
channel_request_start(c->self, "break", 0);
|
||||
channel_request_start(ssh, c->self, "break", 0);
|
||||
packet_put_int(1000);
|
||||
packet_send();
|
||||
continue;
|
||||
|
@ -1080,7 +1077,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
|
|||
options.request_tty == REQUEST_TTY_FORCE);
|
||||
|
||||
/* Stop listening for new connections. */
|
||||
channel_stop_listening();
|
||||
channel_stop_listening(ssh);
|
||||
|
||||
snprintf(string, sizeof string,
|
||||
"%c& [backgrounded]\n", efc->escape_char);
|
||||
|
@ -1111,7 +1108,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
|
|||
snprintf(string, sizeof string, "%c#\r\n",
|
||||
efc->escape_char);
|
||||
buffer_append(berr, string, strlen(string));
|
||||
s = channel_open_message();
|
||||
s = channel_open_message(ssh);
|
||||
buffer_append(berr, s, strlen(s));
|
||||
free(s);
|
||||
continue;
|
||||
|
@ -1119,7 +1116,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
|
|||
case 'C':
|
||||
if (c && c->ctl_chan != -1)
|
||||
goto noescape;
|
||||
process_cmdline();
|
||||
process_cmdline(ssh);
|
||||
continue;
|
||||
|
||||
default:
|
||||
|
@ -1190,25 +1187,25 @@ client_new_escape_filter_ctx(int escape_char)
|
|||
|
||||
/* Free the escape filter context on channel free */
|
||||
void
|
||||
client_filter_cleanup(int cid, void *ctx)
|
||||
client_filter_cleanup(struct ssh *ssh, int cid, void *ctx)
|
||||
{
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
int
|
||||
client_simple_escape_filter(Channel *c, char *buf, int len)
|
||||
client_simple_escape_filter(struct ssh *ssh, Channel *c, char *buf, int len)
|
||||
{
|
||||
if (c->extended_usage != CHAN_EXTENDED_WRITE)
|
||||
return 0;
|
||||
|
||||
return process_escapes(c, &c->input, &c->output, &c->extended,
|
||||
return process_escapes(ssh, c, c->input, c->output, c->extended,
|
||||
buf, len);
|
||||
}
|
||||
|
||||
static void
|
||||
client_channel_closed(int id, void *arg)
|
||||
client_channel_closed(struct ssh *ssh, int id, void *arg)
|
||||
{
|
||||
channel_cancel_cleanup(id);
|
||||
channel_cancel_cleanup(ssh, id);
|
||||
session_closed = 1;
|
||||
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
|
||||
}
|
||||
|
@ -1219,9 +1216,9 @@ client_channel_closed(int id, void *arg)
|
|||
* remote host. If escape_char != SSH_ESCAPECHAR_NONE, it is the character
|
||||
* used as an escape character for terminating or suspending the session.
|
||||
*/
|
||||
|
||||
int
|
||||
client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
||||
client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
|
||||
int ssh2_chan_id)
|
||||
{
|
||||
fd_set *readset = NULL, *writeset = NULL;
|
||||
double start_time, total_time;
|
||||
|
@ -1299,13 +1296,13 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
|||
session_ident = ssh2_chan_id;
|
||||
if (session_ident != -1) {
|
||||
if (escape_char_arg != SSH_ESCAPECHAR_NONE) {
|
||||
channel_register_filter(session_ident,
|
||||
channel_register_filter(ssh, session_ident,
|
||||
client_simple_escape_filter, NULL,
|
||||
client_filter_cleanup,
|
||||
client_new_escape_filter_ctx(
|
||||
escape_char_arg));
|
||||
}
|
||||
channel_register_cleanup(session_ident,
|
||||
channel_register_cleanup(ssh, session_ident,
|
||||
client_channel_closed, 0);
|
||||
}
|
||||
|
||||
|
@ -1315,15 +1312,15 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
|||
/* Process buffered packets sent by the server. */
|
||||
client_process_buffered_input_packets();
|
||||
|
||||
if (session_closed && !channel_still_open())
|
||||
if (session_closed && !channel_still_open(ssh))
|
||||
break;
|
||||
|
||||
if (ssh_packet_is_rekeying(active_state)) {
|
||||
if (ssh_packet_is_rekeying(ssh)) {
|
||||
debug("rekeying in progress");
|
||||
} else if (need_rekeying) {
|
||||
/* manual rekey request */
|
||||
debug("need rekeying");
|
||||
if ((r = kex_start_rekex(active_state)) != 0)
|
||||
if ((r = kex_start_rekex(ssh)) != 0)
|
||||
fatal("%s: kex_start_rekex: %s", __func__,
|
||||
ssh_err(r));
|
||||
need_rekeying = 0;
|
||||
|
@ -1333,13 +1330,13 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
|||
* enqueue them for sending to the server.
|
||||
*/
|
||||
if (packet_not_very_much_data_to_write())
|
||||
channel_output_poll();
|
||||
channel_output_poll(ssh);
|
||||
|
||||
/*
|
||||
* Check if the window size has changed, and buffer a
|
||||
* message about it to the server if so.
|
||||
*/
|
||||
client_check_window_change();
|
||||
client_check_window_change(ssh);
|
||||
|
||||
if (quit_pending)
|
||||
break;
|
||||
|
@ -1349,15 +1346,15 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
|||
* available on one of the descriptors).
|
||||
*/
|
||||
max_fd2 = max_fd;
|
||||
client_wait_until_can_do_something(&readset, &writeset,
|
||||
&max_fd2, &nalloc, ssh_packet_is_rekeying(active_state));
|
||||
client_wait_until_can_do_something(ssh, &readset, &writeset,
|
||||
&max_fd2, &nalloc, ssh_packet_is_rekeying(ssh));
|
||||
|
||||
if (quit_pending)
|
||||
break;
|
||||
|
||||
/* Do channel operations unless rekeying in progress. */
|
||||
if (!ssh_packet_is_rekeying(active_state))
|
||||
channel_after_select(readset, writeset);
|
||||
if (!ssh_packet_is_rekeying(ssh))
|
||||
channel_after_select(ssh, readset, writeset);
|
||||
|
||||
/* Buffer input from the connection. */
|
||||
client_process_net_input(readset);
|
||||
|
@ -1399,7 +1396,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
|||
packet_send();
|
||||
packet_write_wait();
|
||||
|
||||
channel_free_all();
|
||||
channel_free_all(ssh);
|
||||
|
||||
if (have_pty)
|
||||
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
|
||||
|
@ -1467,8 +1464,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
|
|||
/*********/
|
||||
|
||||
static Channel *
|
||||
client_request_forwarded_tcpip(const char *request_type, int rchan,
|
||||
u_int rwindow, u_int rmaxpack)
|
||||
client_request_forwarded_tcpip(struct ssh *ssh, const char *request_type,
|
||||
int rchan, u_int rwindow, u_int rmaxpack)
|
||||
{
|
||||
Channel *c = NULL;
|
||||
struct sshbuf *b = NULL;
|
||||
|
@ -1486,7 +1483,7 @@ client_request_forwarded_tcpip(const char *request_type, int rchan,
|
|||
debug("%s: listen %s port %d, originator %s port %d", __func__,
|
||||
listen_address, listen_port, originator_address, originator_port);
|
||||
|
||||
c = channel_connect_by_listen_address(listen_address, listen_port,
|
||||
c = channel_connect_by_listen_address(ssh, listen_address, listen_port,
|
||||
"forwarded-tcpip", originator_address);
|
||||
|
||||
if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) {
|
||||
|
@ -1505,7 +1502,7 @@ client_request_forwarded_tcpip(const char *request_type, int rchan,
|
|||
(r = sshbuf_put_u32(b, listen_port)) != 0 ||
|
||||
(r = sshbuf_put_cstring(b, originator_address)) != 0 ||
|
||||
(r = sshbuf_put_u32(b, originator_port)) != 0 ||
|
||||
(r = sshbuf_put_stringb(&c->output, b)) != 0) {
|
||||
(r = sshbuf_put_stringb(c->output, b)) != 0) {
|
||||
error("%s: compose for muxclient %s", __func__,
|
||||
ssh_err(r));
|
||||
goto out;
|
||||
|
@ -1520,7 +1517,8 @@ client_request_forwarded_tcpip(const char *request_type, int rchan,
|
|||
}
|
||||
|
||||
static Channel *
|
||||
client_request_forwarded_streamlocal(const char *request_type, int rchan)
|
||||
client_request_forwarded_streamlocal(struct ssh *ssh,
|
||||
const char *request_type, int rchan)
|
||||
{
|
||||
Channel *c = NULL;
|
||||
char *listen_path;
|
||||
|
@ -1534,14 +1532,14 @@ client_request_forwarded_streamlocal(const char *request_type, int rchan)
|
|||
|
||||
debug("%s: %s", __func__, listen_path);
|
||||
|
||||
c = channel_connect_by_listen_path(listen_path,
|
||||
c = channel_connect_by_listen_path(ssh, listen_path,
|
||||
"forwarded-streamlocal@openssh.com", "forwarded-streamlocal");
|
||||
free(listen_path);
|
||||
return c;
|
||||
}
|
||||
|
||||
static Channel *
|
||||
client_request_x11(const char *request_type, int rchan)
|
||||
client_request_x11(struct ssh *ssh, const char *request_type, int rchan)
|
||||
{
|
||||
Channel *c = NULL;
|
||||
char *originator;
|
||||
|
@ -1571,10 +1569,10 @@ client_request_x11(const char *request_type, int rchan)
|
|||
debug("client_request_x11: request from %s %d", originator,
|
||||
originator_port);
|
||||
free(originator);
|
||||
sock = x11_connect_display();
|
||||
sock = x11_connect_display(ssh);
|
||||
if (sock < 0)
|
||||
return NULL;
|
||||
c = channel_new("x11",
|
||||
c = channel_new(ssh, "x11",
|
||||
SSH_CHANNEL_X11_OPEN, sock, sock, -1,
|
||||
CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
|
||||
c->force_drain = 1;
|
||||
|
@ -1582,7 +1580,7 @@ client_request_x11(const char *request_type, int rchan)
|
|||
}
|
||||
|
||||
static Channel *
|
||||
client_request_agent(const char *request_type, int rchan)
|
||||
client_request_agent(struct ssh *ssh, const char *request_type, int rchan)
|
||||
{
|
||||
Channel *c = NULL;
|
||||
int r, sock;
|
||||
|
@ -1599,7 +1597,7 @@ client_request_agent(const char *request_type, int rchan)
|
|||
__func__, ssh_err(r));
|
||||
return NULL;
|
||||
}
|
||||
c = channel_new("authentication agent connection",
|
||||
c = channel_new(ssh, "authentication agent connection",
|
||||
SSH_CHANNEL_OPEN, sock, sock, -1,
|
||||
CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
|
||||
"authentication agent connection", 1);
|
||||
|
@ -1608,7 +1606,8 @@ client_request_agent(const char *request_type, int rchan)
|
|||
}
|
||||
|
||||
int
|
||||
client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun)
|
||||
client_request_tun_fwd(struct ssh *ssh, int tun_mode,
|
||||
int local_tun, int remote_tun)
|
||||
{
|
||||
Channel *c;
|
||||
int fd;
|
||||
|
@ -1624,13 +1623,13 @@ client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun)
|
|||
return -1;
|
||||
}
|
||||
|
||||
c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
|
||||
c = channel_new(ssh, "tun", SSH_CHANNEL_OPENING, fd, fd, -1,
|
||||
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
|
||||
c->datagram = 1;
|
||||
|
||||
#if defined(SSH_TUN_FILTER)
|
||||
if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
|
||||
channel_register_filter(c->self, sys_tun_infilter,
|
||||
channel_register_filter(ssh, c->self, sys_tun_infilter,
|
||||
sys_tun_outfilter, NULL, NULL);
|
||||
#endif
|
||||
|
||||
|
@ -1664,20 +1663,21 @@ client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
|
|||
ctype, rchan, rwindow, rmaxpack);
|
||||
|
||||
if (strcmp(ctype, "forwarded-tcpip") == 0) {
|
||||
c = client_request_forwarded_tcpip(ctype, rchan, rwindow,
|
||||
c = client_request_forwarded_tcpip(ssh, ctype, rchan, rwindow,
|
||||
rmaxpack);
|
||||
} else if (strcmp(ctype, "forwarded-streamlocal@openssh.com") == 0) {
|
||||
c = client_request_forwarded_streamlocal(ctype, rchan);
|
||||
c = client_request_forwarded_streamlocal(ssh, ctype, rchan);
|
||||
} else if (strcmp(ctype, "x11") == 0) {
|
||||
c = client_request_x11(ctype, rchan);
|
||||
c = client_request_x11(ssh, ctype, rchan);
|
||||
} else if (strcmp(ctype, "auth-agent@openssh.com") == 0) {
|
||||
c = client_request_agent(ctype, rchan);
|
||||
c = client_request_agent(ssh, ctype, rchan);
|
||||
}
|
||||
if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) {
|
||||
debug3("proxied to downstream: %s", ctype);
|
||||
} else if (c != NULL) {
|
||||
debug("confirm %s", ctype);
|
||||
c->remote_id = rchan;
|
||||
c->have_remote_id = 1;
|
||||
c->remote_window = rwindow;
|
||||
c->remote_maxpacket = rmaxpack;
|
||||
if (c->type != SSH_CHANNEL_CONNECTING) {
|
||||
|
@ -1711,7 +1711,7 @@ client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
|
|||
char *rtype;
|
||||
|
||||
id = packet_get_int();
|
||||
c = channel_lookup(id);
|
||||
c = channel_lookup(ssh, id);
|
||||
if (channel_proxy_upstream(c, type, seq, ssh))
|
||||
return 0;
|
||||
rtype = packet_get_string(NULL);
|
||||
|
@ -1727,11 +1727,11 @@ client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
|
|||
"unknown channel", id);
|
||||
} else if (strcmp(rtype, "eow@openssh.com") == 0) {
|
||||
packet_check_eom();
|
||||
chan_rcvd_eow(c);
|
||||
chan_rcvd_eow(ssh, c);
|
||||
} else if (strcmp(rtype, "exit-status") == 0) {
|
||||
exitval = packet_get_int();
|
||||
if (c->ctl_chan != -1) {
|
||||
mux_exit_message(c, exitval);
|
||||
mux_exit_message(ssh, c, exitval);
|
||||
success = 1;
|
||||
} else if (id == session_ident) {
|
||||
/* Record exit value of local session */
|
||||
|
@ -1745,6 +1745,9 @@ client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
|
|||
packet_check_eom();
|
||||
}
|
||||
if (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) {
|
||||
if (!c->have_remote_id)
|
||||
fatal("%s: channel %d: no remote_id",
|
||||
__func__, c->self);
|
||||
packet_start(success ?
|
||||
SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
|
||||
packet_put_int(c->remote_id);
|
||||
|
@ -1899,9 +1902,9 @@ update_known_hosts(struct hostkeys_update_ctx *ctx)
|
|||
}
|
||||
|
||||
static void
|
||||
client_global_hostkeys_private_confirm(int type, u_int32_t seq, void *_ctx)
|
||||
client_global_hostkeys_private_confirm(struct ssh *ssh, int type,
|
||||
u_int32_t seq, void *_ctx)
|
||||
{
|
||||
struct ssh *ssh = active_state; /* XXX */
|
||||
struct hostkeys_update_ctx *ctx = (struct hostkeys_update_ctx *)_ctx;
|
||||
size_t i, ndone;
|
||||
struct sshbuf *signdata;
|
||||
|
@ -2165,7 +2168,7 @@ client_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
|
|||
}
|
||||
|
||||
void
|
||||
client_session2_setup(int id, int want_tty, int want_subsystem,
|
||||
client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
|
||||
const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env)
|
||||
{
|
||||
int len;
|
||||
|
@ -2173,8 +2176,8 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
|
|||
|
||||
debug2("%s: id %d", __func__, id);
|
||||
|
||||
if ((c = channel_lookup(id)) == NULL)
|
||||
fatal("client_session2_setup: channel %d: unknown channel", id);
|
||||
if ((c = channel_lookup(ssh, id)) == NULL)
|
||||
fatal("%s: channel %d: unknown channel", __func__, id);
|
||||
|
||||
packet_set_interactive(want_tty,
|
||||
options.ip_qos_interactive, options.ip_qos_bulk);
|
||||
|
@ -2186,8 +2189,8 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
|
|||
if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0)
|
||||
memset(&ws, 0, sizeof(ws));
|
||||
|
||||
channel_request_start(id, "pty-req", 1);
|
||||
client_expect_confirm(id, "PTY allocation", CONFIRM_TTY);
|
||||
channel_request_start(ssh, id, "pty-req", 1);
|
||||
client_expect_confirm(ssh, id, "PTY allocation", CONFIRM_TTY);
|
||||
packet_put_cstring(term != NULL ? term : "");
|
||||
packet_put_int((u_int)ws.ws_col);
|
||||
packet_put_int((u_int)ws.ws_row);
|
||||
|
@ -2230,7 +2233,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
|
|||
}
|
||||
|
||||
debug("Sending env %s = %s", name, val);
|
||||
channel_request_start(id, "env", 0);
|
||||
channel_request_start(ssh, id, "env", 0);
|
||||
packet_put_cstring(name);
|
||||
packet_put_cstring(val);
|
||||
packet_send();
|
||||
|
@ -2245,19 +2248,20 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
|
|||
if (want_subsystem) {
|
||||
debug("Sending subsystem: %.*s",
|
||||
len, (u_char*)buffer_ptr(cmd));
|
||||
channel_request_start(id, "subsystem", 1);
|
||||
client_expect_confirm(id, "subsystem", CONFIRM_CLOSE);
|
||||
channel_request_start(ssh, id, "subsystem", 1);
|
||||
client_expect_confirm(ssh, id, "subsystem",
|
||||
CONFIRM_CLOSE);
|
||||
} else {
|
||||
debug("Sending command: %.*s",
|
||||
len, (u_char*)buffer_ptr(cmd));
|
||||
channel_request_start(id, "exec", 1);
|
||||
client_expect_confirm(id, "exec", CONFIRM_CLOSE);
|
||||
channel_request_start(ssh, id, "exec", 1);
|
||||
client_expect_confirm(ssh, id, "exec", CONFIRM_CLOSE);
|
||||
}
|
||||
packet_put_string(buffer_ptr(cmd), buffer_len(cmd));
|
||||
packet_send();
|
||||
} else {
|
||||
channel_request_start(id, "shell", 1);
|
||||
client_expect_confirm(id, "shell", CONFIRM_CLOSE);
|
||||
channel_request_start(ssh, id, "shell", 1);
|
||||
client_expect_confirm(ssh, id, "shell", CONFIRM_CLOSE);
|
||||
packet_send();
|
||||
}
|
||||
}
|
||||
|
|
31
clientloop.h
31
clientloop.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: clientloop.h,v 1.33 2016/09/30 09:19:13 markus Exp $ */
|
||||
/* $OpenBSD: clientloop.h,v 1.34 2017/09/12 06:32:07 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -37,28 +37,31 @@
|
|||
|
||||
#include <termios.h>
|
||||
|
||||
struct ssh;
|
||||
|
||||
/* Client side main loop for the interactive session. */
|
||||
int client_loop(int, int, int);
|
||||
int client_x11_get_proto(const char *, const char *, u_int, u_int,
|
||||
char **, char **);
|
||||
int client_loop(struct ssh *, int, int, int);
|
||||
int client_x11_get_proto(struct ssh *, const char *, const char *,
|
||||
u_int, u_int, char **, char **);
|
||||
void client_global_request_reply_fwd(int, u_int32_t, void *);
|
||||
void client_session2_setup(int, int, int, const char *, struct termios *,
|
||||
int, Buffer *, char **);
|
||||
int client_request_tun_fwd(int, int, int);
|
||||
void client_session2_setup(struct ssh *, int, int, int,
|
||||
const char *, struct termios *, int, Buffer *, char **);
|
||||
int client_request_tun_fwd(struct ssh *, int, int, int);
|
||||
void client_stop_mux(void);
|
||||
|
||||
/* Escape filter for protocol 2 sessions */
|
||||
void *client_new_escape_filter_ctx(int);
|
||||
void client_filter_cleanup(int, void *);
|
||||
int client_simple_escape_filter(Channel *, char *, int);
|
||||
void client_filter_cleanup(struct ssh *, int, void *);
|
||||
int client_simple_escape_filter(struct ssh *, Channel *, char *, int);
|
||||
|
||||
/* Global request confirmation callbacks */
|
||||
typedef void global_confirm_cb(int, u_int32_t seq, void *);
|
||||
typedef void global_confirm_cb(struct ssh *, int, u_int32_t, void *);
|
||||
void client_register_global_confirm(global_confirm_cb *, void *);
|
||||
|
||||
/* Channel request confirmation callbacks */
|
||||
enum confirm_action { CONFIRM_WARN = 0, CONFIRM_CLOSE, CONFIRM_TTY };
|
||||
void client_expect_confirm(int, const char *, enum confirm_action);
|
||||
void client_expect_confirm(struct ssh *, int, const char *,
|
||||
enum confirm_action);
|
||||
|
||||
/* Multiplexing protocol version */
|
||||
#define SSHMUX_VER 4
|
||||
|
@ -73,8 +76,8 @@ void client_expect_confirm(int, const char *, enum confirm_action);
|
|||
#define SSHMUX_COMMAND_CANCEL_FWD 7 /* Cancel forwarding(s) */
|
||||
#define SSHMUX_COMMAND_PROXY 8 /* Open new connection */
|
||||
|
||||
void muxserver_listen(void);
|
||||
void muxserver_listen(struct ssh *);
|
||||
int muxclient(const char *);
|
||||
void mux_exit_message(Channel *, int);
|
||||
void mux_tty_alloc_failed(Channel *);
|
||||
void mux_exit_message(struct ssh *, Channel *, int);
|
||||
void mux_tty_alloc_failed(struct ssh *ssh, Channel *);
|
||||
|
||||
|
|
56
configure.ac
56
configure.ac
|
@ -163,8 +163,8 @@ if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
|
|||
OSSH_CHECK_CFLAG_COMPILE([-Wpointer-sign], [-Wno-pointer-sign])
|
||||
OSSH_CHECK_CFLAG_COMPILE([-Wunused-result], [-Wno-unused-result])
|
||||
OSSH_CHECK_CFLAG_COMPILE([-fno-strict-aliasing])
|
||||
OSSH_CHECK_CFLAG_COMPILE([-D_FORTIFY_SOURCE=2])
|
||||
if test "x$use_toolchain_hardening" = "x1"; then
|
||||
OSSH_CHECK_CFLAG_COMPILE([-D_FORTIFY_SOURCE=2])
|
||||
OSSH_CHECK_LDFLAG_LINK([-Wl,-z,relro])
|
||||
OSSH_CHECK_LDFLAG_LINK([-Wl,-z,now])
|
||||
OSSH_CHECK_LDFLAG_LINK([-Wl,-z,noexecstack])
|
||||
|
@ -289,6 +289,16 @@ AC_ARG_WITH([cflags],
|
|||
fi
|
||||
]
|
||||
)
|
||||
|
||||
AC_ARG_WITH([cflags-after],
|
||||
[ --with-cflags-after Specify additional flags to pass to compiler after configure],
|
||||
[
|
||||
if test -n "$withval" && test "x$withval" != "xno" && \
|
||||
test "x${withval}" != "xyes"; then
|
||||
CFLAGS_AFTER="$withval"
|
||||
fi
|
||||
]
|
||||
)
|
||||
AC_ARG_WITH([cppflags],
|
||||
[ --with-cppflags Specify additional flags to pass to preprocessor] ,
|
||||
[
|
||||
|
@ -307,6 +317,15 @@ AC_ARG_WITH([ldflags],
|
|||
fi
|
||||
]
|
||||
)
|
||||
AC_ARG_WITH([ldflags-after],
|
||||
[ --with-ldflags-after Specify additional flags to pass to linker after configure],
|
||||
[
|
||||
if test -n "$withval" && test "x$withval" != "xno" && \
|
||||
test "x${withval}" != "xyes"; then
|
||||
LDFLAGS_AFTER="$withval"
|
||||
fi
|
||||
]
|
||||
)
|
||||
AC_ARG_WITH([libs],
|
||||
[ --with-libs Specify additional libraries to link with],
|
||||
[
|
||||
|
@ -370,7 +389,6 @@ AC_CHECK_HEADERS([ \
|
|||
sys/audit.h \
|
||||
sys/bitypes.h \
|
||||
sys/bsdtty.h \
|
||||
sys/capability.h \
|
||||
sys/cdefs.h \
|
||||
sys/dir.h \
|
||||
sys/mman.h \
|
||||
|
@ -402,6 +420,13 @@ AC_CHECK_HEADERS([ \
|
|||
wchar.h \
|
||||
])
|
||||
|
||||
# sys/capsicum.h requires sys/types.h
|
||||
AC_CHECK_HEADERS([sys/capsicum.h], [], [], [
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
])
|
||||
|
||||
# lastlog.h requires sys/time.h to be included first on Solaris
|
||||
AC_CHECK_HEADERS([lastlog.h], [], [], [
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
|
@ -1306,7 +1331,17 @@ AC_CHECK_FUNCS([fmt_scaled scan_scaled login logout openpty updwtmp logwtmp])
|
|||
AC_SEARCH_LIBS([inet_ntop], [resolv nsl])
|
||||
AC_SEARCH_LIBS([gethostbyname], [resolv nsl])
|
||||
|
||||
# "Particular Function Checks"
|
||||
# see https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Particular-Functions.html
|
||||
AC_FUNC_STRFTIME
|
||||
AC_FUNC_MALLOC
|
||||
AC_FUNC_REALLOC
|
||||
# autoconf doesn't have AC_FUNC_CALLOC so fake it if malloc returns NULL;
|
||||
if test "x$ac_cv_func_malloc_0_nonnull" != "xyes"; then
|
||||
AC_DEFINE(HAVE_CALLOC, 0, [calloc(x, 0) returns NULL])
|
||||
AC_DEFINE(calloc, rpl_calloc,
|
||||
[Define to rpl_calloc if the replacement function should be used.])
|
||||
fi
|
||||
|
||||
# Check for ALTDIRFUNC glob() extension
|
||||
AC_MSG_CHECKING([for GLOB_ALTDIRFUNC support])
|
||||
|
@ -1671,6 +1706,7 @@ AC_CHECK_FUNCS([ \
|
|||
fchmod \
|
||||
fchown \
|
||||
freeaddrinfo \
|
||||
freezero \
|
||||
fstatfs \
|
||||
fstatvfs \
|
||||
futimes \
|
||||
|
@ -1744,6 +1780,7 @@ AC_CHECK_FUNCS([ \
|
|||
strnlen \
|
||||
strnvis \
|
||||
strptime \
|
||||
strsignal \
|
||||
strtonum \
|
||||
strtoll \
|
||||
strtoul \
|
||||
|
@ -2512,7 +2549,11 @@ if test "x$openssl" = "xyes" ; then
|
|||
10000*|0*)
|
||||
AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")])
|
||||
;;
|
||||
*) ;;
|
||||
100*) ;; # 1.0.x
|
||||
200*) ;; # LibreSSL
|
||||
*)
|
||||
AC_MSG_ERROR([OpenSSL >= 1.1.0 is not yet supported (have "$ssl_library_ver")])
|
||||
;;
|
||||
esac
|
||||
AC_MSG_RESULT([$ssl_library_ver])
|
||||
],
|
||||
|
@ -3256,10 +3297,10 @@ elif test "x$sandbox_arg" = "xseccomp_filter" || \
|
|||
AC_DEFINE([SANDBOX_SECCOMP_FILTER], [1], [Sandbox using seccomp filter])
|
||||
elif test "x$sandbox_arg" = "xcapsicum" || \
|
||||
( test -z "$sandbox_arg" && \
|
||||
test "x$ac_cv_header_sys_capability_h" = "xyes" && \
|
||||
test "x$ac_cv_header_sys_capsicum_h" = "xyes" && \
|
||||
test "x$ac_cv_func_cap_rights_limit" = "xyes") ; then
|
||||
test "x$ac_cv_header_sys_capability_h" != "xyes" && \
|
||||
AC_MSG_ERROR([capsicum sandbox requires sys/capability.h header])
|
||||
test "x$ac_cv_header_sys_capsicum_h" != "xyes" && \
|
||||
AC_MSG_ERROR([capsicum sandbox requires sys/capsicum.h header])
|
||||
test "x$ac_cv_func_cap_rights_limit" != "xyes" && \
|
||||
AC_MSG_ERROR([capsicum sandbox requires cap_rights_limit function])
|
||||
SANDBOX_STYLE="capsicum"
|
||||
|
@ -5016,6 +5057,9 @@ AC_SUBST([TEST_SSH_UTF8], [$TEST_SSH_UTF8])
|
|||
AC_SUBST([TEST_MALLOC_OPTIONS], [$TEST_MALLOC_OPTIONS])
|
||||
AC_SUBST([UNSUPPORTED_ALGORITHMS], [$unsupported_algorithms])
|
||||
|
||||
CFLAGS="${CFLAGS} ${CFLAGS_AFTER}"
|
||||
LDFLAGS="${LDFLAGS} ${LDFLAGS_AFTER}"
|
||||
|
||||
AC_EXEEXT
|
||||
AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \
|
||||
openbsd-compat/Makefile openbsd-compat/regress/Makefile \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%define ver 7.5p1
|
||||
%define ver 7.6p1
|
||||
%define rel 1
|
||||
|
||||
# OpenSSH privilege separation requires a user & group ID
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 1999-2013 Philip Hands <phil@hands.com>
|
||||
# Copyright (c) 1999-2016 Philip Hands <phil@hands.com>
|
||||
# 2013 Martin Kletzander <mkletzan@redhat.com>
|
||||
# 2010 Adeodato =?iso-8859-1?Q?Sim=F3?= <asp16@alu.ua.es>
|
||||
# 2010 Eric Moret <eric.moret@gmail.com>
|
||||
|
@ -56,7 +56,8 @@ then
|
|||
fi
|
||||
fi
|
||||
|
||||
DEFAULT_PUB_ID_FILE="$HOME/$(cd "$HOME" ; ls -t .ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1)"
|
||||
most_recent_id="$(cd "$HOME" ; ls -t .ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1)"
|
||||
DEFAULT_PUB_ID_FILE="${most_recent_id:+$HOME/}$most_recent_id"
|
||||
|
||||
usage () {
|
||||
printf 'Usage: %s [-h|-?|-f|-n] [-i [identity_file]] [-p port] [[-o <ssh -o options>] ...] [user@]hostname\n' "$0" >&2
|
||||
|
@ -74,6 +75,11 @@ quote() {
|
|||
use_id_file() {
|
||||
local L_ID_FILE="$1"
|
||||
|
||||
if [ -z "$L_ID_FILE" ] ; then
|
||||
printf "%s: ERROR: no ID file found\n" "$0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if expr "$L_ID_FILE" : ".*\.pub$" >/dev/null ; then
|
||||
PUB_ID_FILE="$L_ID_FILE"
|
||||
else
|
||||
|
@ -287,9 +293,10 @@ case "$REMOTE_VERSION" in
|
|||
*)
|
||||
# Assuming that the remote host treats ~/.ssh/authorized_keys as one might expect
|
||||
populate_new_ids 0
|
||||
# in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX; 'cd' to be at $HOME; and all on one line, because tcsh.
|
||||
# in ssh below - to defend against quirky remote shells: use 'exec sh -c' to get POSIX;
|
||||
# 'cd' to be at $HOME; add a newline if it's missing; and all on one line, because tcsh.
|
||||
[ "$DRY_RUN" ] || printf '%s\n' "$NEW_IDS" | \
|
||||
ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \
|
||||
ssh "$@" "exec sh -c 'cd ; umask 077 ; mkdir -p .ssh && { [ -z "'`tail -1c .ssh/authorized_keys 2>/dev/null`'" ] || echo >> .ssh/authorized_keys ; } && cat >> .ssh/authorized_keys || exit 1 ; if type restorecon >/dev/null 2>&1 ; then restorecon -F .ssh .ssh/authorized_keys ; fi'" \
|
||||
|| exit 1
|
||||
ADDED=$(printf '%s\n' "$NEW_IDS" | wc -l)
|
||||
;;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
|
||||
Name: openssh
|
||||
Version: 7.5p1
|
||||
Version: 7.6p1
|
||||
URL: https://www.openssh.com/
|
||||
Release: 1
|
||||
Source0: openssh-%{version}.tar.gz
|
||||
|
|
2
dns.c
2
dns.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: dns.c,v 1.35 2015/08/20 22:32:42 deraadt Exp $ */
|
||||
/* $OpenBSD: dns.c,v 1.37 2017/09/14 04:32:21 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
|
||||
|
|
2
dns.h
2
dns.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: dns.h,v 1.15 2015/05/08 06:45:13 djm Exp $ */
|
||||
/* $OpenBSD: dns.h,v 1.17 2017/09/14 04:32:21 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Wesley Griffin. All rights reserved.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: monitor.c,v 1.172 2017/06/24 06:34:38 djm Exp $ */
|
||||
/* $OpenBSD: monitor.c,v 1.174 2017/10/02 19:33:20 djm Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
|
@ -760,10 +760,12 @@ mm_answer_pwnamallow(int sock, Buffer *m)
|
|||
for (i = 0; i < options.nx; i++) \
|
||||
buffer_put_cstring(m, options.x[i]); \
|
||||
} while (0)
|
||||
#define M_CP_STRARRAYOPT_ALLOC(x, nx) M_CP_STRARRAYOPT(x, nx)
|
||||
/* See comment in servconf.h */
|
||||
COPY_MATCH_STRING_OPTS();
|
||||
#undef M_CP_STROPT
|
||||
#undef M_CP_STRARRAYOPT
|
||||
#undef M_CP_STRARRAYOPT_ALLOC
|
||||
|
||||
/* Create valid auth method lists */
|
||||
if (auth2_setup_methods_lists(authctxt) != 0) {
|
||||
|
@ -1519,13 +1521,14 @@ mm_answer_pty_cleanup(int sock, Buffer *m)
|
|||
int
|
||||
mm_answer_term(int sock, Buffer *req)
|
||||
{
|
||||
struct ssh *ssh = active_state; /* XXX */
|
||||
extern struct monitor *pmonitor;
|
||||
int res, status;
|
||||
|
||||
debug3("%s: tearing down sessions", __func__);
|
||||
|
||||
/* The child is terminating */
|
||||
session_destroy_all(&mm_session_close);
|
||||
session_destroy_all(ssh, &mm_session_close);
|
||||
|
||||
#ifdef USE_PAM
|
||||
if (options.use_pam)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: monitor_wrap.c,v 1.92 2017/05/30 14:10:53 markus Exp $ */
|
||||
/* $OpenBSD: monitor_wrap.c,v 1.94 2017/10/02 19:33:20 djm Exp $ */
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* Copyright 2002 Markus Friedl <markus@openbsd.org>
|
||||
|
@ -242,6 +242,7 @@ mm_key_sign(struct sshkey *key, u_char **sigp, u_int *lenp,
|
|||
struct passwd *
|
||||
mm_getpwnamallow(const char *username)
|
||||
{
|
||||
struct ssh *ssh = active_state; /* XXX */
|
||||
Buffer m;
|
||||
struct passwd *pw;
|
||||
u_int len, i;
|
||||
|
@ -289,13 +290,20 @@ out:
|
|||
for (i = 0; i < newopts->nx; i++) \
|
||||
newopts->x[i] = buffer_get_string(&m, NULL); \
|
||||
} while (0)
|
||||
#define M_CP_STRARRAYOPT_ALLOC(x, nx) do { \
|
||||
newopts->x = newopts->nx == 0 ? \
|
||||
NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \
|
||||
M_CP_STRARRAYOPT(x, nx); \
|
||||
} while (0)
|
||||
/* See comment in servconf.h */
|
||||
COPY_MATCH_STRING_OPTS();
|
||||
#undef M_CP_STROPT
|
||||
#undef M_CP_STRARRAYOPT
|
||||
#undef M_CP_STRARRAYOPT_ALLOC
|
||||
|
||||
copy_set_server_options(&options, newopts, 1);
|
||||
log_change_level(options.log_level);
|
||||
process_permitopen(ssh, &options);
|
||||
free(newopts);
|
||||
|
||||
buffer_free(&m);
|
||||
|
|
209
mux.c
209
mux.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: mux.c,v 1.65 2017/06/09 06:47:13 djm Exp $ */
|
||||
/* $OpenBSD: mux.c,v 1.69 2017/09/20 05:19:00 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
|
@ -161,22 +161,32 @@ struct mux_master_state {
|
|||
#define MUX_FWD_REMOTE 2
|
||||
#define MUX_FWD_DYNAMIC 3
|
||||
|
||||
static void mux_session_confirm(int, int, void *);
|
||||
static void mux_stdio_confirm(int, int, void *);
|
||||
static void mux_session_confirm(struct ssh *, int, int, void *);
|
||||
static void mux_stdio_confirm(struct ssh *, int, int, void *);
|
||||
|
||||
static int process_mux_master_hello(u_int, Channel *, Buffer *, Buffer *);
|
||||
static int process_mux_new_session(u_int, Channel *, Buffer *, Buffer *);
|
||||
static int process_mux_alive_check(u_int, Channel *, Buffer *, Buffer *);
|
||||
static int process_mux_terminate(u_int, Channel *, Buffer *, Buffer *);
|
||||
static int process_mux_open_fwd(u_int, Channel *, Buffer *, Buffer *);
|
||||
static int process_mux_close_fwd(u_int, Channel *, Buffer *, Buffer *);
|
||||
static int process_mux_stdio_fwd(u_int, Channel *, Buffer *, Buffer *);
|
||||
static int process_mux_stop_listening(u_int, Channel *, Buffer *, Buffer *);
|
||||
static int process_mux_proxy(u_int, Channel *, Buffer *, Buffer *);
|
||||
static int process_mux_master_hello(struct ssh *, u_int,
|
||||
Channel *, struct sshbuf *, struct sshbuf *);
|
||||
static int process_mux_new_session(struct ssh *, u_int,
|
||||
Channel *, struct sshbuf *, struct sshbuf *);
|
||||
static int process_mux_alive_check(struct ssh *, u_int,
|
||||
Channel *, struct sshbuf *, struct sshbuf *);
|
||||
static int process_mux_terminate(struct ssh *, u_int,
|
||||
Channel *, struct sshbuf *, struct sshbuf *);
|
||||
static int process_mux_open_fwd(struct ssh *, u_int,
|
||||
Channel *, struct sshbuf *, struct sshbuf *);
|
||||
static int process_mux_close_fwd(struct ssh *, u_int,
|
||||
Channel *, struct sshbuf *, struct sshbuf *);
|
||||
static int process_mux_stdio_fwd(struct ssh *, u_int,
|
||||
Channel *, struct sshbuf *, struct sshbuf *);
|
||||
static int process_mux_stop_listening(struct ssh *, u_int,
|
||||
Channel *, struct sshbuf *, struct sshbuf *);
|
||||
static int process_mux_proxy(struct ssh *, u_int,
|
||||
Channel *, struct sshbuf *, struct sshbuf *);
|
||||
|
||||
static const struct {
|
||||
u_int type;
|
||||
int (*handler)(u_int, Channel *, Buffer *, Buffer *);
|
||||
int (*handler)(struct ssh *, u_int, Channel *,
|
||||
struct sshbuf *, struct sshbuf *);
|
||||
} mux_master_handlers[] = {
|
||||
{ MUX_MSG_HELLO, process_mux_master_hello },
|
||||
{ MUX_C_NEW_SESSION, process_mux_new_session },
|
||||
|
@ -193,52 +203,54 @@ static const struct {
|
|||
/* Cleanup callback fired on closure of mux slave _session_ channel */
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
mux_master_session_cleanup_cb(int cid, void *unused)
|
||||
mux_master_session_cleanup_cb(struct ssh *ssh, int cid, void *unused)
|
||||
{
|
||||
Channel *cc, *c = channel_by_id(cid);
|
||||
Channel *cc, *c = channel_by_id(ssh, cid);
|
||||
|
||||
debug3("%s: entering for channel %d", __func__, cid);
|
||||
if (c == NULL)
|
||||
fatal("%s: channel_by_id(%i) == NULL", __func__, cid);
|
||||
if (c->ctl_chan != -1) {
|
||||
if ((cc = channel_by_id(c->ctl_chan)) == NULL)
|
||||
if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
|
||||
fatal("%s: channel %d missing control channel %d",
|
||||
__func__, c->self, c->ctl_chan);
|
||||
c->ctl_chan = -1;
|
||||
cc->remote_id = -1;
|
||||
chan_rcvd_oclose(cc);
|
||||
cc->remote_id = 0;
|
||||
cc->have_remote_id = 0;
|
||||
chan_rcvd_oclose(ssh, cc);
|
||||
}
|
||||
channel_cancel_cleanup(c->self);
|
||||
channel_cancel_cleanup(ssh, c->self);
|
||||
}
|
||||
|
||||
/* Cleanup callback fired on closure of mux slave _control_ channel */
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
mux_master_control_cleanup_cb(int cid, void *unused)
|
||||
mux_master_control_cleanup_cb(struct ssh *ssh, int cid, void *unused)
|
||||
{
|
||||
Channel *sc, *c = channel_by_id(cid);
|
||||
Channel *sc, *c = channel_by_id(ssh, cid);
|
||||
|
||||
debug3("%s: entering for channel %d", __func__, cid);
|
||||
if (c == NULL)
|
||||
fatal("%s: channel_by_id(%i) == NULL", __func__, cid);
|
||||
if (c->remote_id != -1) {
|
||||
if ((sc = channel_by_id(c->remote_id)) == NULL)
|
||||
fatal("%s: channel %d missing session channel %d",
|
||||
if (c->have_remote_id) {
|
||||
if ((sc = channel_by_id(ssh, c->remote_id)) == NULL)
|
||||
fatal("%s: channel %d missing session channel %u",
|
||||
__func__, c->self, c->remote_id);
|
||||
c->remote_id = -1;
|
||||
c->remote_id = 0;
|
||||
c->have_remote_id = 0;
|
||||
sc->ctl_chan = -1;
|
||||
if (sc->type != SSH_CHANNEL_OPEN &&
|
||||
sc->type != SSH_CHANNEL_OPENING) {
|
||||
debug2("%s: channel %d: not open", __func__, sc->self);
|
||||
chan_mark_dead(sc);
|
||||
chan_mark_dead(ssh, sc);
|
||||
} else {
|
||||
if (sc->istate == CHAN_INPUT_OPEN)
|
||||
chan_read_failed(sc);
|
||||
chan_read_failed(ssh, sc);
|
||||
if (sc->ostate == CHAN_OUTPUT_OPEN)
|
||||
chan_write_failed(sc);
|
||||
chan_write_failed(ssh, sc);
|
||||
}
|
||||
}
|
||||
channel_cancel_cleanup(c->self);
|
||||
channel_cancel_cleanup(ssh, c->self);
|
||||
}
|
||||
|
||||
/* Check mux client environment variables before passing them to mux master. */
|
||||
|
@ -266,7 +278,8 @@ env_permitted(char *env)
|
|||
/* Mux master protocol message handlers */
|
||||
|
||||
static int
|
||||
process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
||||
process_mux_master_hello(struct ssh *ssh, u_int rid,
|
||||
Channel *c, Buffer *m, Buffer *r)
|
||||
{
|
||||
u_int ver;
|
||||
struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
|
||||
|
@ -308,7 +321,8 @@ process_mux_master_hello(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
}
|
||||
|
||||
static int
|
||||
process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
||||
process_mux_new_session(struct ssh *ssh, u_int rid,
|
||||
Channel *c, Buffer *m, Buffer *r)
|
||||
{
|
||||
Channel *nc;
|
||||
struct mux_session_confirm_ctx *cctx;
|
||||
|
@ -401,7 +415,7 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
new_fd[0], new_fd[1], new_fd[2]);
|
||||
|
||||
/* XXX support multiple child sessions in future */
|
||||
if (c->remote_id != -1) {
|
||||
if (c->have_remote_id) {
|
||||
debug2("%s: session already open", __func__);
|
||||
/* prepare reply */
|
||||
buffer_put_int(r, MUX_S_FAILURE);
|
||||
|
@ -453,15 +467,16 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
packetmax >>= 1;
|
||||
}
|
||||
|
||||
nc = channel_new("session", SSH_CHANNEL_OPENING,
|
||||
nc = channel_new(ssh, "session", SSH_CHANNEL_OPENING,
|
||||
new_fd[0], new_fd[1], new_fd[2], window, packetmax,
|
||||
CHAN_EXTENDED_WRITE, "client-session", /*nonblock*/0);
|
||||
|
||||
nc->ctl_chan = c->self; /* link session -> control channel */
|
||||
c->remote_id = nc->self; /* link control -> session channel */
|
||||
c->have_remote_id = 1;
|
||||
|
||||
if (cctx->want_tty && escape_char != 0xffffffff) {
|
||||
channel_register_filter(nc->self,
|
||||
channel_register_filter(ssh, nc->self,
|
||||
client_simple_escape_filter, NULL,
|
||||
client_filter_cleanup,
|
||||
client_new_escape_filter_ctx((int)escape_char));
|
||||
|
@ -470,17 +485,19 @@ process_mux_new_session(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
debug2("%s: channel_new: %d linked to control channel %d",
|
||||
__func__, nc->self, nc->ctl_chan);
|
||||
|
||||
channel_send_open(nc->self);
|
||||
channel_register_open_confirm(nc->self, mux_session_confirm, cctx);
|
||||
channel_send_open(ssh, nc->self);
|
||||
channel_register_open_confirm(ssh, nc->self, mux_session_confirm, cctx);
|
||||
c->mux_pause = 1; /* stop handling messages until open_confirm done */
|
||||
channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1);
|
||||
channel_register_cleanup(ssh, nc->self,
|
||||
mux_master_session_cleanup_cb, 1);
|
||||
|
||||
/* reply is deferred, sent by mux_session_confirm */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
process_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
||||
process_mux_alive_check(struct ssh *ssh, u_int rid,
|
||||
Channel *c, Buffer *m, Buffer *r)
|
||||
{
|
||||
debug2("%s: channel %d: alive check", __func__, c->self);
|
||||
|
||||
|
@ -493,7 +510,8 @@ process_mux_alive_check(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
}
|
||||
|
||||
static int
|
||||
process_mux_terminate(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
||||
process_mux_terminate(struct ssh *ssh, u_int rid,
|
||||
Channel *c, Buffer *m, Buffer *r)
|
||||
{
|
||||
debug2("%s: channel %d: terminate request", __func__, c->self);
|
||||
|
||||
|
@ -582,7 +600,7 @@ compare_forward(struct Forward *a, struct Forward *b)
|
|||
}
|
||||
|
||||
static void
|
||||
mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
|
||||
mux_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
|
||||
{
|
||||
struct mux_channel_confirm_ctx *fctx = ctxt;
|
||||
char *failmsg = NULL;
|
||||
|
@ -590,7 +608,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
|
|||
Channel *c;
|
||||
Buffer out;
|
||||
|
||||
if ((c = channel_by_id(fctx->cid)) == NULL) {
|
||||
if ((c = channel_by_id(ssh, fctx->cid)) == NULL) {
|
||||
/* no channel for reply */
|
||||
error("%s: unknown channel", __func__);
|
||||
return;
|
||||
|
@ -616,7 +634,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
|
|||
buffer_put_int(&out, MUX_S_REMOTE_PORT);
|
||||
buffer_put_int(&out, fctx->rid);
|
||||
buffer_put_int(&out, rfwd->allocated_port);
|
||||
channel_update_permitted_opens(rfwd->handle,
|
||||
channel_update_permitted_opens(ssh, rfwd->handle,
|
||||
rfwd->allocated_port);
|
||||
} else {
|
||||
buffer_put_int(&out, MUX_S_OK);
|
||||
|
@ -625,7 +643,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
|
|||
goto out;
|
||||
} else {
|
||||
if (rfwd->listen_port == 0)
|
||||
channel_update_permitted_opens(rfwd->handle, -1);
|
||||
channel_update_permitted_opens(ssh, rfwd->handle, -1);
|
||||
if (rfwd->listen_path != NULL)
|
||||
xasprintf(&failmsg, "remote port forwarding failed for "
|
||||
"listen path %s", rfwd->listen_path);
|
||||
|
@ -651,7 +669,7 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
|
|||
buffer_put_cstring(&out, failmsg);
|
||||
free(failmsg);
|
||||
out:
|
||||
buffer_put_string(&c->output, buffer_ptr(&out), buffer_len(&out));
|
||||
buffer_put_string(c->output, buffer_ptr(&out), buffer_len(&out));
|
||||
buffer_free(&out);
|
||||
if (c->mux_pause <= 0)
|
||||
fatal("%s: mux_pause %d", __func__, c->mux_pause);
|
||||
|
@ -659,7 +677,8 @@ mux_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
|
|||
}
|
||||
|
||||
static int
|
||||
process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
||||
process_mux_open_fwd(struct ssh *ssh, u_int rid,
|
||||
Channel *c, Buffer *m, Buffer *r)
|
||||
{
|
||||
struct Forward fwd;
|
||||
char *fwd_desc = NULL;
|
||||
|
@ -727,13 +746,16 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
fwd.listen_port);
|
||||
goto invalid;
|
||||
}
|
||||
if ((fwd.connect_port != PORT_STREAMLOCAL && fwd.connect_port >= 65536)
|
||||
|| (ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE && fwd.connect_port == 0)) {
|
||||
if ((fwd.connect_port != PORT_STREAMLOCAL &&
|
||||
fwd.connect_port >= 65536) ||
|
||||
(ftype != MUX_FWD_DYNAMIC && ftype != MUX_FWD_REMOTE &&
|
||||
fwd.connect_port == 0)) {
|
||||
logit("%s: invalid connect port %u", __func__,
|
||||
fwd.connect_port);
|
||||
goto invalid;
|
||||
}
|
||||
if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL && fwd.connect_path == NULL) {
|
||||
if (ftype != MUX_FWD_DYNAMIC && fwd.connect_host == NULL &&
|
||||
fwd.connect_path == NULL) {
|
||||
logit("%s: missing connect host", __func__);
|
||||
goto invalid;
|
||||
}
|
||||
|
@ -784,7 +806,7 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
}
|
||||
|
||||
if (ftype == MUX_FWD_LOCAL || ftype == MUX_FWD_DYNAMIC) {
|
||||
if (!channel_setup_local_fwd_listener(&fwd,
|
||||
if (!channel_setup_local_fwd_listener(ssh, &fwd,
|
||||
&options.fwd_opts)) {
|
||||
fail:
|
||||
logit("slave-requested %s failed", fwd_desc);
|
||||
|
@ -798,7 +820,7 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
} else {
|
||||
struct mux_channel_confirm_ctx *fctx;
|
||||
|
||||
fwd.handle = channel_request_remote_forwarding(&fwd);
|
||||
fwd.handle = channel_request_remote_forwarding(ssh, &fwd);
|
||||
if (fwd.handle < 0)
|
||||
goto fail;
|
||||
add_remote_forward(&options, &fwd);
|
||||
|
@ -827,7 +849,8 @@ process_mux_open_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
}
|
||||
|
||||
static int
|
||||
process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
||||
process_mux_close_fwd(struct ssh *ssh, u_int rid,
|
||||
Channel *c, Buffer *m, Buffer *r)
|
||||
{
|
||||
struct Forward fwd, *found_fwd;
|
||||
char *fwd_desc = NULL;
|
||||
|
@ -908,11 +931,11 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
* However, for dynamic allocated listen ports we need
|
||||
* to use the actual listen port.
|
||||
*/
|
||||
if (channel_request_rforward_cancel(found_fwd) == -1)
|
||||
if (channel_request_rforward_cancel(ssh, found_fwd) == -1)
|
||||
error_reason = "port not in permitted opens";
|
||||
} else { /* local and dynamic forwards */
|
||||
/* Ditto */
|
||||
if (channel_cancel_lport_listener(&fwd, fwd.connect_port,
|
||||
if (channel_cancel_lport_listener(ssh, &fwd, fwd.connect_port,
|
||||
&options.fwd_opts) == -1)
|
||||
error_reason = "port not found";
|
||||
}
|
||||
|
@ -942,7 +965,8 @@ process_mux_close_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
}
|
||||
|
||||
static int
|
||||
process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
||||
process_mux_stdio_fwd(struct ssh *ssh, u_int rid,
|
||||
Channel *c, Buffer *m, Buffer *r)
|
||||
{
|
||||
Channel *nc;
|
||||
char *reserved, *chost;
|
||||
|
@ -986,7 +1010,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
new_fd[0], new_fd[1]);
|
||||
|
||||
/* XXX support multiple child sessions in future */
|
||||
if (c->remote_id != -1) {
|
||||
if (c->have_remote_id) {
|
||||
debug2("%s: session already open", __func__);
|
||||
/* prepare reply */
|
||||
buffer_put_int(r, MUX_S_FAILURE);
|
||||
|
@ -1018,19 +1042,21 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
if (!isatty(new_fd[1]))
|
||||
set_nonblock(new_fd[1]);
|
||||
|
||||
nc = channel_connect_stdio_fwd(chost, cport, new_fd[0], new_fd[1]);
|
||||
nc = channel_connect_stdio_fwd(ssh, chost, cport, new_fd[0], new_fd[1]);
|
||||
|
||||
nc->ctl_chan = c->self; /* link session -> control channel */
|
||||
c->remote_id = nc->self; /* link control -> session channel */
|
||||
c->have_remote_id = 1;
|
||||
|
||||
debug2("%s: channel_new: %d linked to control channel %d",
|
||||
__func__, nc->self, nc->ctl_chan);
|
||||
|
||||
channel_register_cleanup(nc->self, mux_master_session_cleanup_cb, 1);
|
||||
channel_register_cleanup(ssh, nc->self,
|
||||
mux_master_session_cleanup_cb, 1);
|
||||
|
||||
cctx = xcalloc(1, sizeof(*cctx));
|
||||
cctx->rid = rid;
|
||||
channel_register_open_confirm(nc->self, mux_stdio_confirm, cctx);
|
||||
channel_register_open_confirm(ssh, nc->self, mux_stdio_confirm, cctx);
|
||||
c->mux_pause = 1; /* stop handling messages until open_confirm done */
|
||||
|
||||
/* reply is deferred, sent by mux_session_confirm */
|
||||
|
@ -1039,7 +1065,7 @@ process_mux_stdio_fwd(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
|
||||
/* Callback on open confirmation in mux master for a mux stdio fwd session. */
|
||||
static void
|
||||
mux_stdio_confirm(int id, int success, void *arg)
|
||||
mux_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
|
||||
{
|
||||
struct mux_stdio_confirm_ctx *cctx = arg;
|
||||
Channel *c, *cc;
|
||||
|
@ -1047,9 +1073,9 @@ mux_stdio_confirm(int id, int success, void *arg)
|
|||
|
||||
if (cctx == NULL)
|
||||
fatal("%s: cctx == NULL", __func__);
|
||||
if ((c = channel_by_id(id)) == NULL)
|
||||
if ((c = channel_by_id(ssh, id)) == NULL)
|
||||
fatal("%s: no channel for id %d", __func__, id);
|
||||
if ((cc = channel_by_id(c->ctl_chan)) == NULL)
|
||||
if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
|
||||
fatal("%s: channel %d lacks control channel %d", __func__,
|
||||
id, c->ctl_chan);
|
||||
|
||||
|
@ -1072,7 +1098,7 @@ mux_stdio_confirm(int id, int success, void *arg)
|
|||
|
||||
done:
|
||||
/* Send reply */
|
||||
buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply));
|
||||
buffer_put_string(cc->output, buffer_ptr(&reply), buffer_len(&reply));
|
||||
buffer_free(&reply);
|
||||
|
||||
if (cc->mux_pause <= 0)
|
||||
|
@ -1083,7 +1109,8 @@ mux_stdio_confirm(int id, int success, void *arg)
|
|||
}
|
||||
|
||||
static int
|
||||
process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
||||
process_mux_stop_listening(struct ssh *ssh, u_int rid,
|
||||
Channel *c, Buffer *m, Buffer *r)
|
||||
{
|
||||
debug("%s: channel %d: stop listening", __func__, c->self);
|
||||
|
||||
|
@ -1100,7 +1127,7 @@ process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
}
|
||||
|
||||
if (mux_listener_channel != NULL) {
|
||||
channel_free(mux_listener_channel);
|
||||
channel_free(ssh, mux_listener_channel);
|
||||
client_stop_mux();
|
||||
free(options.control_path);
|
||||
options.control_path = NULL;
|
||||
|
@ -1116,7 +1143,8 @@ process_mux_stop_listening(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
}
|
||||
|
||||
static int
|
||||
process_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
||||
process_mux_proxy(struct ssh *ssh, u_int rid,
|
||||
Channel *c, Buffer *m, Buffer *r)
|
||||
{
|
||||
debug("%s: channel %d: proxy request", __func__, c->self);
|
||||
|
||||
|
@ -1129,7 +1157,7 @@ process_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r)
|
|||
|
||||
/* Channel callbacks fired on read/write from mux slave fd */
|
||||
static int
|
||||
mux_master_read_cb(Channel *c)
|
||||
mux_master_read_cb(struct ssh *ssh, Channel *c)
|
||||
{
|
||||
struct mux_master_state *state = (struct mux_master_state *)c->mux_ctx;
|
||||
Buffer in, out;
|
||||
|
@ -1141,7 +1169,7 @@ mux_master_read_cb(Channel *c)
|
|||
if (c->mux_ctx == NULL) {
|
||||
state = xcalloc(1, sizeof(*state));
|
||||
c->mux_ctx = state;
|
||||
channel_register_cleanup(c->self,
|
||||
channel_register_cleanup(ssh, c->self,
|
||||
mux_master_control_cleanup_cb, 0);
|
||||
|
||||
/* Send hello */
|
||||
|
@ -1149,7 +1177,7 @@ mux_master_read_cb(Channel *c)
|
|||
buffer_put_int(&out, MUX_MSG_HELLO);
|
||||
buffer_put_int(&out, SSHMUX_VER);
|
||||
/* no extensions */
|
||||
buffer_put_string(&c->output, buffer_ptr(&out),
|
||||
buffer_put_string(c->output, buffer_ptr(&out),
|
||||
buffer_len(&out));
|
||||
buffer_free(&out);
|
||||
debug3("%s: channel %d: hello sent", __func__, c->self);
|
||||
|
@ -1160,7 +1188,7 @@ mux_master_read_cb(Channel *c)
|
|||
buffer_init(&out);
|
||||
|
||||
/* Channel code ensures that we receive whole packets */
|
||||
if ((ptr = buffer_get_string_ptr_ret(&c->input, &have)) == NULL) {
|
||||
if ((ptr = buffer_get_string_ptr_ret(c->input, &have)) == NULL) {
|
||||
malf:
|
||||
error("%s: malformed message", __func__);
|
||||
goto out;
|
||||
|
@ -1186,7 +1214,8 @@ mux_master_read_cb(Channel *c)
|
|||
|
||||
for (i = 0; mux_master_handlers[i].handler != NULL; i++) {
|
||||
if (type == mux_master_handlers[i].type) {
|
||||
ret = mux_master_handlers[i].handler(rid, c, &in, &out);
|
||||
ret = mux_master_handlers[i].handler(ssh, rid,
|
||||
c, &in, &out);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1199,7 +1228,7 @@ mux_master_read_cb(Channel *c)
|
|||
}
|
||||
/* Enqueue reply packet */
|
||||
if (buffer_len(&out) != 0) {
|
||||
buffer_put_string(&c->output, buffer_ptr(&out),
|
||||
buffer_put_string(c->output, buffer_ptr(&out),
|
||||
buffer_len(&out));
|
||||
}
|
||||
out:
|
||||
|
@ -1209,7 +1238,7 @@ mux_master_read_cb(Channel *c)
|
|||
}
|
||||
|
||||
void
|
||||
mux_exit_message(Channel *c, int exitval)
|
||||
mux_exit_message(struct ssh *ssh, Channel *c, int exitval)
|
||||
{
|
||||
Buffer m;
|
||||
Channel *mux_chan;
|
||||
|
@ -1217,7 +1246,7 @@ mux_exit_message(Channel *c, int exitval)
|
|||
debug3("%s: channel %d: exit message, exitval %d", __func__, c->self,
|
||||
exitval);
|
||||
|
||||
if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL)
|
||||
if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL)
|
||||
fatal("%s: channel %d missing mux channel %d",
|
||||
__func__, c->self, c->ctl_chan);
|
||||
|
||||
|
@ -1227,19 +1256,19 @@ mux_exit_message(Channel *c, int exitval)
|
|||
buffer_put_int(&m, c->self);
|
||||
buffer_put_int(&m, exitval);
|
||||
|
||||
buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m));
|
||||
buffer_put_string(mux_chan->output, buffer_ptr(&m), buffer_len(&m));
|
||||
buffer_free(&m);
|
||||
}
|
||||
|
||||
void
|
||||
mux_tty_alloc_failed(Channel *c)
|
||||
mux_tty_alloc_failed(struct ssh *ssh, Channel *c)
|
||||
{
|
||||
Buffer m;
|
||||
Channel *mux_chan;
|
||||
|
||||
debug3("%s: channel %d: TTY alloc failed", __func__, c->self);
|
||||
|
||||
if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL)
|
||||
if ((mux_chan = channel_by_id(ssh, c->ctl_chan)) == NULL)
|
||||
fatal("%s: channel %d missing mux channel %d",
|
||||
__func__, c->self, c->ctl_chan);
|
||||
|
||||
|
@ -1248,13 +1277,13 @@ mux_tty_alloc_failed(Channel *c)
|
|||
buffer_put_int(&m, MUX_S_TTY_ALLOC_FAIL);
|
||||
buffer_put_int(&m, c->self);
|
||||
|
||||
buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m));
|
||||
buffer_put_string(mux_chan->output, buffer_ptr(&m), buffer_len(&m));
|
||||
buffer_free(&m);
|
||||
}
|
||||
|
||||
/* Prepare a mux master to listen on a Unix domain socket. */
|
||||
void
|
||||
muxserver_listen(void)
|
||||
muxserver_listen(struct ssh *ssh)
|
||||
{
|
||||
mode_t old_umask;
|
||||
char *orig_control_path = options.control_path;
|
||||
|
@ -1327,7 +1356,7 @@ muxserver_listen(void)
|
|||
|
||||
set_nonblock(muxserver_sock);
|
||||
|
||||
mux_listener_channel = channel_new("mux listener",
|
||||
mux_listener_channel = channel_new(ssh, "mux listener",
|
||||
SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1,
|
||||
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
|
||||
0, options.control_path, 1);
|
||||
|
@ -1338,7 +1367,7 @@ muxserver_listen(void)
|
|||
|
||||
/* Callback on open confirmation in mux master for a mux client session. */
|
||||
static void
|
||||
mux_session_confirm(int id, int success, void *arg)
|
||||
mux_session_confirm(struct ssh *ssh, int id, int success, void *arg)
|
||||
{
|
||||
struct mux_session_confirm_ctx *cctx = arg;
|
||||
const char *display;
|
||||
|
@ -1348,9 +1377,9 @@ mux_session_confirm(int id, int success, void *arg)
|
|||
|
||||
if (cctx == NULL)
|
||||
fatal("%s: cctx == NULL", __func__);
|
||||
if ((c = channel_by_id(id)) == NULL)
|
||||
if ((c = channel_by_id(ssh, id)) == NULL)
|
||||
fatal("%s: no channel for id %d", __func__, id);
|
||||
if ((cc = channel_by_id(c->ctl_chan)) == NULL)
|
||||
if ((cc = channel_by_id(ssh, c->ctl_chan)) == NULL)
|
||||
fatal("%s: channel %d lacks control channel %d", __func__,
|
||||
id, c->ctl_chan);
|
||||
|
||||
|
@ -1369,27 +1398,27 @@ mux_session_confirm(int id, int success, void *arg)
|
|||
char *proto, *data;
|
||||
|
||||
/* Get reasonable local authentication information. */
|
||||
if (client_x11_get_proto(display, options.xauth_location,
|
||||
if (client_x11_get_proto(ssh, display, options.xauth_location,
|
||||
options.forward_x11_trusted, options.forward_x11_timeout,
|
||||
&proto, &data) == 0) {
|
||||
/* Request forwarding with authentication spoofing. */
|
||||
debug("Requesting X11 forwarding with authentication "
|
||||
"spoofing.");
|
||||
x11_request_forwarding_with_spoofing(id, display, proto,
|
||||
data, 1);
|
||||
x11_request_forwarding_with_spoofing(ssh, id,
|
||||
display, proto, data, 1);
|
||||
/* XXX exit_on_forward_failure */
|
||||
client_expect_confirm(id, "X11 forwarding",
|
||||
client_expect_confirm(ssh, id, "X11 forwarding",
|
||||
CONFIRM_WARN);
|
||||
}
|
||||
}
|
||||
|
||||
if (cctx->want_agent_fwd && options.forward_agent) {
|
||||
debug("Requesting authentication agent forwarding.");
|
||||
channel_request_start(id, "auth-agent-req@openssh.com", 0);
|
||||
channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0);
|
||||
packet_send();
|
||||
}
|
||||
|
||||
client_session2_setup(id, cctx->want_tty, cctx->want_subsys,
|
||||
client_session2_setup(ssh, id, cctx->want_tty, cctx->want_subsys,
|
||||
cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env);
|
||||
|
||||
debug3("%s: sending success reply", __func__);
|
||||
|
@ -1401,7 +1430,7 @@ mux_session_confirm(int id, int success, void *arg)
|
|||
|
||||
done:
|
||||
/* Send reply */
|
||||
buffer_put_string(&cc->output, buffer_ptr(&reply), buffer_len(&reply));
|
||||
buffer_put_string(cc->output, buffer_ptr(&reply), buffer_len(&reply));
|
||||
buffer_free(&reply);
|
||||
|
||||
if (cc->mux_pause <= 0)
|
||||
|
@ -1972,7 +2001,7 @@ mux_client_request_session(int fd)
|
|||
leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
|
||||
|
||||
if (muxclient_terminate) {
|
||||
debug2("Exiting on signal %d", muxclient_terminate);
|
||||
debug2("Exiting on signal: %s", strsignal(muxclient_terminate));
|
||||
exitval = 255;
|
||||
} else if (!exitval_seen) {
|
||||
debug2("Control master terminated unexpectedly");
|
||||
|
|
122
nchan.c
122
nchan.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: nchan.c,v 1.65 2017/04/30 23:28:42 djm Exp $ */
|
||||
/* $OpenBSD: nchan.c,v 1.67 2017/09/12 06:35:32 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
|
||||
*
|
||||
|
@ -34,7 +34,8 @@
|
|||
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
#include "ssh2.h"
|
||||
#include "buffer.h"
|
||||
#include "sshbuf.h"
|
||||
#include "ssherr.h"
|
||||
#include "packet.h"
|
||||
#include "channels.h"
|
||||
#include "compat.h"
|
||||
|
@ -73,15 +74,15 @@
|
|||
/*
|
||||
* ACTIONS: should never update the channel states
|
||||
*/
|
||||
static void chan_send_eof2(Channel *);
|
||||
static void chan_send_eow2(Channel *);
|
||||
static void chan_send_eof2(struct ssh *, Channel *);
|
||||
static void chan_send_eow2(struct ssh *, Channel *);
|
||||
|
||||
/* helper */
|
||||
static void chan_shutdown_write(Channel *);
|
||||
static void chan_shutdown_read(Channel *);
|
||||
static void chan_shutdown_write(struct ssh *, Channel *);
|
||||
static void chan_shutdown_read(struct ssh *, Channel *);
|
||||
|
||||
static char *ostates[] = { "open", "drain", "wait_ieof", "closed" };
|
||||
static char *istates[] = { "open", "drain", "wait_oclose", "closed" };
|
||||
static const char *ostates[] = { "open", "drain", "wait_ieof", "closed" };
|
||||
static const char *istates[] = { "open", "drain", "wait_oclose", "closed" };
|
||||
|
||||
static void
|
||||
chan_set_istate(Channel *c, u_int next)
|
||||
|
@ -104,12 +105,12 @@ chan_set_ostate(Channel *c, u_int next)
|
|||
}
|
||||
|
||||
void
|
||||
chan_read_failed(Channel *c)
|
||||
chan_read_failed(struct ssh *ssh, Channel *c)
|
||||
{
|
||||
debug2("channel %d: read failed", c->self);
|
||||
switch (c->istate) {
|
||||
case CHAN_INPUT_OPEN:
|
||||
chan_shutdown_read(c);
|
||||
chan_shutdown_read(ssh, c);
|
||||
chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN);
|
||||
break;
|
||||
default:
|
||||
|
@ -120,10 +121,10 @@ chan_read_failed(Channel *c)
|
|||
}
|
||||
|
||||
void
|
||||
chan_ibuf_empty(Channel *c)
|
||||
chan_ibuf_empty(struct ssh *ssh, Channel *c)
|
||||
{
|
||||
debug2("channel %d: ibuf empty", c->self);
|
||||
if (buffer_len(&c->input)) {
|
||||
if (sshbuf_len(c->input)) {
|
||||
error("channel %d: chan_ibuf_empty for non empty buffer",
|
||||
c->self);
|
||||
return;
|
||||
|
@ -131,7 +132,7 @@ chan_ibuf_empty(Channel *c)
|
|||
switch (c->istate) {
|
||||
case CHAN_INPUT_WAIT_DRAIN:
|
||||
if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))
|
||||
chan_send_eof2(c);
|
||||
chan_send_eof2(ssh, c);
|
||||
chan_set_istate(c, CHAN_INPUT_CLOSED);
|
||||
break;
|
||||
default:
|
||||
|
@ -142,17 +143,17 @@ chan_ibuf_empty(Channel *c)
|
|||
}
|
||||
|
||||
void
|
||||
chan_obuf_empty(Channel *c)
|
||||
chan_obuf_empty(struct ssh *ssh, Channel *c)
|
||||
{
|
||||
debug2("channel %d: obuf empty", c->self);
|
||||
if (buffer_len(&c->output)) {
|
||||
if (sshbuf_len(c->output)) {
|
||||
error("channel %d: chan_obuf_empty for non empty buffer",
|
||||
c->self);
|
||||
return;
|
||||
}
|
||||
switch (c->ostate) {
|
||||
case CHAN_OUTPUT_WAIT_DRAIN:
|
||||
chan_shutdown_write(c);
|
||||
chan_shutdown_write(ssh, c);
|
||||
chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
|
||||
break;
|
||||
default:
|
||||
|
@ -163,26 +164,32 @@ chan_obuf_empty(Channel *c)
|
|||
}
|
||||
|
||||
void
|
||||
chan_rcvd_eow(Channel *c)
|
||||
chan_rcvd_eow(struct ssh *ssh, Channel *c)
|
||||
{
|
||||
debug2("channel %d: rcvd eow", c->self);
|
||||
switch (c->istate) {
|
||||
case CHAN_INPUT_OPEN:
|
||||
chan_shutdown_read(c);
|
||||
chan_shutdown_read(ssh, c);
|
||||
chan_set_istate(c, CHAN_INPUT_CLOSED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
chan_send_eof2(Channel *c)
|
||||
chan_send_eof2(struct ssh *ssh, Channel *c)
|
||||
{
|
||||
int r;
|
||||
|
||||
debug2("channel %d: send eof", c->self);
|
||||
switch (c->istate) {
|
||||
case CHAN_INPUT_WAIT_DRAIN:
|
||||
packet_start(SSH2_MSG_CHANNEL_EOF);
|
||||
packet_put_int(c->remote_id);
|
||||
packet_send();
|
||||
if (!c->have_remote_id)
|
||||
fatal("%s: channel %d: no remote_id",
|
||||
__func__, c->self);
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_EOF)) != 0 ||
|
||||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0)
|
||||
fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
|
||||
c->flags |= CHAN_EOF_SENT;
|
||||
break;
|
||||
default:
|
||||
|
@ -193,8 +200,10 @@ chan_send_eof2(Channel *c)
|
|||
}
|
||||
|
||||
static void
|
||||
chan_send_close2(Channel *c)
|
||||
chan_send_close2(struct ssh *ssh, Channel *c)
|
||||
{
|
||||
int r;
|
||||
|
||||
debug2("channel %d: send close", c->self);
|
||||
if (c->ostate != CHAN_OUTPUT_CLOSED ||
|
||||
c->istate != CHAN_INPUT_CLOSED) {
|
||||
|
@ -203,16 +212,22 @@ chan_send_close2(Channel *c)
|
|||
} else if (c->flags & CHAN_CLOSE_SENT) {
|
||||
error("channel %d: already sent close", c->self);
|
||||
} else {
|
||||
packet_start(SSH2_MSG_CHANNEL_CLOSE);
|
||||
packet_put_int(c->remote_id);
|
||||
packet_send();
|
||||
if (!c->have_remote_id)
|
||||
fatal("%s: channel %d: no remote_id",
|
||||
__func__, c->self);
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_CLOSE)) != 0 ||
|
||||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0)
|
||||
fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
|
||||
c->flags |= CHAN_CLOSE_SENT;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
chan_send_eow2(Channel *c)
|
||||
chan_send_eow2(struct ssh *ssh, Channel *c)
|
||||
{
|
||||
int r;
|
||||
|
||||
debug2("channel %d: send eow", c->self);
|
||||
if (c->ostate == CHAN_OUTPUT_CLOSED) {
|
||||
error("channel %d: must not sent eow on closed output",
|
||||
|
@ -221,30 +236,33 @@ chan_send_eow2(Channel *c)
|
|||
}
|
||||
if (!(datafellows & SSH_NEW_OPENSSH))
|
||||
return;
|
||||
packet_start(SSH2_MSG_CHANNEL_REQUEST);
|
||||
packet_put_int(c->remote_id);
|
||||
packet_put_cstring("eow@openssh.com");
|
||||
packet_put_char(0);
|
||||
packet_send();
|
||||
if (!c->have_remote_id)
|
||||
fatal("%s: channel %d: no remote_id", __func__, c->self);
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_REQUEST)) != 0 ||
|
||||
(r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, "eow@openssh.com")) != 0 ||
|
||||
(r = sshpkt_put_u8(ssh, 0)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0)
|
||||
fatal("%s: send CHANNEL_EOF: %s", __func__, ssh_err(r));
|
||||
}
|
||||
|
||||
/* shared */
|
||||
|
||||
void
|
||||
chan_rcvd_ieof(Channel *c)
|
||||
chan_rcvd_ieof(struct ssh *ssh, Channel *c)
|
||||
{
|
||||
debug2("channel %d: rcvd eof", c->self);
|
||||
c->flags |= CHAN_EOF_RCVD;
|
||||
if (c->ostate == CHAN_OUTPUT_OPEN)
|
||||
chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
|
||||
if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
|
||||
buffer_len(&c->output) == 0 &&
|
||||
sshbuf_len(c->output) == 0 &&
|
||||
!CHANNEL_EFD_OUTPUT_ACTIVE(c))
|
||||
chan_obuf_empty(c);
|
||||
chan_obuf_empty(ssh, c);
|
||||
}
|
||||
|
||||
void
|
||||
chan_rcvd_oclose(Channel *c)
|
||||
chan_rcvd_oclose(struct ssh *ssh, Channel *c)
|
||||
{
|
||||
debug2("channel %d: rcvd close", c->self);
|
||||
if (!(c->flags & CHAN_LOCAL)) {
|
||||
|
@ -270,27 +288,27 @@ chan_rcvd_oclose(Channel *c)
|
|||
}
|
||||
switch (c->istate) {
|
||||
case CHAN_INPUT_OPEN:
|
||||
chan_shutdown_read(c);
|
||||
chan_shutdown_read(ssh, c);
|
||||
chan_set_istate(c, CHAN_INPUT_CLOSED);
|
||||
break;
|
||||
case CHAN_INPUT_WAIT_DRAIN:
|
||||
if (!(c->flags & CHAN_LOCAL))
|
||||
chan_send_eof2(c);
|
||||
chan_send_eof2(ssh, c);
|
||||
chan_set_istate(c, CHAN_INPUT_CLOSED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
chan_write_failed(Channel *c)
|
||||
chan_write_failed(struct ssh *ssh, Channel *c)
|
||||
{
|
||||
debug2("channel %d: write failed", c->self);
|
||||
switch (c->ostate) {
|
||||
case CHAN_OUTPUT_OPEN:
|
||||
case CHAN_OUTPUT_WAIT_DRAIN:
|
||||
chan_shutdown_write(c);
|
||||
chan_shutdown_write(ssh, c);
|
||||
if (strcmp(c->ctype, "session") == 0)
|
||||
chan_send_eow2(c);
|
||||
chan_send_eow2(ssh, c);
|
||||
chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
|
||||
break;
|
||||
default:
|
||||
|
@ -301,13 +319,13 @@ chan_write_failed(Channel *c)
|
|||
}
|
||||
|
||||
void
|
||||
chan_mark_dead(Channel *c)
|
||||
chan_mark_dead(struct ssh *ssh, Channel *c)
|
||||
{
|
||||
c->type = SSH_CHANNEL_ZOMBIE;
|
||||
}
|
||||
|
||||
int
|
||||
chan_is_dead(Channel *c, int do_send)
|
||||
chan_is_dead(struct ssh *ssh, Channel *c, int do_send)
|
||||
{
|
||||
if (c->type == SSH_CHANNEL_ZOMBIE) {
|
||||
debug2("channel %d: zombie", c->self);
|
||||
|
@ -318,9 +336,9 @@ chan_is_dead(Channel *c, int do_send)
|
|||
if ((datafellows & SSH_BUG_EXTEOF) &&
|
||||
c->extended_usage == CHAN_EXTENDED_WRITE &&
|
||||
c->efd != -1 &&
|
||||
buffer_len(&c->extended) > 0) {
|
||||
debug2("channel %d: active efd: %d len %d",
|
||||
c->self, c->efd, buffer_len(&c->extended));
|
||||
sshbuf_len(c->extended) > 0) {
|
||||
debug2("channel %d: active efd: %d len %zu",
|
||||
c->self, c->efd, sshbuf_len(c->extended));
|
||||
return 0;
|
||||
}
|
||||
if (c->flags & CHAN_LOCAL) {
|
||||
|
@ -329,7 +347,7 @@ chan_is_dead(Channel *c, int do_send)
|
|||
}
|
||||
if (!(c->flags & CHAN_CLOSE_SENT)) {
|
||||
if (do_send) {
|
||||
chan_send_close2(c);
|
||||
chan_send_close2(ssh, c);
|
||||
} else {
|
||||
/* channel would be dead if we sent a close */
|
||||
if (c->flags & CHAN_CLOSE_RCVD) {
|
||||
|
@ -349,9 +367,9 @@ chan_is_dead(Channel *c, int do_send)
|
|||
|
||||
/* helper */
|
||||
static void
|
||||
chan_shutdown_write(Channel *c)
|
||||
chan_shutdown_write(struct ssh *ssh, Channel *c)
|
||||
{
|
||||
buffer_clear(&c->output);
|
||||
sshbuf_reset(c->output);
|
||||
if (c->type == SSH_CHANNEL_LARVAL)
|
||||
return;
|
||||
/* shutdown failure is allowed if write failed already */
|
||||
|
@ -362,7 +380,7 @@ chan_shutdown_write(Channel *c)
|
|||
"shutdown() failed for fd %d: %.100s",
|
||||
c->self, c->sock, strerror(errno));
|
||||
} else {
|
||||
if (channel_close_fd(&c->wfd) < 0)
|
||||
if (channel_close_fd(ssh, &c->wfd) < 0)
|
||||
logit("channel %d: chan_shutdown_write: "
|
||||
"close() failed for fd %d: %.100s",
|
||||
c->self, c->wfd, strerror(errno));
|
||||
|
@ -370,7 +388,7 @@ chan_shutdown_write(Channel *c)
|
|||
}
|
||||
|
||||
static void
|
||||
chan_shutdown_read(Channel *c)
|
||||
chan_shutdown_read(struct ssh *ssh, Channel *c)
|
||||
{
|
||||
if (c->type == SSH_CHANNEL_LARVAL)
|
||||
return;
|
||||
|
@ -388,7 +406,7 @@ chan_shutdown_read(Channel *c)
|
|||
c->self, c->sock, c->istate, c->ostate,
|
||||
strerror(errno));
|
||||
} else {
|
||||
if (channel_close_fd(&c->rfd) < 0)
|
||||
if (channel_close_fd(ssh, &c->rfd) < 0)
|
||||
logit("channel %d: chan_shutdown_read: "
|
||||
"close() failed for fd %d: %.100s",
|
||||
c->self, c->rfd, strerror(errno));
|
||||
|
|
|
@ -16,9 +16,9 @@ RANLIB=@RANLIB@
|
|||
INSTALL=@INSTALL@
|
||||
LDFLAGS=-L. @LDFLAGS@
|
||||
|
||||
OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o recallocarray.o rresvport.o setenv.o setproctitle.o sha1.o sha2.o rmd160.o md5.o sigact.o strcasestr.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o
|
||||
OPENBSD=base64.o basename.o bcrypt_pbkdf.o bindresvport.o blowfish.o daemon.o dirname.o fmt_scaled.o getcwd.o getgrouplist.o getopt_long.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o pwcache.o readpassphrase.o reallocarray.o realpath.o recallocarray.o rresvport.o setenv.o setproctitle.o sha1.o sha2.o rmd160.o md5.o sigact.o strcasestr.o strlcat.o strlcpy.o strmode.o strnlen.o strptime.o strsep.o strtonum.o strtoll.o strtoul.o strtoull.o timingsafe_bcmp.o vis.o blowfish.o bcrypt_pbkdf.o explicit_bzero.o freezero.o
|
||||
|
||||
COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-getpagesize.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o
|
||||
COMPAT=arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o getrrsetbyname-ldns.o bsd-err.o bsd-getpagesize.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-malloc.o bsd-setres_id.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xcrypt.o kludge-fd_set.o
|
||||
|
||||
PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o
|
||||
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Darren Tucker (dtucker at zip com au).
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#undef malloc
|
||||
#undef calloc
|
||||
#undef realloc
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(HAVE_MALLOC) && HAVE_MALLOC == 0
|
||||
void *
|
||||
rpl_malloc(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
size = 1;
|
||||
return malloc(size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_CALLOC) && HAVE_CALLOC == 0
|
||||
void *
|
||||
rpl_calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
if (nmemb == 0)
|
||||
nmemb = 1;
|
||||
if (size == 0)
|
||||
size = 1;
|
||||
return calloc(nmemb, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_REALLOC) && HAVE_REALLOC == 0
|
||||
void *
|
||||
rpl_realloc(void *ptr, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
size = 1;
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
#endif
|
|
@ -104,6 +104,16 @@ const char *strerror(int e)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STRSIGNAL)
|
||||
char *strsignal(int sig)
|
||||
{
|
||||
static char buf[16];
|
||||
|
||||
(void)snprintf(buf, sizeof(buf), "%d", sig);
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_UTIMES
|
||||
int utimes(char *filename, struct timeval *tvp)
|
||||
{
|
||||
|
|
|
@ -49,6 +49,10 @@ int setegid(uid_t);
|
|||
const char *strerror(int);
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STRSIGNAL)
|
||||
char *strsignal(int);
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_SETLINEBUF)
|
||||
#define setlinebuf(a) (setvbuf((a), NULL, _IOLBF, 0))
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#ifndef HAVE_FREEZERO
|
||||
|
||||
void
|
||||
freezero(void *ptr, size_t sz)
|
||||
{
|
||||
explicit_bzero(ptr, sz);
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
#endif /* HAVE_FREEZERO */
|
||||
|
|
@ -307,6 +307,10 @@ int bcrypt_pbkdf(const char *, size_t, const u_int8_t *, size_t,
|
|||
void explicit_bzero(void *p, size_t n);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FREEZERO
|
||||
void freezero(void *, size_t);
|
||||
#endif
|
||||
|
||||
char *xcrypt(const char *password, const char *salt);
|
||||
char *shadow_pw(struct passwd *pw);
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ sys_tun_open(int tun, int mode)
|
|||
#define OPENBSD_AF_INET6 24
|
||||
|
||||
int
|
||||
sys_tun_infilter(struct Channel *c, char *buf, int _len)
|
||||
sys_tun_infilter(struct ssh *ssh, struct Channel *c, char *buf, int _len)
|
||||
{
|
||||
int r;
|
||||
size_t len;
|
||||
|
@ -245,24 +245,22 @@ sys_tun_infilter(struct Channel *c, char *buf, int _len)
|
|||
POKE_U32(buf, af == AF_INET6 ? OPENBSD_AF_INET6 : OPENBSD_AF_INET);
|
||||
#endif
|
||||
|
||||
if ((r = sshbuf_put_string(&c->input, ptr, len)) != 0)
|
||||
if ((r = sshbuf_put_string(c->input, ptr, len)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
return (0);
|
||||
}
|
||||
|
||||
u_char *
|
||||
sys_tun_outfilter(struct Channel *c, u_char **data, u_int *dlen)
|
||||
sys_tun_outfilter(struct ssh *ssh, struct Channel *c,
|
||||
u_char **data, size_t *dlen)
|
||||
{
|
||||
u_char *buf;
|
||||
u_int32_t af;
|
||||
int r;
|
||||
size_t xxx_dlen;
|
||||
|
||||
/* XXX new API is incompatible with this signature. */
|
||||
if ((r = sshbuf_get_string(&c->output, data, &xxx_dlen)) != 0)
|
||||
if ((r = sshbuf_get_string(c->output, data, dlen)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
if (dlen != NULL)
|
||||
*dlen = xxx_dlen;
|
||||
if (*dlen < sizeof(af))
|
||||
return (NULL);
|
||||
buf = *data;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#define _PORT_TUN_H
|
||||
|
||||
struct Channel;
|
||||
struct ssh;
|
||||
|
||||
#if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD)
|
||||
# define CUSTOM_SYS_TUN_OPEN
|
||||
|
@ -26,8 +27,8 @@ int sys_tun_open(int, int);
|
|||
|
||||
#if defined(SSH_TUN_COMPAT_AF) || defined(SSH_TUN_PREPEND_AF)
|
||||
# define SSH_TUN_FILTER
|
||||
int sys_tun_infilter(struct Channel *, char *, int);
|
||||
u_char *sys_tun_outfilter(struct Channel *, u_char **, u_int *);
|
||||
int sys_tun_infilter(struct ssh *, struct Channel *, char *, int);
|
||||
u_char *sys_tun_outfilter(struct ssh *, struct Channel *, u_char **, size_t *);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
68
packet.c
68
packet.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: packet.c,v 1.263 2017/07/23 23:37:02 djm Exp $ */
|
||||
/* $OpenBSD: packet.c,v 1.264 2017/09/12 06:32:07 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -2090,35 +2090,6 @@ ssh_packet_get_maxsize(struct ssh *ssh)
|
|||
return ssh->state->max_packet_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* 9.2. Ignored Data Message
|
||||
*
|
||||
* byte SSH_MSG_IGNORE
|
||||
* string data
|
||||
*
|
||||
* All implementations MUST understand (and ignore) this message at any
|
||||
* time (after receiving the protocol version). No implementation is
|
||||
* required to send them. This message can be used as an additional
|
||||
* protection measure against advanced traffic analysis techniques.
|
||||
*/
|
||||
void
|
||||
ssh_packet_send_ignore(struct ssh *ssh, int nbytes)
|
||||
{
|
||||
u_int32_t rnd = 0;
|
||||
int r, i;
|
||||
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 ||
|
||||
(r = sshpkt_put_u32(ssh, nbytes)) != 0)
|
||||
fatal("%s: %s", __func__, ssh_err(r));
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
if (i % 4 == 0)
|
||||
rnd = arc4random();
|
||||
if ((r = sshpkt_put_u8(ssh, (u_char)rnd & 0xff)) != 0)
|
||||
fatal("%s: %s", __func__, ssh_err(r));
|
||||
rnd >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ssh_packet_set_rekey_limits(struct ssh *ssh, u_int64_t bytes, u_int32_t seconds)
|
||||
{
|
||||
|
@ -2538,6 +2509,12 @@ sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp)
|
|||
return sshbuf_get_string_direct(ssh->state->incoming_packet, valp, lenp);
|
||||
}
|
||||
|
||||
int
|
||||
sshpkt_peek_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp)
|
||||
{
|
||||
return sshbuf_peek_string_direct(ssh->state->incoming_packet, valp, lenp);
|
||||
}
|
||||
|
||||
int
|
||||
sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp)
|
||||
{
|
||||
|
@ -2621,6 +2598,37 @@ ssh_packet_send_mux(struct ssh *ssh)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 9.2. Ignored Data Message
|
||||
*
|
||||
* byte SSH_MSG_IGNORE
|
||||
* string data
|
||||
*
|
||||
* All implementations MUST understand (and ignore) this message at any
|
||||
* time (after receiving the protocol version). No implementation is
|
||||
* required to send them. This message can be used as an additional
|
||||
* protection measure against advanced traffic analysis techniques.
|
||||
*/
|
||||
int
|
||||
sshpkt_msg_ignore(struct ssh *ssh, u_int nbytes)
|
||||
{
|
||||
u_int32_t rnd = 0;
|
||||
int r;
|
||||
u_int i;
|
||||
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 ||
|
||||
(r = sshpkt_put_u32(ssh, nbytes)) != 0)
|
||||
return r;
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
if (i % 4 == 0)
|
||||
rnd = arc4random();
|
||||
if ((r = sshpkt_put_u8(ssh, (u_char)rnd & 0xff)) != 0)
|
||||
return r;
|
||||
rnd >>= 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* send it */
|
||||
|
||||
int
|
||||
|
|
8
packet.h
8
packet.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: packet.h,v 1.81 2017/05/31 08:09:45 markus Exp $ */
|
||||
/* $OpenBSD: packet.h,v 1.82 2017/09/12 06:32:07 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -80,6 +80,9 @@ struct ssh {
|
|||
/* Client/Server authentication context */
|
||||
void *authctxt;
|
||||
|
||||
/* Channels context */
|
||||
struct ssh_channels *chanctxt;
|
||||
|
||||
/* APP data */
|
||||
void *app_data;
|
||||
};
|
||||
|
@ -143,7 +146,6 @@ int ssh_packet_not_very_much_data_to_write(struct ssh *);
|
|||
|
||||
int ssh_packet_connection_is_on_socket(struct ssh *);
|
||||
int ssh_packet_remaining(struct ssh *);
|
||||
void ssh_packet_send_ignore(struct ssh *, int);
|
||||
|
||||
void tty_make_modes(int, struct termios *);
|
||||
void tty_parse_modes(int, int *);
|
||||
|
@ -174,6 +176,7 @@ int sshpkt_disconnect(struct ssh *, const char *fmt, ...)
|
|||
__attribute__((format(printf, 2, 3)));
|
||||
int sshpkt_add_padding(struct ssh *, u_char);
|
||||
void sshpkt_fatal(struct ssh *ssh, const char *tag, int r);
|
||||
int sshpkt_msg_ignore(struct ssh *, u_int);
|
||||
|
||||
int sshpkt_put(struct ssh *ssh, const void *v, size_t len);
|
||||
int sshpkt_putb(struct ssh *ssh, const struct sshbuf *b);
|
||||
|
@ -192,6 +195,7 @@ int sshpkt_get_u32(struct ssh *ssh, u_int32_t *valp);
|
|||
int sshpkt_get_u64(struct ssh *ssh, u_int64_t *valp);
|
||||
int sshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp);
|
||||
int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp);
|
||||
int sshpkt_peek_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp);
|
||||
int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp);
|
||||
int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g);
|
||||
int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v);
|
||||
|
|
59
readconf.c
59
readconf.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: readconf.c,v 1.277 2017/05/30 18:58:37 bluhm Exp $ */
|
||||
/* $OpenBSD: readconf.c,v 1.279 2017/09/21 19:16:53 markus Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -757,6 +757,16 @@ static const struct multistate multistate_yesnoask[] = {
|
|||
{ "ask", 2 },
|
||||
{ NULL, -1 }
|
||||
};
|
||||
static const struct multistate multistate_strict_hostkey[] = {
|
||||
{ "true", SSH_STRICT_HOSTKEY_YES },
|
||||
{ "false", SSH_STRICT_HOSTKEY_OFF },
|
||||
{ "yes", SSH_STRICT_HOSTKEY_YES },
|
||||
{ "no", SSH_STRICT_HOSTKEY_OFF },
|
||||
{ "ask", SSH_STRICT_HOSTKEY_ASK },
|
||||
{ "off", SSH_STRICT_HOSTKEY_OFF },
|
||||
{ "accept-new", SSH_STRICT_HOSTKEY_NEW },
|
||||
{ NULL, -1 }
|
||||
};
|
||||
static const struct multistate multistate_yesnoaskconfirm[] = {
|
||||
{ "true", 1 },
|
||||
{ "false", 0 },
|
||||
|
@ -832,6 +842,7 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host,
|
|||
char **cpptr, fwdarg[256];
|
||||
u_int i, *uintptr, max_entries = 0;
|
||||
int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
|
||||
int remotefwd, dynamicfwd;
|
||||
LogLevel *log_level_ptr;
|
||||
SyslogFacility *log_facility_ptr;
|
||||
long long val64;
|
||||
|
@ -990,7 +1001,7 @@ parse_time:
|
|||
|
||||
case oStrictHostKeyChecking:
|
||||
intptr = &options->strict_host_key_checking;
|
||||
multistate_ptr = multistate_yesnoask;
|
||||
multistate_ptr = multistate_strict_hostkey;
|
||||
goto parse_multistate;
|
||||
|
||||
case oCompression:
|
||||
|
@ -1251,31 +1262,36 @@ parse_keytypes:
|
|||
fatal("%.200s line %d: Missing port argument.",
|
||||
filename, linenum);
|
||||
|
||||
if (opcode == oLocalForward ||
|
||||
opcode == oRemoteForward) {
|
||||
remotefwd = (opcode == oRemoteForward);
|
||||
dynamicfwd = (opcode == oDynamicForward);
|
||||
|
||||
if (!dynamicfwd) {
|
||||
arg2 = strdelim(&s);
|
||||
if (arg2 == NULL || *arg2 == '\0')
|
||||
fatal("%.200s line %d: Missing target argument.",
|
||||
filename, linenum);
|
||||
|
||||
/* construct a string for parse_forward */
|
||||
snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
|
||||
} else if (opcode == oDynamicForward) {
|
||||
strlcpy(fwdarg, arg, sizeof(fwdarg));
|
||||
if (arg2 == NULL || *arg2 == '\0') {
|
||||
if (remotefwd)
|
||||
dynamicfwd = 1;
|
||||
else
|
||||
fatal("%.200s line %d: Missing target "
|
||||
"argument.", filename, linenum);
|
||||
} else {
|
||||
/* construct a string for parse_forward */
|
||||
snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg,
|
||||
arg2);
|
||||
}
|
||||
}
|
||||
if (dynamicfwd)
|
||||
strlcpy(fwdarg, arg, sizeof(fwdarg));
|
||||
|
||||
if (parse_forward(&fwd, fwdarg,
|
||||
opcode == oDynamicForward ? 1 : 0,
|
||||
opcode == oRemoteForward ? 1 : 0) == 0)
|
||||
if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0)
|
||||
fatal("%.200s line %d: Bad forwarding specification.",
|
||||
filename, linenum);
|
||||
|
||||
if (*activep) {
|
||||
if (opcode == oLocalForward ||
|
||||
opcode == oDynamicForward)
|
||||
add_local_forward(options, &fwd);
|
||||
else if (opcode == oRemoteForward)
|
||||
if (remotefwd) {
|
||||
add_remote_forward(options, &fwd);
|
||||
} else {
|
||||
add_local_forward(options, &fwd);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1944,7 +1960,7 @@ fill_default_options(Options * options)
|
|||
if (options->check_host_ip == -1)
|
||||
options->check_host_ip = 1;
|
||||
if (options->strict_host_key_checking == -1)
|
||||
options->strict_host_key_checking = 2; /* 2 is default */
|
||||
options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK;
|
||||
if (options->compression == -1)
|
||||
options->compression = 0;
|
||||
if (options->tcp_keep_alive == -1)
|
||||
|
@ -2346,9 +2362,10 @@ fmt_intarg(OpCodes code, int val)
|
|||
case oAddressFamily:
|
||||
return fmt_multistate_int(val, multistate_addressfamily);
|
||||
case oVerifyHostKeyDNS:
|
||||
case oStrictHostKeyChecking:
|
||||
case oUpdateHostkeys:
|
||||
return fmt_multistate_int(val, multistate_yesnoask);
|
||||
case oStrictHostKeyChecking:
|
||||
return fmt_multistate_int(val, multistate_strict_hostkey);
|
||||
case oControlMaster:
|
||||
return fmt_multistate_int(val, multistate_controlmaster);
|
||||
case oTunnel:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: readconf.h,v 1.122 2017/05/30 18:58:37 bluhm Exp $ */
|
||||
/* $OpenBSD: readconf.h,v 1.123 2017/09/03 23:33:13 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -190,6 +190,11 @@ typedef struct {
|
|||
#define SSH_UPDATE_HOSTKEYS_YES 1
|
||||
#define SSH_UPDATE_HOSTKEYS_ASK 2
|
||||
|
||||
#define SSH_STRICT_HOSTKEY_OFF 0
|
||||
#define SSH_STRICT_HOSTKEY_NEW 1
|
||||
#define SSH_STRICT_HOSTKEY_YES 2
|
||||
#define SSH_STRICT_HOSTKEY_ASK 3
|
||||
|
||||
void initialize_options(Options *);
|
||||
void fill_default_options(Options *);
|
||||
void fill_default_options_for_canonicalization(Options *);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: agent-getpeereid.sh,v 1.8 2017/01/06 02:51:16 djm Exp $
|
||||
# $OpenBSD: agent-getpeereid.sh,v 1.9 2017/09/13 14:58:26 bluhm Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="disallow agent attach from other uid"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: dynamic-forward.sh,v 1.12 2017/04/30 23:34:55 djm Exp $
|
||||
# $OpenBSD: dynamic-forward.sh,v 1.13 2017/09/21 19:18:12 markus Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="dynamic forwarding"
|
||||
|
@ -17,33 +17,34 @@ trace "will use ProxyCommand $proxycmd"
|
|||
|
||||
start_sshd
|
||||
|
||||
for p in ${SSH_PROTOCOLS}; do
|
||||
for d in D R; do
|
||||
n=0
|
||||
error="1"
|
||||
trace "start dynamic forwarding, fork to background"
|
||||
|
||||
while [ "$error" -ne 0 -a "$n" -lt 3 ]; do
|
||||
n=`expr $n + 1`
|
||||
${SSH} -$p -F $OBJ/ssh_config -f -D $FWDPORT -q \
|
||||
${SSH} -F $OBJ/ssh_config -f -$d $FWDPORT -q \
|
||||
-oExitOnForwardFailure=yes somehost exec sh -c \
|
||||
\'"echo \$\$ > $OBJ/remote_pid; exec sleep 444"\'
|
||||
error=$?
|
||||
if [ "$error" -ne 0 ]; then
|
||||
trace "forward failed proto $p attempt $n err $error"
|
||||
trace "forward failed attempt $n err $error"
|
||||
sleep $n
|
||||
fi
|
||||
done
|
||||
if [ "$error" -ne 0 ]; then
|
||||
fatal "failed to start dynamic forwarding proto $p"
|
||||
fatal "failed to start dynamic forwarding"
|
||||
fi
|
||||
|
||||
for s in 4 5; do
|
||||
for h in 127.0.0.1 localhost; do
|
||||
trace "testing ssh protocol $p socks version $s host $h"
|
||||
trace "testing ssh socks version $s host $h (-$d)"
|
||||
${SSH} -F $OBJ/ssh_config \
|
||||
-o "ProxyCommand ${proxycmd}${s} $h $PORT" \
|
||||
somehost cat $DATA > $OBJ/ls.copy
|
||||
test -f $OBJ/ls.copy || fail "failed copy $DATA"
|
||||
cmp $DATA $OBJ/ls.copy || fail "corrupted copy of $DATA"
|
||||
somehost cat ${DATA} > ${COPY}
|
||||
test -f ${COPY} || fail "failed copy ${DATA}"
|
||||
cmp ${DATA} ${COPY} || fail "corrupted copy of ${DATA}"
|
||||
done
|
||||
done
|
||||
|
||||
|
@ -56,4 +57,5 @@ for p in ${SSH_PROTOCOLS}; do
|
|||
else
|
||||
fail "no pid file: $OBJ/remote_pid"
|
||||
fi
|
||||
|
||||
done
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: login-timeout.sh,v 1.8 2016/12/16 01:06:27 dtucker Exp $
|
||||
# $OpenBSD: login-timeout.sh,v 1.9 2017/08/07 00:53:51 dtucker Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="connect after login grace timeout"
|
||||
|
@ -10,23 +10,9 @@ echo "LoginGraceTime 10s" >> $OBJ/sshd_config
|
|||
echo "MaxStartups 1" >> $OBJ/sshd_config
|
||||
start_sshd
|
||||
|
||||
(echo SSH-2.0-fake; sleep 60) | telnet 127.0.0.1 ${PORT} >/dev/null 2>&1 &
|
||||
(echo SSH-2.0-fake; sleep 60) | telnet 127.0.0.1 ${PORT} >/dev/null 2>&1 &
|
||||
sleep 15
|
||||
${SSH} -F $OBJ/ssh_config somehost true
|
||||
if [ $? -ne 0 ]; then
|
||||
fail "ssh connect after login grace timeout failed with privsep"
|
||||
fi
|
||||
|
||||
stop_sshd
|
||||
|
||||
trace "test login grace without privsep"
|
||||
echo "UsePrivilegeSeparation no" >> $OBJ/sshd_config
|
||||
start_sshd
|
||||
sleep 1
|
||||
|
||||
(echo SSH-2.0-fake; sleep 60) | telnet 127.0.0.1 ${PORT} >/dev/null 2>&1 &
|
||||
sleep 15
|
||||
${SSH} -F $OBJ/ssh_config somehost true
|
||||
if [ $? -ne 0 ]; then
|
||||
fail "ssh connect after login grace timeout failed without privsep"
|
||||
fail "ssh connect after login grace timeout failed"
|
||||
fi
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# NB. libssh and libopenbsd-compat should be built with the same sanitizer opts.
|
||||
CXX=clang++-3.9
|
||||
FUZZ_FLAGS=-fsanitize=address,undefined -fsanitize-coverage=edge
|
||||
FUZZ_LIBS=-lFuzzer
|
||||
|
||||
CXXFLAGS=-O2 -g -Wall -Wextra -I ../../.. $(FUZZ_FLAGS)
|
||||
LDFLAGS=-L ../../.. -L ../../../openbsd-compat -g $(FUZZ_FLAGS)
|
||||
LIBS=-lssh -lopenbsd-compat -lcrypto $(FUZZ_LIBS)
|
||||
|
||||
all: pubkey_fuzz sig_fuzz
|
||||
|
||||
.cc.o:
|
||||
$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
pubkey_fuzz: pubkey_fuzz.o
|
||||
$(CXX) -o $@ pubkey_fuzz.o $(LDFLAGS) $(LIBS)
|
||||
|
||||
sig_fuzz: sig_fuzz.o
|
||||
$(CXX) -o $@ sig_fuzz.o $(LDFLAGS) $(LIBS)
|
||||
|
||||
clean:
|
||||
-rm -f *.o pubkey_fuzz sig_fuzz
|
|
@ -0,0 +1 @@
|
|||
This directory contains fuzzing harnesses for use with clang's libfuzzer.
|
|
@ -0,0 +1,18 @@
|
|||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include "sshkey.h"
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
|
||||
{
|
||||
struct sshkey *k = NULL;
|
||||
int r = sshkey_from_blob(data, size, &k);
|
||||
if (r == 0) sshkey_free(k);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // extern
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
// cc_fuzz_target test for public key parsing.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include "includes.h"
|
||||
#include "sshkey.h"
|
||||
#include "ssherr.h"
|
||||
|
||||
static struct sshkey *generate_or_die(int type, unsigned bits) {
|
||||
int r;
|
||||
struct sshkey *ret;
|
||||
if ((r = sshkey_generate(type, bits, &ret)) != 0) {
|
||||
fprintf(stderr, "generate(%d, %u): %s", type, bits, ssh_err(r));
|
||||
abort();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t* sig, size_t slen)
|
||||
{
|
||||
#ifdef WITH_OPENSSL
|
||||
static struct sshkey *rsa = generate_or_die(KEY_RSA, 2048);
|
||||
static struct sshkey *dsa = generate_or_die(KEY_DSA, 1024);
|
||||
static struct sshkey *ecdsa256 = generate_or_die(KEY_ECDSA, 256);
|
||||
static struct sshkey *ecdsa384 = generate_or_die(KEY_ECDSA, 384);
|
||||
static struct sshkey *ecdsa521 = generate_or_die(KEY_ECDSA, 521);
|
||||
#endif
|
||||
static struct sshkey *ed25519 = generate_or_die(KEY_ED25519, 0);
|
||||
static const char *data = "If everyone started announcing his nose had "
|
||||
"run away, I don’t know how it would all end";
|
||||
static const size_t dlen = strlen(data);
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
sshkey_verify(rsa, sig, slen, (const u_char *)data, dlen, 0);
|
||||
sshkey_verify(dsa, sig, slen, (const u_char *)data, dlen, 0);
|
||||
sshkey_verify(ecdsa256, sig, slen, (const u_char *)data, dlen, 0);
|
||||
sshkey_verify(ecdsa384, sig, slen, (const u_char *)data, dlen, 0);
|
||||
sshkey_verify(ecdsa521, sig, slen, (const u_char *)data, dlen, 0);
|
||||
#endif
|
||||
sshkey_verify(ed25519, sig, slen, (const u_char *)data, dlen, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // extern
|
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: reexec.sh,v 1.11 2017/04/30 23:34:55 djm Exp $
|
||||
# $OpenBSD: reexec.sh,v 1.12 2017/08/07 03:52:55 dtucker Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="reexec tests"
|
||||
|
@ -51,17 +51,4 @@ rm -f $SSHD_COPY
|
|||
copy_tests
|
||||
|
||||
stop_sshd
|
||||
|
||||
verbose "test reexec fallback without privsep"
|
||||
|
||||
cp $OBJ/sshd_config.orig $OBJ/sshd_config
|
||||
echo "UsePrivilegeSeparation=no" >> $OBJ/sshd_config
|
||||
|
||||
start_sshd_copy
|
||||
rm -f $SSHD_COPY
|
||||
|
||||
copy_tests
|
||||
|
||||
stop_sshd
|
||||
|
||||
fi
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $OpenBSD: test-exec.sh,v 1.60 2017/04/30 23:34:55 djm Exp $
|
||||
# $OpenBSD: test-exec.sh,v 1.61 2017/07/28 10:32:08 dtucker Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
#SUDO=sudo
|
||||
|
@ -304,8 +304,15 @@ stop_sshd ()
|
|||
i=`expr $i + 1`
|
||||
sleep $i
|
||||
done
|
||||
test -f $PIDFILE && \
|
||||
fatal "sshd didn't exit port $PORT pid $pid"
|
||||
if test -f $PIDFILE; then
|
||||
if $SUDO kill -0 $pid; then
|
||||
echo "sshd didn't exit " \
|
||||
"port $PORT pid $pid"
|
||||
else
|
||||
echo "sshd died without cleanup"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/capability.h>
|
||||
#include <sys/capsicum.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
|
|
94
servconf.c
94
servconf.c
|
@ -1,5 +1,5 @@
|
|||
|
||||
/* $OpenBSD: servconf.c,v 1.309 2017/06/24 06:34:38 djm Exp $ */
|
||||
/* $OpenBSD: servconf.c,v 1.312 2017/10/02 19:33:20 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
|
@ -149,7 +149,7 @@ initialize_server_options(ServerOptions *options)
|
|||
options->num_authkeys_files = 0;
|
||||
options->num_accept_env = 0;
|
||||
options->permit_tun = -1;
|
||||
options->num_permitted_opens = -1;
|
||||
options->permitted_opens = NULL;
|
||||
options->adm_forced_command = NULL;
|
||||
options->chroot_directory = NULL;
|
||||
options->authorized_keys_command = NULL;
|
||||
|
@ -703,6 +703,44 @@ process_queued_listen_addrs(ServerOptions *options)
|
|||
options->num_queued_listens = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Inform channels layer of permitopen options from configuration.
|
||||
*/
|
||||
void
|
||||
process_permitopen(struct ssh *ssh, ServerOptions *options)
|
||||
{
|
||||
u_int i;
|
||||
int port;
|
||||
char *host, *arg, *oarg;
|
||||
|
||||
channel_clear_adm_permitted_opens(ssh);
|
||||
if (options->num_permitted_opens == 0)
|
||||
return; /* permit any */
|
||||
|
||||
/* handle keywords: "any" / "none" */
|
||||
if (options->num_permitted_opens == 1 &&
|
||||
strcmp(options->permitted_opens[0], "any") == 0)
|
||||
return;
|
||||
if (options->num_permitted_opens == 1 &&
|
||||
strcmp(options->permitted_opens[0], "none") == 0) {
|
||||
channel_disable_adm_local_opens(ssh);
|
||||
return;
|
||||
}
|
||||
/* Otherwise treat it as a list of permitted host:port */
|
||||
for (i = 0; i < options->num_permitted_opens; i++) {
|
||||
oarg = arg = xstrdup(options->permitted_opens[i]);
|
||||
host = hpdelim(&arg);
|
||||
if (host == NULL)
|
||||
fatal("%s: missing host in PermitOpen", __func__);
|
||||
host = cleanhostname(host);
|
||||
if (arg == NULL || ((port = permitopen_port(arg)) < 0))
|
||||
fatal("%s: bad port number in PermitOpen", __func__);
|
||||
/* Send it to channels layer */
|
||||
channel_add_adm_permitted_opens(ssh, host, port);
|
||||
free(oarg);
|
||||
}
|
||||
}
|
||||
|
||||
struct connection_info *
|
||||
get_connection_info(int populate, int use_dns)
|
||||
{
|
||||
|
@ -960,7 +998,7 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
const char *filename, int linenum, int *activep,
|
||||
struct connection_info *connectinfo)
|
||||
{
|
||||
char *cp, **charptr, *arg, *p;
|
||||
char *cp, **charptr, *arg, *arg2, *p;
|
||||
int cmdline = 0, *intptr, value, value2, n, port;
|
||||
SyslogFacility *log_facility_ptr;
|
||||
LogLevel *log_level_ptr;
|
||||
|
@ -1631,24 +1669,18 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
if (!arg || *arg == '\0')
|
||||
fatal("%s line %d: missing PermitOpen specification",
|
||||
filename, linenum);
|
||||
n = options->num_permitted_opens; /* modified later */
|
||||
if (strcmp(arg, "any") == 0) {
|
||||
if (*activep && n == -1) {
|
||||
channel_clear_adm_permitted_opens();
|
||||
options->num_permitted_opens = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (strcmp(arg, "none") == 0) {
|
||||
if (*activep && n == -1) {
|
||||
i = options->num_permitted_opens; /* modified later */
|
||||
if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
|
||||
if (*activep && i == 0) {
|
||||
options->num_permitted_opens = 1;
|
||||
channel_disable_adm_local_opens();
|
||||
options->permitted_opens = xcalloc(1,
|
||||
sizeof(*options->permitted_opens));
|
||||
options->permitted_opens[0] = xstrdup(arg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (*activep && n == -1)
|
||||
channel_clear_adm_permitted_opens();
|
||||
for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
|
||||
arg2 = xstrdup(arg);
|
||||
p = hpdelim(&arg);
|
||||
if (p == NULL)
|
||||
fatal("%s line %d: missing host in PermitOpen",
|
||||
|
@ -1657,9 +1689,16 @@ process_server_config_line(ServerOptions *options, char *line,
|
|||
if (arg == NULL || ((port = permitopen_port(arg)) < 0))
|
||||
fatal("%s line %d: bad port number in "
|
||||
"PermitOpen", filename, linenum);
|
||||
if (*activep && n == -1)
|
||||
options->num_permitted_opens =
|
||||
channel_add_adm_permitted_opens(p, port);
|
||||
if (*activep && i == 0) {
|
||||
options->permitted_opens = xrecallocarray(
|
||||
options->permitted_opens,
|
||||
options->num_permitted_opens,
|
||||
options->num_permitted_opens + 1,
|
||||
sizeof(*options->permitted_opens));
|
||||
i = options->num_permitted_opens++;
|
||||
options->permitted_opens[i] = arg2;
|
||||
} else
|
||||
free(arg2);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2030,6 +2069,13 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
|
|||
dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \
|
||||
} \
|
||||
} while(0)
|
||||
#define M_CP_STRARRAYOPT_ALLOC(n, num_n) do { \
|
||||
if (src->num_n != 0) { \
|
||||
dst->n = xcalloc(src->num_n, sizeof(*dst->n)); \
|
||||
M_CP_STRARRAYOPT(n, num_n); \
|
||||
dst->num_n = src->num_n; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* See comment in servconf.h */
|
||||
COPY_MATCH_STRING_OPTS();
|
||||
|
@ -2060,6 +2106,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
|
|||
#undef M_CP_INTOPT
|
||||
#undef M_CP_STROPT
|
||||
#undef M_CP_STRARRAYOPT
|
||||
#undef M_CP_STRARRAYOPT_ALLOC
|
||||
|
||||
void
|
||||
parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
|
||||
|
@ -2384,5 +2431,12 @@ dump_config(ServerOptions *o)
|
|||
printf("rekeylimit %llu %d\n", (unsigned long long)o->rekey_limit,
|
||||
o->rekey_interval);
|
||||
|
||||
channel_print_adm_permitted_opens();
|
||||
printf("permitopen");
|
||||
if (o->num_permitted_opens == 0)
|
||||
printf(" any");
|
||||
else {
|
||||
for (i = 0; i < o->num_permitted_opens; i++)
|
||||
printf(" %s", o->permitted_opens[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
|
14
servconf.h
14
servconf.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: servconf.h,v 1.124 2017/06/24 06:34:38 djm Exp $ */
|
||||
/* $OpenBSD: servconf.h,v 1.126 2017/10/02 19:33:20 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -48,12 +48,19 @@
|
|||
#define FORWARD_LOCAL (1<<1)
|
||||
#define FORWARD_ALLOW (FORWARD_REMOTE|FORWARD_LOCAL)
|
||||
|
||||
/* PermitOpen */
|
||||
#define PERMITOPEN_ANY 0
|
||||
#define PERMITOPEN_NONE -2
|
||||
|
||||
#define DEFAULT_AUTH_FAIL_MAX 6 /* Default for MaxAuthTries */
|
||||
#define DEFAULT_SESSIONS_MAX 10 /* Default for MaxSessions */
|
||||
|
||||
/* Magic name for internal sftp-server */
|
||||
#define INTERNAL_SFTP_NAME "internal-sftp"
|
||||
|
||||
struct ssh;
|
||||
struct fwd_perm_list;
|
||||
|
||||
typedef struct {
|
||||
u_int num_ports;
|
||||
u_int ports_from_cmdline;
|
||||
|
@ -169,7 +176,8 @@ typedef struct {
|
|||
|
||||
int permit_tun;
|
||||
|
||||
int num_permitted_opens;
|
||||
char **permitted_opens;
|
||||
u_int num_permitted_opens; /* May also be one of PERMITOPEN_* */
|
||||
|
||||
char *chroot_directory;
|
||||
char *revoked_keys_file;
|
||||
|
@ -229,6 +237,7 @@ struct connection_info {
|
|||
M_CP_STRARRAYOPT(deny_groups, num_deny_groups); \
|
||||
M_CP_STRARRAYOPT(accept_env, num_accept_env); \
|
||||
M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \
|
||||
M_CP_STRARRAYOPT_ALLOC(permitted_opens, num_permitted_opens); \
|
||||
} while (0)
|
||||
|
||||
struct connection_info *get_connection_info(int, int);
|
||||
|
@ -236,6 +245,7 @@ void initialize_server_options(ServerOptions *);
|
|||
void fill_default_server_options(ServerOptions *);
|
||||
int process_server_config_line(ServerOptions *, char *, const char *, int,
|
||||
int *, struct connection_info *);
|
||||
void process_permitopen(struct ssh *ssh, ServerOptions *options);
|
||||
void load_server_config(const char *, Buffer *);
|
||||
void parse_server_config(ServerOptions *, const char *, Buffer *,
|
||||
struct connection_info *);
|
||||
|
|
113
serverloop.c
113
serverloop.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: serverloop.c,v 1.195 2017/08/11 04:16:35 dtucker Exp $ */
|
||||
/* $OpenBSD: serverloop.c,v 1.198 2017/09/12 06:35:32 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -165,7 +165,7 @@ sigterm_handler(int sig)
|
|||
}
|
||||
|
||||
static void
|
||||
client_alive_check(void)
|
||||
client_alive_check(struct ssh *ssh)
|
||||
{
|
||||
int channel_id;
|
||||
|
||||
|
@ -179,12 +179,13 @@ client_alive_check(void)
|
|||
* send a bogus global/channel request with "wantreply",
|
||||
* we should get back a failure
|
||||
*/
|
||||
if ((channel_id = channel_find_open()) == -1) {
|
||||
if ((channel_id = channel_find_open(ssh)) == -1) {
|
||||
packet_start(SSH2_MSG_GLOBAL_REQUEST);
|
||||
packet_put_cstring("keepalive@openssh.com");
|
||||
packet_put_char(1); /* boolean: want reply */
|
||||
} else {
|
||||
channel_request_start(channel_id, "keepalive@openssh.com", 1);
|
||||
channel_request_start(ssh, channel_id,
|
||||
"keepalive@openssh.com", 1);
|
||||
}
|
||||
packet_send();
|
||||
}
|
||||
|
@ -196,7 +197,8 @@ client_alive_check(void)
|
|||
* for the duration of the wait (0 = infinite).
|
||||
*/
|
||||
static void
|
||||
wait_until_can_do_something(int connection_in, int connection_out,
|
||||
wait_until_can_do_something(struct ssh *ssh,
|
||||
int connection_in, int connection_out,
|
||||
fd_set **readsetp, fd_set **writesetp, int *maxfdp,
|
||||
u_int *nallocp, u_int64_t max_time_ms)
|
||||
{
|
||||
|
@ -207,8 +209,8 @@ wait_until_can_do_something(int connection_in, int connection_out,
|
|||
static time_t last_client_time;
|
||||
|
||||
/* Allocate and update select() masks for channel descriptors. */
|
||||
channel_prepare_select(readsetp, writesetp, maxfdp, nallocp,
|
||||
&minwait_secs, 0);
|
||||
channel_prepare_select(ssh, readsetp, writesetp, maxfdp,
|
||||
nallocp, &minwait_secs);
|
||||
|
||||
/* XXX need proper deadline system for rekey/client alive */
|
||||
if (minwait_secs != 0)
|
||||
|
@ -273,12 +275,12 @@ wait_until_can_do_something(int connection_in, int connection_out,
|
|||
time_t now = monotime();
|
||||
|
||||
if (ret == 0) { /* timeout */
|
||||
client_alive_check();
|
||||
client_alive_check(ssh);
|
||||
} else if (FD_ISSET(connection_in, *readsetp)) {
|
||||
last_client_time = now;
|
||||
} else if (last_client_time != 0 && last_client_time +
|
||||
options.client_alive_interval <= now) {
|
||||
client_alive_check();
|
||||
client_alive_check(ssh);
|
||||
last_client_time = now;
|
||||
}
|
||||
}
|
||||
|
@ -291,9 +293,8 @@ wait_until_can_do_something(int connection_in, int connection_out,
|
|||
* in buffers and processed later.
|
||||
*/
|
||||
static int
|
||||
process_input(fd_set *readset, int connection_in)
|
||||
process_input(struct ssh *ssh, fd_set *readset, int connection_in)
|
||||
{
|
||||
struct ssh *ssh = active_state; /* XXX */
|
||||
int len;
|
||||
char buf[16384];
|
||||
|
||||
|
@ -333,13 +334,13 @@ process_output(fd_set *writeset, int connection_out)
|
|||
}
|
||||
|
||||
static void
|
||||
process_buffered_input_packets(void)
|
||||
process_buffered_input_packets(struct ssh *ssh)
|
||||
{
|
||||
ssh_dispatch_run_fatal(active_state, DISPATCH_NONBLOCK, NULL);
|
||||
ssh_dispatch_run_fatal(ssh, DISPATCH_NONBLOCK, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
collect_children(void)
|
||||
collect_children(struct ssh *ssh)
|
||||
{
|
||||
pid_t pid;
|
||||
sigset_t oset, nset;
|
||||
|
@ -354,14 +355,14 @@ collect_children(void)
|
|||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
|
||||
(pid < 0 && errno == EINTR))
|
||||
if (pid > 0)
|
||||
session_close_by_pid(pid, status);
|
||||
session_close_by_pid(ssh, pid, status);
|
||||
child_terminated = 0;
|
||||
}
|
||||
sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
server_loop2(Authctxt *authctxt)
|
||||
server_loop2(struct ssh *ssh, Authctxt *authctxt)
|
||||
{
|
||||
fd_set *readset = NULL, *writeset = NULL;
|
||||
int max_fd;
|
||||
|
@ -389,18 +390,17 @@ server_loop2(Authctxt *authctxt)
|
|||
server_init_dispatch();
|
||||
|
||||
for (;;) {
|
||||
process_buffered_input_packets();
|
||||
process_buffered_input_packets(ssh);
|
||||
|
||||
if (!ssh_packet_is_rekeying(active_state) &&
|
||||
if (!ssh_packet_is_rekeying(ssh) &&
|
||||
packet_not_very_much_data_to_write())
|
||||
channel_output_poll();
|
||||
if (options.rekey_interval > 0 &&
|
||||
!ssh_packet_is_rekeying(active_state))
|
||||
channel_output_poll(ssh);
|
||||
if (options.rekey_interval > 0 && !ssh_packet_is_rekeying(ssh))
|
||||
rekey_timeout_ms = packet_get_rekey_timeout() * 1000;
|
||||
else
|
||||
rekey_timeout_ms = 0;
|
||||
|
||||
wait_until_can_do_something(connection_in, connection_out,
|
||||
wait_until_can_do_something(ssh, connection_in, connection_out,
|
||||
&readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms);
|
||||
|
||||
if (received_sigterm) {
|
||||
|
@ -409,23 +409,23 @@ server_loop2(Authctxt *authctxt)
|
|||
cleanup_exit(255);
|
||||
}
|
||||
|
||||
collect_children();
|
||||
if (!ssh_packet_is_rekeying(active_state))
|
||||
channel_after_select(readset, writeset);
|
||||
if (process_input(readset, connection_in) < 0)
|
||||
collect_children(ssh);
|
||||
if (!ssh_packet_is_rekeying(ssh))
|
||||
channel_after_select(ssh, readset, writeset);
|
||||
if (process_input(ssh, readset, connection_in) < 0)
|
||||
break;
|
||||
process_output(writeset, connection_out);
|
||||
}
|
||||
collect_children();
|
||||
collect_children(ssh);
|
||||
|
||||
free(readset);
|
||||
free(writeset);
|
||||
|
||||
/* free all channels, no more reads and writes */
|
||||
channel_free_all();
|
||||
channel_free_all(ssh);
|
||||
|
||||
/* free remaining sessions, e.g. remove wtmp entries */
|
||||
session_destroy_all(NULL);
|
||||
session_destroy_all(ssh, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -442,7 +442,7 @@ server_input_keep_alive(int type, u_int32_t seq, struct ssh *ssh)
|
|||
}
|
||||
|
||||
static Channel *
|
||||
server_request_direct_tcpip(int *reason, const char **errmsg)
|
||||
server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg)
|
||||
{
|
||||
Channel *c = NULL;
|
||||
char *target, *originator;
|
||||
|
@ -460,7 +460,7 @@ server_request_direct_tcpip(int *reason, const char **errmsg)
|
|||
/* XXX fine grained permissions */
|
||||
if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 &&
|
||||
!no_port_forwarding_flag && !options.disable_forwarding) {
|
||||
c = channel_connect_to_port(target, target_port,
|
||||
c = channel_connect_to_port(ssh, target, target_port,
|
||||
"direct-tcpip", "direct-tcpip", reason, errmsg);
|
||||
} else {
|
||||
logit("refused local port forward: "
|
||||
|
@ -477,7 +477,7 @@ server_request_direct_tcpip(int *reason, const char **errmsg)
|
|||
}
|
||||
|
||||
static Channel *
|
||||
server_request_direct_streamlocal(void)
|
||||
server_request_direct_streamlocal(struct ssh *ssh)
|
||||
{
|
||||
Channel *c = NULL;
|
||||
char *target, *originator;
|
||||
|
@ -499,7 +499,7 @@ server_request_direct_streamlocal(void)
|
|||
if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 &&
|
||||
!no_port_forwarding_flag && !options.disable_forwarding &&
|
||||
(pw->pw_uid == 0 || use_privsep)) {
|
||||
c = channel_connect_to_path(target,
|
||||
c = channel_connect_to_path(ssh, target,
|
||||
"direct-streamlocal@openssh.com", "direct-streamlocal");
|
||||
} else {
|
||||
logit("refused streamlocal port forward: "
|
||||
|
@ -514,7 +514,7 @@ server_request_direct_streamlocal(void)
|
|||
}
|
||||
|
||||
static Channel *
|
||||
server_request_tun(void)
|
||||
server_request_tun(struct ssh *ssh)
|
||||
{
|
||||
Channel *c = NULL;
|
||||
int mode, tun;
|
||||
|
@ -544,12 +544,12 @@ server_request_tun(void)
|
|||
sock = tun_open(tun, mode);
|
||||
if (sock < 0)
|
||||
goto done;
|
||||
c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
|
||||
c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1,
|
||||
CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
|
||||
c->datagram = 1;
|
||||
#if defined(SSH_TUN_FILTER)
|
||||
if (mode == SSH_TUNMODE_POINTOPOINT)
|
||||
channel_register_filter(c->self, sys_tun_infilter,
|
||||
channel_register_filter(ssh, c->self, sys_tun_infilter,
|
||||
sys_tun_outfilter, NULL, NULL);
|
||||
#endif
|
||||
|
||||
|
@ -560,7 +560,7 @@ server_request_tun(void)
|
|||
}
|
||||
|
||||
static Channel *
|
||||
server_request_session(void)
|
||||
server_request_session(struct ssh *ssh)
|
||||
{
|
||||
Channel *c;
|
||||
|
||||
|
@ -578,15 +578,15 @@ server_request_session(void)
|
|||
* SSH_CHANNEL_LARVAL. Additionally, a callback for handling all
|
||||
* CHANNEL_REQUEST messages is registered.
|
||||
*/
|
||||
c = channel_new("session", SSH_CHANNEL_LARVAL,
|
||||
c = channel_new(ssh, "session", SSH_CHANNEL_LARVAL,
|
||||
-1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
|
||||
0, "server-session", 1);
|
||||
if (session_open(the_authctxt, c->self) != 1) {
|
||||
debug("session open failed, free channel %d", c->self);
|
||||
channel_free(c);
|
||||
channel_free(ssh, c);
|
||||
return NULL;
|
||||
}
|
||||
channel_register_cleanup(c->self, session_close_by_channel, 0);
|
||||
channel_register_cleanup(ssh, c->self, session_close_by_channel, 0);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -608,17 +608,18 @@ server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
|
|||
ctype, rchan, rwindow, rmaxpack);
|
||||
|
||||
if (strcmp(ctype, "session") == 0) {
|
||||
c = server_request_session();
|
||||
c = server_request_session(ssh);
|
||||
} else if (strcmp(ctype, "direct-tcpip") == 0) {
|
||||
c = server_request_direct_tcpip(&reason, &errmsg);
|
||||
c = server_request_direct_tcpip(ssh, &reason, &errmsg);
|
||||
} else if (strcmp(ctype, "direct-streamlocal@openssh.com") == 0) {
|
||||
c = server_request_direct_streamlocal();
|
||||
c = server_request_direct_streamlocal(ssh);
|
||||
} else if (strcmp(ctype, "tun@openssh.com") == 0) {
|
||||
c = server_request_tun();
|
||||
c = server_request_tun(ssh);
|
||||
}
|
||||
if (c != NULL) {
|
||||
debug("server_input_channel_open: confirm %s", ctype);
|
||||
c->remote_id = rchan;
|
||||
c->have_remote_id = 1;
|
||||
c->remote_window = rwindow;
|
||||
c->remote_maxpacket = rmaxpack;
|
||||
if (c->type != SSH_CHANNEL_CONNECTING) {
|
||||
|
@ -645,9 +646,8 @@ server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
|
|||
}
|
||||
|
||||
static int
|
||||
server_input_hostkeys_prove(struct sshbuf **respp)
|
||||
server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
|
||||
{
|
||||
struct ssh *ssh = active_state; /* XXX */
|
||||
struct sshbuf *resp = NULL;
|
||||
struct sshbuf *sigbuf = NULL;
|
||||
struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL;
|
||||
|
@ -750,7 +750,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
|
|||
packet_send_debug("Server has disabled port forwarding.");
|
||||
} else {
|
||||
/* Start listening on the port */
|
||||
success = channel_setup_remote_fwd_listener(&fwd,
|
||||
success = channel_setup_remote_fwd_listener(ssh, &fwd,
|
||||
&allocated_listen_port, &options.fwd_opts);
|
||||
}
|
||||
free(fwd.listen_host);
|
||||
|
@ -768,7 +768,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
|
|||
debug("%s: cancel-tcpip-forward addr %s port %d", __func__,
|
||||
fwd.listen_host, fwd.listen_port);
|
||||
|
||||
success = channel_cancel_rport_listener(&fwd);
|
||||
success = channel_cancel_rport_listener(ssh, &fwd);
|
||||
free(fwd.listen_host);
|
||||
} else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) {
|
||||
struct Forward fwd;
|
||||
|
@ -787,7 +787,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
|
|||
"streamlocal forwarding.");
|
||||
} else {
|
||||
/* Start listening on the socket */
|
||||
success = channel_setup_remote_fwd_listener(
|
||||
success = channel_setup_remote_fwd_listener(ssh,
|
||||
&fwd, NULL, &options.fwd_opts);
|
||||
}
|
||||
free(fwd.listen_path);
|
||||
|
@ -799,19 +799,19 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
|
|||
debug("%s: cancel-streamlocal-forward path %s", __func__,
|
||||
fwd.listen_path);
|
||||
|
||||
success = channel_cancel_rport_listener(&fwd);
|
||||
success = channel_cancel_rport_listener(ssh, &fwd);
|
||||
free(fwd.listen_path);
|
||||
} else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) {
|
||||
no_more_sessions = 1;
|
||||
success = 1;
|
||||
} else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) {
|
||||
success = server_input_hostkeys_prove(&resp);
|
||||
success = server_input_hostkeys_prove(ssh, &resp);
|
||||
}
|
||||
if (want_reply) {
|
||||
packet_start(success ?
|
||||
SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
|
||||
if (success && resp != NULL)
|
||||
ssh_packet_put_raw(active_state, sshbuf_ptr(resp),
|
||||
ssh_packet_put_raw(ssh, sshbuf_ptr(resp),
|
||||
sshbuf_len(resp));
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
|
@ -835,16 +835,19 @@ server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
|
|||
debug("server_input_channel_req: channel %d request %s reply %d",
|
||||
id, rtype, reply);
|
||||
|
||||
if ((c = channel_lookup(id)) == NULL)
|
||||
if ((c = channel_lookup(ssh, id)) == NULL)
|
||||
packet_disconnect("server_input_channel_req: "
|
||||
"unknown channel %d", id);
|
||||
if (!strcmp(rtype, "eow@openssh.com")) {
|
||||
packet_check_eom();
|
||||
chan_rcvd_eow(c);
|
||||
chan_rcvd_eow(ssh, c);
|
||||
} else if ((c->type == SSH_CHANNEL_LARVAL ||
|
||||
c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0)
|
||||
success = session_input_channel_req(c, rtype);
|
||||
success = session_input_channel_req(ssh, c, rtype);
|
||||
if (reply && !(c->flags & CHAN_CLOSE_SENT)) {
|
||||
if (!c->have_remote_id)
|
||||
fatal("%s: channel %d: no remote_id",
|
||||
__func__, c->self);
|
||||
packet_start(success ?
|
||||
SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
|
||||
packet_put_int(c->remote_id);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: serverloop.h,v 1.7 2016/08/13 17:47:41 markus Exp $ */
|
||||
/* $OpenBSD: serverloop.h,v 1.8 2017/09/12 06:32:07 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
|
@ -21,6 +21,8 @@
|
|||
#ifndef SERVERLOOP_H
|
||||
#define SERVERLOOP_H
|
||||
|
||||
void server_loop2(Authctxt *);
|
||||
struct ssh;
|
||||
|
||||
void server_loop2(struct ssh *, Authctxt *);
|
||||
|
||||
#endif
|
||||
|
|
223
session.c
223
session.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: session.c,v 1.291 2017/08/18 05:36:45 djm Exp $ */
|
||||
/* $OpenBSD: session.c,v 1.292 2017/09/12 06:32:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
|
@ -113,24 +113,24 @@
|
|||
/* func */
|
||||
|
||||
Session *session_new(void);
|
||||
void session_set_fds(Session *, int, int, int, int, int);
|
||||
void session_set_fds(struct ssh *, Session *, int, int, int, int, int);
|
||||
void session_pty_cleanup(Session *);
|
||||
void session_proctitle(Session *);
|
||||
int session_setup_x11fwd(Session *);
|
||||
int do_exec_pty(Session *, const char *);
|
||||
int do_exec_no_pty(Session *, const char *);
|
||||
int do_exec(Session *, const char *);
|
||||
void do_login(Session *, const char *);
|
||||
int session_setup_x11fwd(struct ssh *, Session *);
|
||||
int do_exec_pty(struct ssh *, Session *, const char *);
|
||||
int do_exec_no_pty(struct ssh *, Session *, const char *);
|
||||
int do_exec(struct ssh *, Session *, const char *);
|
||||
void do_login(struct ssh *, Session *, const char *);
|
||||
void do_child(struct ssh *, Session *, const char *);
|
||||
#ifdef LOGIN_NEEDS_UTMPX
|
||||
static void do_pre_login(Session *s);
|
||||
#endif
|
||||
void do_child(Session *, const char *);
|
||||
void do_motd(void);
|
||||
int check_quietlogin(Session *, const char *);
|
||||
|
||||
static void do_authenticated2(Authctxt *);
|
||||
static void do_authenticated2(struct ssh *, Authctxt *);
|
||||
|
||||
static int session_pty_req(Session *);
|
||||
static int session_pty_req(struct ssh *, Session *);
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
|
@ -183,7 +183,7 @@ auth_sock_cleanup_proc(struct passwd *pw)
|
|||
}
|
||||
|
||||
static int
|
||||
auth_input_request_forwarding(struct passwd * pw)
|
||||
auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw)
|
||||
{
|
||||
#ifdef WINDOWS
|
||||
packet_send_debug("Agent forwarding not supported in Windows yet");
|
||||
|
@ -227,7 +227,7 @@ auth_input_request_forwarding(struct passwd * pw)
|
|||
goto authsock_err;
|
||||
|
||||
/* Allocate a channel for the authentication agent socket. */
|
||||
nc = channel_new("auth socket",
|
||||
nc = channel_new(ssh, "auth socket",
|
||||
SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
|
||||
CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
|
||||
0, "auth socket", 1);
|
||||
|
@ -293,7 +293,7 @@ prepare_auth_info_file(struct passwd *pw, struct sshbuf *info)
|
|||
}
|
||||
|
||||
void
|
||||
do_authenticated(Authctxt *authctxt)
|
||||
do_authenticated(struct ssh *ssh, Authctxt *authctxt)
|
||||
{
|
||||
setproctitle("%s", authctxt->pw->pw_name);
|
||||
|
||||
|
@ -301,17 +301,17 @@ do_authenticated(Authctxt *authctxt)
|
|||
/* XXX - streamlocal? */
|
||||
if (no_port_forwarding_flag || options.disable_forwarding ||
|
||||
(options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)
|
||||
channel_disable_adm_local_opens();
|
||||
channel_disable_adm_local_opens(ssh);
|
||||
else
|
||||
channel_permit_all_opens();
|
||||
channel_permit_all_opens(ssh);
|
||||
|
||||
auth_debug_send();
|
||||
|
||||
prepare_auth_info_file(authctxt->pw, authctxt->session_info);
|
||||
|
||||
do_authenticated2(authctxt);
|
||||
do_authenticated2(ssh, authctxt);
|
||||
|
||||
do_cleanup(authctxt);
|
||||
do_cleanup(ssh, authctxt);
|
||||
}
|
||||
|
||||
/* Check untrusted xauth strings for metacharacters */
|
||||
|
@ -608,7 +608,7 @@ do_exec_pty(Session *s, const char *command) {
|
|||
* setting up file descriptors and such.
|
||||
*/
|
||||
int
|
||||
do_exec_no_pty(Session *s, const char *command)
|
||||
do_exec_no_pty(struct ssh *ssh, Session *s, const char *command)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
|
@ -733,7 +733,7 @@ do_exec_no_pty(Session *s, const char *command)
|
|||
#endif
|
||||
|
||||
/* Do processing for the child (exec command etc). */
|
||||
do_child(s, command);
|
||||
do_child(ssh, s, command);
|
||||
/* NOTREACHED */
|
||||
default:
|
||||
break;
|
||||
|
@ -764,7 +764,7 @@ do_exec_no_pty(Session *s, const char *command)
|
|||
close(pout[1]);
|
||||
close(perr[1]);
|
||||
|
||||
session_set_fds(s, pin[1], pout[0], perr[0],
|
||||
session_set_fds(ssh, s, pin[1], pout[0], perr[0],
|
||||
s->is_subsystem, 0);
|
||||
#else
|
||||
/* We are the parent. Close the child sides of the socket pairs. */
|
||||
|
@ -788,7 +788,7 @@ do_exec_no_pty(Session *s, const char *command)
|
|||
* lastlog, and other such operations.
|
||||
*/
|
||||
int
|
||||
do_exec_pty(Session *s, const char *command)
|
||||
do_exec_pty(struct ssh *ssh, Session *s, const char *command)
|
||||
{
|
||||
int fdout, ptyfd, ttyfd, ptymaster;
|
||||
pid_t pid;
|
||||
|
@ -857,13 +857,13 @@ do_exec_pty(Session *s, const char *command)
|
|||
cray_init_job(s->pw); /* set up cray jid and tmpdir */
|
||||
#endif /* _UNICOS */
|
||||
#ifndef HAVE_OSF_SIA
|
||||
do_login(s, command);
|
||||
do_login(ssh, s, command);
|
||||
#endif
|
||||
/*
|
||||
* Do common processing for the child, such as execing
|
||||
* the command.
|
||||
*/
|
||||
do_child(s, command);
|
||||
do_child(ssh, s, command);
|
||||
/* NOTREACHED */
|
||||
default:
|
||||
break;
|
||||
|
@ -885,7 +885,7 @@ do_exec_pty(Session *s, const char *command)
|
|||
s->ptymaster = ptymaster;
|
||||
packet_set_interactive(1,
|
||||
options.ip_qos_interactive, options.ip_qos_bulk);
|
||||
session_set_fds(s, ptyfd, fdout, -1, 1, 1);
|
||||
session_set_fds(ssh, s, ptyfd, fdout, -1, 1, 1);
|
||||
return 0;
|
||||
}
|
||||
#endif /* !WINDOWS */
|
||||
|
@ -924,9 +924,8 @@ do_pre_login(Session *s)
|
|||
* to be forced, execute that instead.
|
||||
*/
|
||||
int
|
||||
do_exec(Session *s, const char *command)
|
||||
do_exec(struct ssh *ssh, Session *s, const char *command)
|
||||
{
|
||||
struct ssh *ssh = active_state; /* XXX */
|
||||
int ret;
|
||||
const char *forced = NULL, *tty = NULL;
|
||||
char session_type[1024];
|
||||
|
@ -985,9 +984,9 @@ do_exec(Session *s, const char *command)
|
|||
}
|
||||
#endif
|
||||
if (s->ttyfd != -1)
|
||||
ret = do_exec_pty(s, command);
|
||||
ret = do_exec_pty(ssh, s, command);
|
||||
else
|
||||
ret = do_exec_no_pty(s, command);
|
||||
ret = do_exec_no_pty(ssh, s, command);
|
||||
|
||||
original_command = NULL;
|
||||
|
||||
|
@ -1003,9 +1002,8 @@ do_exec(Session *s, const char *command)
|
|||
|
||||
/* administrative, login(1)-like work */
|
||||
void
|
||||
do_login(Session *s, const char *command)
|
||||
do_login(struct ssh *ssh, Session *s, const char *command)
|
||||
{
|
||||
struct ssh *ssh = active_state; /* XXX */
|
||||
socklen_t fromlen;
|
||||
struct sockaddr_storage from;
|
||||
struct passwd * pw = s->pw;
|
||||
|
@ -1238,9 +1236,8 @@ copy_environment(char **source, char ***env, u_int *envsize)
|
|||
}
|
||||
|
||||
static char **
|
||||
do_setup_env(Session *s, const char *shell)
|
||||
do_setup_env(struct ssh *ssh, Session *s, const char *shell)
|
||||
{
|
||||
struct ssh *ssh = active_state; /* XXX */
|
||||
char buf[256];
|
||||
u_int i, envsize;
|
||||
char **env, *laddr;
|
||||
|
@ -1699,7 +1696,7 @@ do_pwchange(Session *s)
|
|||
}
|
||||
|
||||
static void
|
||||
child_close_fds(void)
|
||||
child_close_fds(struct ssh *ssh)
|
||||
{
|
||||
extern int auth_sock;
|
||||
|
||||
|
@ -1719,7 +1716,7 @@ child_close_fds(void)
|
|||
* open in the parent.
|
||||
*/
|
||||
/* XXX better use close-on-exec? -markus */
|
||||
channel_close_all();
|
||||
channel_close_all(ssh);
|
||||
|
||||
/*
|
||||
* Close any extra file descriptors. Note that there may still be
|
||||
|
@ -1743,7 +1740,7 @@ child_close_fds(void)
|
|||
*/
|
||||
#define ARGV_MAX 10
|
||||
void
|
||||
do_child(Session *s, const char *command)
|
||||
do_child(struct ssh *ssh, Session *s, const char *command)
|
||||
{
|
||||
#ifdef WINDOWS
|
||||
/*not called for Windows */
|
||||
|
@ -1763,7 +1760,7 @@ do_child(Session *s, const char *command)
|
|||
/* Force a password change */
|
||||
if (s->authctxt->force_pwchange) {
|
||||
do_setusercontext(pw);
|
||||
child_close_fds();
|
||||
child_close_fds(ssh);
|
||||
do_pwchange(s);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -1812,7 +1809,7 @@ do_child(Session *s, const char *command)
|
|||
* Make sure $SHELL points to the shell from the password file,
|
||||
* even if shell is overridden from login.conf
|
||||
*/
|
||||
env = do_setup_env(s, shell);
|
||||
env = do_setup_env(ssh, s, shell);
|
||||
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
|
||||
|
@ -1825,7 +1822,7 @@ do_child(Session *s, const char *command)
|
|||
* closed before building the environment, as we call
|
||||
* ssh_remote_ipaddr there.
|
||||
*/
|
||||
child_close_fds();
|
||||
child_close_fds(ssh);
|
||||
|
||||
/*
|
||||
* Must take new environment into use so that .ssh/rc,
|
||||
|
@ -2123,7 +2120,7 @@ session_by_pid(pid_t pid)
|
|||
}
|
||||
|
||||
static int
|
||||
session_window_change_req(Session *s)
|
||||
session_window_change_req(struct ssh *ssh, Session *s)
|
||||
{
|
||||
s->col = packet_get_int();
|
||||
s->row = packet_get_int();
|
||||
|
@ -2135,7 +2132,7 @@ session_window_change_req(Session *s)
|
|||
}
|
||||
|
||||
static int
|
||||
session_pty_req(Session *s)
|
||||
session_pty_req(struct ssh *ssh, Session *s)
|
||||
{
|
||||
u_int len;
|
||||
int n_bytes;
|
||||
|
@ -2188,7 +2185,7 @@ session_pty_req(Session *s)
|
|||
}
|
||||
|
||||
static int
|
||||
session_subsystem_req(Session *s)
|
||||
session_subsystem_req(struct ssh *ssh, Session *s)
|
||||
{
|
||||
struct stat st;
|
||||
u_int len;
|
||||
|
@ -2215,7 +2212,7 @@ session_subsystem_req(Session *s)
|
|||
s->is_subsystem = SUBSYSTEM_EXT;
|
||||
debug("subsystem: exec() %s", cmd);
|
||||
}
|
||||
success = do_exec(s, cmd) == 0;
|
||||
success = do_exec(ssh, s, cmd) == 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2228,7 +2225,7 @@ session_subsystem_req(Session *s)
|
|||
}
|
||||
|
||||
static int
|
||||
session_x11_req(Session *s)
|
||||
session_x11_req(struct ssh *ssh, Session *s)
|
||||
{
|
||||
int success;
|
||||
|
||||
|
@ -2245,7 +2242,7 @@ session_x11_req(Session *s)
|
|||
|
||||
if (xauth_valid_string(s->auth_proto) &&
|
||||
xauth_valid_string(s->auth_data))
|
||||
success = session_setup_x11fwd(s);
|
||||
success = session_setup_x11fwd(ssh, s);
|
||||
else {
|
||||
success = 0;
|
||||
error("Invalid X11 forwarding data");
|
||||
|
@ -2260,26 +2257,26 @@ session_x11_req(Session *s)
|
|||
}
|
||||
|
||||
static int
|
||||
session_shell_req(Session *s)
|
||||
session_shell_req(struct ssh *ssh, Session *s)
|
||||
{
|
||||
packet_check_eom();
|
||||
return do_exec(s, NULL) == 0;
|
||||
return do_exec(ssh, s, NULL) == 0;
|
||||
}
|
||||
|
||||
static int
|
||||
session_exec_req(Session *s)
|
||||
session_exec_req(struct ssh *ssh, Session *s)
|
||||
{
|
||||
u_int len, success;
|
||||
|
||||
char *command = packet_get_string(&len);
|
||||
packet_check_eom();
|
||||
success = do_exec(s, command) == 0;
|
||||
success = do_exec(ssh, s, command) == 0;
|
||||
free(command);
|
||||
return success;
|
||||
}
|
||||
|
||||
static int
|
||||
session_break_req(Session *s)
|
||||
session_break_req(struct ssh *ssh, Session *s)
|
||||
{
|
||||
|
||||
packet_get_int(); /* ignored */
|
||||
|
@ -2291,7 +2288,7 @@ session_break_req(Session *s)
|
|||
}
|
||||
|
||||
static int
|
||||
session_env_req(Session *s)
|
||||
session_env_req(struct ssh *ssh, Session *s)
|
||||
{
|
||||
char *name, *val;
|
||||
u_int name_len, val_len, i;
|
||||
|
@ -2326,7 +2323,7 @@ session_env_req(Session *s)
|
|||
}
|
||||
|
||||
static int
|
||||
session_auth_agent_req(Session *s)
|
||||
session_auth_agent_req(struct ssh *ssh, Session *s)
|
||||
{
|
||||
static int called = 0;
|
||||
packet_check_eom();
|
||||
|
@ -2338,22 +2335,21 @@ session_auth_agent_req(Session *s)
|
|||
return 0;
|
||||
} else {
|
||||
called = 1;
|
||||
return auth_input_request_forwarding(s->pw);
|
||||
return auth_input_request_forwarding(ssh, s->pw);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
session_input_channel_req(Channel *c, const char *rtype)
|
||||
session_input_channel_req(struct ssh *ssh, Channel *c, const char *rtype)
|
||||
{
|
||||
int success = 0;
|
||||
Session *s;
|
||||
|
||||
if ((s = session_by_channel(c->self)) == NULL) {
|
||||
logit("session_input_channel_req: no session %d req %.100s",
|
||||
c->self, rtype);
|
||||
logit("%s: no session %d req %.100s", __func__, c->self, rtype);
|
||||
return 0;
|
||||
}
|
||||
debug("session_input_channel_req: session %d req %s", s->self, rtype);
|
||||
debug("%s: session %d req %s", __func__, s->self, rtype);
|
||||
|
||||
/*
|
||||
* a session is in LARVAL state until a shell, a command
|
||||
|
@ -2361,33 +2357,33 @@ session_input_channel_req(Channel *c, const char *rtype)
|
|||
*/
|
||||
if (c->type == SSH_CHANNEL_LARVAL) {
|
||||
if (strcmp(rtype, "shell") == 0) {
|
||||
success = session_shell_req(s);
|
||||
success = session_shell_req(ssh, s);
|
||||
} else if (strcmp(rtype, "exec") == 0) {
|
||||
success = session_exec_req(s);
|
||||
success = session_exec_req(ssh, s);
|
||||
} else if (strcmp(rtype, "pty-req") == 0) {
|
||||
success = session_pty_req(s);
|
||||
success = session_pty_req(ssh, s);
|
||||
} else if (strcmp(rtype, "x11-req") == 0) {
|
||||
success = session_x11_req(s);
|
||||
success = session_x11_req(ssh, s);
|
||||
} else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
|
||||
success = session_auth_agent_req(s);
|
||||
success = session_auth_agent_req(ssh, s);
|
||||
} else if (strcmp(rtype, "subsystem") == 0) {
|
||||
success = session_subsystem_req(s);
|
||||
success = session_subsystem_req(ssh, s);
|
||||
} else if (strcmp(rtype, "env") == 0) {
|
||||
success = session_env_req(s);
|
||||
success = session_env_req(ssh, s);
|
||||
}
|
||||
}
|
||||
if (strcmp(rtype, "window-change") == 0) {
|
||||
success = session_window_change_req(s);
|
||||
success = session_window_change_req(ssh, s);
|
||||
} else if (strcmp(rtype, "break") == 0) {
|
||||
success = session_break_req(s);
|
||||
success = session_break_req(ssh, s);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void
|
||||
session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr,
|
||||
int is_tty)
|
||||
session_set_fds(struct ssh *ssh, Session *s,
|
||||
int fdin, int fdout, int fderr, int ignore_fderr, int is_tty)
|
||||
{
|
||||
/*
|
||||
* now that have a child and a pipe to the child,
|
||||
|
@ -2395,7 +2391,7 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr,
|
|||
*/
|
||||
if (s->chanid == -1)
|
||||
fatal("no channel for session %d", s->self);
|
||||
channel_set_fds(s->chanid,
|
||||
channel_set_fds(ssh, s->chanid,
|
||||
fdout, fdin, fderr,
|
||||
ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
|
||||
1, is_tty, CHAN_SES_WINDOW_DEFAULT);
|
||||
|
@ -2466,40 +2462,40 @@ sig2name(int sig)
|
|||
}
|
||||
|
||||
static void
|
||||
session_close_x11(int id)
|
||||
session_close_x11(struct ssh *ssh, int id)
|
||||
{
|
||||
Channel *c;
|
||||
|
||||
if ((c = channel_by_id(id)) == NULL) {
|
||||
debug("session_close_x11: x11 channel %d missing", id);
|
||||
if ((c = channel_by_id(ssh, id)) == NULL) {
|
||||
debug("%s: x11 channel %d missing", __func__, id);
|
||||
} else {
|
||||
/* Detach X11 listener */
|
||||
debug("session_close_x11: detach x11 channel %d", id);
|
||||
channel_cancel_cleanup(id);
|
||||
debug("%s: detach x11 channel %d", __func__, id);
|
||||
channel_cancel_cleanup(ssh, id);
|
||||
if (c->ostate != CHAN_OUTPUT_CLOSED)
|
||||
chan_mark_dead(c);
|
||||
chan_mark_dead(ssh, c);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
session_close_single_x11(int id, void *arg)
|
||||
session_close_single_x11(struct ssh *ssh, int id, void *arg)
|
||||
{
|
||||
Session *s;
|
||||
u_int i;
|
||||
|
||||
debug3("session_close_single_x11: channel %d", id);
|
||||
channel_cancel_cleanup(id);
|
||||
debug3("%s: channel %d", __func__, id);
|
||||
channel_cancel_cleanup(ssh, id);
|
||||
if ((s = session_by_x11_channel(id)) == NULL)
|
||||
fatal("session_close_single_x11: no x11 channel %d", id);
|
||||
fatal("%s: no x11 channel %d", __func__, id);
|
||||
for (i = 0; s->x11_chanids[i] != -1; i++) {
|
||||
debug("session_close_single_x11: session %d: "
|
||||
"closing channel %d", s->self, s->x11_chanids[i]);
|
||||
debug("%s: session %d: closing channel %d",
|
||||
__func__, s->self, s->x11_chanids[i]);
|
||||
/*
|
||||
* The channel "id" is already closing, but make sure we
|
||||
* close all of its siblings.
|
||||
*/
|
||||
if (s->x11_chanids[i] != id)
|
||||
session_close_x11(s->x11_chanids[i]);
|
||||
session_close_x11(ssh, s->x11_chanids[i]);
|
||||
}
|
||||
free(s->x11_chanids);
|
||||
s->x11_chanids = NULL;
|
||||
|
@ -2514,22 +2510,22 @@ session_close_single_x11(int id, void *arg)
|
|||
}
|
||||
|
||||
static void
|
||||
session_exit_message(Session *s, int status)
|
||||
session_exit_message(struct ssh *ssh, Session *s, int status)
|
||||
{
|
||||
Channel *c;
|
||||
|
||||
if ((c = channel_lookup(s->chanid)) == NULL)
|
||||
fatal("session_exit_message: session %d: no channel %d",
|
||||
s->self, s->chanid);
|
||||
debug("session_exit_message: session %d channel %d pid %ld",
|
||||
s->self, s->chanid, (long)s->pid);
|
||||
if ((c = channel_lookup(ssh, s->chanid)) == NULL)
|
||||
fatal("%s: session %d: no channel %d",
|
||||
__func__, s->self, s->chanid);
|
||||
debug("%s: session %d channel %d pid %ld",
|
||||
__func__, s->self, s->chanid, (long)s->pid);
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
channel_request_start(s->chanid, "exit-status", 0);
|
||||
channel_request_start(ssh, s->chanid, "exit-status", 0);
|
||||
packet_put_int(WEXITSTATUS(status));
|
||||
packet_send();
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
channel_request_start(s->chanid, "exit-signal", 0);
|
||||
channel_request_start(ssh, s->chanid, "exit-signal", 0);
|
||||
packet_put_cstring(sig2name(WTERMSIG(status)));
|
||||
#ifdef WCOREDUMP
|
||||
packet_put_char(WCOREDUMP(status)? 1 : 0);
|
||||
|
@ -2545,14 +2541,14 @@ session_exit_message(Session *s, int status)
|
|||
}
|
||||
|
||||
/* disconnect channel */
|
||||
debug("session_exit_message: release channel %d", s->chanid);
|
||||
debug("%s: release channel %d", __func__, s->chanid);
|
||||
|
||||
/*
|
||||
* Adjust cleanup callback attachment to send close messages when
|
||||
* the channel gets EOF. The session will be then be closed
|
||||
* by session_close_by_channel when the childs close their fds.
|
||||
*/
|
||||
channel_register_cleanup(c->self, session_close_by_channel, 1);
|
||||
channel_register_cleanup(ssh, c->self, session_close_by_channel, 1);
|
||||
|
||||
/*
|
||||
* emulate a write failure with 'chan_write_failed', nobody will be
|
||||
|
@ -2561,13 +2557,12 @@ session_exit_message(Session *s, int status)
|
|||
* be some more data waiting in the pipe.
|
||||
*/
|
||||
if (c->ostate != CHAN_OUTPUT_CLOSED)
|
||||
chan_write_failed(c);
|
||||
chan_write_failed(ssh, c);
|
||||
}
|
||||
|
||||
void
|
||||
session_close(Session *s)
|
||||
session_close(struct ssh *ssh, Session *s)
|
||||
{
|
||||
struct ssh *ssh = active_state; /* XXX */
|
||||
u_int i;
|
||||
|
||||
verbose("Close session: user %s from %.200s port %d id %d",
|
||||
|
@ -2597,16 +2592,15 @@ session_close(Session *s)
|
|||
}
|
||||
|
||||
void
|
||||
session_close_by_pid(pid_t pid, int status)
|
||||
session_close_by_pid(struct ssh *ssh, pid_t pid, int status)
|
||||
{
|
||||
Session *s = session_by_pid(pid);
|
||||
if (s == NULL) {
|
||||
debug("session_close_by_pid: no session for pid %ld",
|
||||
(long)pid);
|
||||
debug("%s: no session for pid %ld", __func__, (long)pid);
|
||||
return;
|
||||
}
|
||||
if (s->chanid != -1)
|
||||
session_exit_message(s, status);
|
||||
session_exit_message(ssh, s, status);
|
||||
if (s->ttyfd != -1)
|
||||
session_pty_cleanup(s);
|
||||
s->pid = 0;
|
||||
|
@ -2617,19 +2611,18 @@ session_close_by_pid(pid_t pid, int status)
|
|||
* the session 'child' itself dies
|
||||
*/
|
||||
void
|
||||
session_close_by_channel(int id, void *arg)
|
||||
session_close_by_channel(struct ssh *ssh, int id, void *arg)
|
||||
{
|
||||
Session *s = session_by_channel(id);
|
||||
u_int i;
|
||||
|
||||
if (s == NULL) {
|
||||
debug("session_close_by_channel: no session for id %d", id);
|
||||
debug("%s: no session for id %d", __func__, id);
|
||||
return;
|
||||
}
|
||||
debug("session_close_by_channel: channel %d child %ld",
|
||||
id, (long)s->pid);
|
||||
debug("%s: channel %d child %ld", __func__, id, (long)s->pid);
|
||||
if (s->pid != 0) {
|
||||
debug("session_close_by_channel: channel %d: has child", id);
|
||||
debug("%s: channel %d: has child", __func__, id);
|
||||
/*
|
||||
* delay detach of session, but release pty, since
|
||||
* the fd's to the child are already closed
|
||||
|
@ -2639,22 +2632,22 @@ session_close_by_channel(int id, void *arg)
|
|||
return;
|
||||
}
|
||||
/* detach by removing callback */
|
||||
channel_cancel_cleanup(s->chanid);
|
||||
channel_cancel_cleanup(ssh, s->chanid);
|
||||
|
||||
/* Close any X11 listeners associated with this session */
|
||||
if (s->x11_chanids != NULL) {
|
||||
for (i = 0; s->x11_chanids[i] != -1; i++) {
|
||||
session_close_x11(s->x11_chanids[i]);
|
||||
session_close_x11(ssh, s->x11_chanids[i]);
|
||||
s->x11_chanids[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
s->chanid = -1;
|
||||
session_close(s);
|
||||
session_close(ssh, s);
|
||||
}
|
||||
|
||||
void
|
||||
session_destroy_all(void (*closefunc)(Session *))
|
||||
session_destroy_all(struct ssh *ssh, void (*closefunc)(Session *))
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sessions_nalloc; i++) {
|
||||
|
@ -2663,7 +2656,7 @@ session_destroy_all(void (*closefunc)(Session *))
|
|||
if (closefunc != NULL)
|
||||
closefunc(s);
|
||||
else
|
||||
session_close(s);
|
||||
session_close(ssh, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2706,7 +2699,7 @@ session_proctitle(Session *s)
|
|||
}
|
||||
|
||||
int
|
||||
session_setup_x11fwd(Session *s)
|
||||
session_setup_x11fwd(struct ssh *ssh, Session *s)
|
||||
{
|
||||
struct stat st;
|
||||
char display[512], auth_display[512];
|
||||
|
@ -2730,14 +2723,14 @@ session_setup_x11fwd(Session *s)
|
|||
debug("X11 display already set.");
|
||||
return 0;
|
||||
}
|
||||
if (x11_create_display_inet(options.x11_display_offset,
|
||||
if (x11_create_display_inet(ssh, options.x11_display_offset,
|
||||
options.x11_use_localhost, s->single_connection,
|
||||
&s->display_number, &s->x11_chanids) == -1) {
|
||||
debug("x11_create_display_inet failed.");
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; s->x11_chanids[i] != -1; i++) {
|
||||
channel_register_cleanup(s->x11_chanids[i],
|
||||
channel_register_cleanup(ssh, s->x11_chanids[i],
|
||||
session_close_single_x11, 0);
|
||||
}
|
||||
|
||||
|
@ -2782,13 +2775,13 @@ session_setup_x11fwd(Session *s)
|
|||
}
|
||||
|
||||
static void
|
||||
do_authenticated2(Authctxt *authctxt)
|
||||
do_authenticated2(struct ssh *ssh, Authctxt *authctxt)
|
||||
{
|
||||
server_loop2(authctxt);
|
||||
server_loop2(ssh, authctxt);
|
||||
}
|
||||
|
||||
void
|
||||
do_cleanup(Authctxt *authctxt)
|
||||
do_cleanup(struct ssh *ssh, Authctxt *authctxt)
|
||||
{
|
||||
static int called = 0;
|
||||
|
||||
|
@ -2844,7 +2837,7 @@ do_cleanup(Authctxt *authctxt)
|
|||
* or if running in monitor.
|
||||
*/
|
||||
if (!use_privsep || mm_is_monitor())
|
||||
session_destroy_all(session_pty_cleanup2);
|
||||
session_destroy_all(ssh, session_pty_cleanup2);
|
||||
}
|
||||
|
||||
/* Return a name for the remote host that fits inside utmp_size */
|
||||
|
|
16
session.h
16
session.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: session.h,v 1.34 2017/08/18 05:36:45 djm Exp $ */
|
||||
/* $OpenBSD: session.h,v 1.35 2017/09/12 06:32:07 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
|
||||
|
@ -62,20 +62,20 @@ struct Session {
|
|||
} *env;
|
||||
};
|
||||
|
||||
void do_authenticated(Authctxt *);
|
||||
void do_cleanup(Authctxt *);
|
||||
void do_authenticated(struct ssh *, Authctxt *);
|
||||
void do_cleanup(struct ssh *, Authctxt *);
|
||||
|
||||
int session_open(Authctxt *, int);
|
||||
void session_unused(int);
|
||||
int session_input_channel_req(Channel *, const char *);
|
||||
void session_close_by_pid(pid_t, int);
|
||||
void session_close_by_channel(int, void *);
|
||||
void session_destroy_all(void (*)(Session *));
|
||||
int session_input_channel_req(struct ssh *, Channel *, const char *);
|
||||
void session_close_by_pid(struct ssh *ssh, pid_t, int);
|
||||
void session_close_by_channel(struct ssh *, int, void *);
|
||||
void session_destroy_all(struct ssh *, void (*)(Session *));
|
||||
void session_pty_cleanup2(Session *);
|
||||
|
||||
Session *session_new(void);
|
||||
Session *session_by_tty(char *);
|
||||
void session_close(Session *);
|
||||
void session_close(struct ssh *, Session *);
|
||||
void do_setusercontext(struct passwd *);
|
||||
|
||||
const char *session_get_remote_name_or_ip(struct ssh *, u_int, int);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $OpenBSD: ssh-add.1,v 1.64 2017/05/05 10:41:58 naddy Exp $
|
||||
.\" $OpenBSD: ssh-add.1,v 1.66 2017/08/29 13:05:58 jmc Exp $
|
||||
.\"
|
||||
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -35,7 +35,7 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: May 5 2017 $
|
||||
.Dd $Mdocdate: August 29 2017 $
|
||||
.Dt SSH-ADD 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -43,7 +43,7 @@
|
|||
.Nd adds private key identities to the authentication agent
|
||||
.Sh SYNOPSIS
|
||||
.Nm ssh-add
|
||||
.Op Fl cDdkLlXx
|
||||
.Op Fl cDdkLlqXx
|
||||
.Op Fl E Ar fingerprint_hash
|
||||
.Op Fl t Ar life
|
||||
.Op Ar
|
||||
|
@ -126,6 +126,8 @@ Lists public key parameters of all identities currently represented
|
|||
by the agent.
|
||||
.It Fl l
|
||||
Lists fingerprints of all identities currently represented by the agent.
|
||||
.It Fl q
|
||||
Be quiet after a successful operation.
|
||||
.It Fl s Ar pkcs11
|
||||
Add keys provided by the PKCS#11 shared library
|
||||
.Ar pkcs11 .
|
||||
|
|
36
ssh-add.c
36
ssh-add.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh-add.c,v 1.133 2017/07/01 13:50:45 djm Exp $ */
|
||||
/* $OpenBSD: ssh-add.c,v 1.134 2017/08/29 09:42:29 dlg Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -102,7 +102,7 @@ clear_pass(void)
|
|||
}
|
||||
|
||||
static int
|
||||
delete_file(int agent_fd, const char *filename, int key_only)
|
||||
delete_file(int agent_fd, const char *filename, int key_only, int qflag)
|
||||
{
|
||||
struct sshkey *public, *cert = NULL;
|
||||
char *certpath = NULL, *comment = NULL;
|
||||
|
@ -113,7 +113,10 @@ delete_file(int agent_fd, const char *filename, int key_only)
|
|||
return -1;
|
||||
}
|
||||
if ((r = ssh_remove_identity(agent_fd, public)) == 0) {
|
||||
fprintf(stderr, "Identity removed: %s (%s)\n", filename, comment);
|
||||
if (!qflag) {
|
||||
fprintf(stderr, "Identity removed: %s (%s)\n",
|
||||
filename, comment);
|
||||
}
|
||||
ret = 0;
|
||||
} else
|
||||
fprintf(stderr, "Could not remove identity \"%s\": %s\n",
|
||||
|
@ -138,8 +141,10 @@ delete_file(int agent_fd, const char *filename, int key_only)
|
|||
certpath, filename);
|
||||
|
||||
if ((r = ssh_remove_identity(agent_fd, cert)) == 0) {
|
||||
fprintf(stderr, "Identity removed: %s (%s)\n", certpath,
|
||||
comment);
|
||||
if (!qflag) {
|
||||
fprintf(stderr, "Identity removed: %s (%s)\n",
|
||||
certpath, comment);
|
||||
}
|
||||
ret = 0;
|
||||
} else
|
||||
fprintf(stderr, "Could not remove identity \"%s\": %s\n",
|
||||
|
@ -179,7 +184,7 @@ delete_all(int agent_fd)
|
|||
}
|
||||
|
||||
static int
|
||||
add_file(int agent_fd, const char *filename, int key_only)
|
||||
add_file(int agent_fd, const char *filename, int key_only, int qflag)
|
||||
{
|
||||
struct sshkey *private, *cert;
|
||||
char *comment = NULL;
|
||||
|
@ -427,13 +432,13 @@ lock_agent(int agent_fd, int lock)
|
|||
}
|
||||
|
||||
static int
|
||||
do_file(int agent_fd, int deleting, int key_only, char *file)
|
||||
do_file(int agent_fd, int deleting, int key_only, char *file, int qflag)
|
||||
{
|
||||
if (deleting) {
|
||||
if (delete_file(agent_fd, file, key_only) == -1)
|
||||
if (delete_file(agent_fd, file, key_only, qflag) == -1)
|
||||
return -1;
|
||||
} else {
|
||||
if (add_file(agent_fd, file, key_only) == -1)
|
||||
if (add_file(agent_fd, file, key_only, qflag) == -1)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -456,6 +461,7 @@ usage(void)
|
|||
fprintf(stderr, " -X Unlock agent.\n");
|
||||
fprintf(stderr, " -s pkcs11 Add keys from PKCS#11 provider.\n");
|
||||
fprintf(stderr, " -e pkcs11 Remove keys provided by PKCS#11 provider.\n");
|
||||
fprintf(stderr, " -q Be quiet after a successful operation.\n");
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -466,7 +472,7 @@ main(int argc, char **argv)
|
|||
int agent_fd;
|
||||
char *pkcs11provider = NULL;
|
||||
int r, i, ch, deleting = 0, ret = 0, key_only = 0;
|
||||
int xflag = 0, lflag = 0, Dflag = 0;
|
||||
int xflag = 0, lflag = 0, Dflag = 0, qflag = 0;
|
||||
|
||||
ssh_malloc_init(); /* must be called before any mallocs */
|
||||
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
|
||||
|
@ -494,7 +500,7 @@ main(int argc, char **argv)
|
|||
exit(2);
|
||||
}
|
||||
|
||||
while ((ch = getopt(argc, argv, "klLcdDxXE:e:s:t:")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "klLcdDxXE:e:qs:t:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'E':
|
||||
fingerprint_hash = ssh_digest_alg_by_name(optarg);
|
||||
|
@ -539,6 +545,9 @@ main(int argc, char **argv)
|
|||
goto done;
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
qflag = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
ret = 1;
|
||||
|
@ -587,7 +596,8 @@ main(int argc, char **argv)
|
|||
default_files[i]);
|
||||
if (stat(buf, &st) < 0)
|
||||
continue;
|
||||
if (do_file(agent_fd, deleting, key_only, buf) == -1)
|
||||
if (do_file(agent_fd, deleting, key_only, buf,
|
||||
qflag) == -1)
|
||||
ret = 1;
|
||||
else
|
||||
count++;
|
||||
|
@ -597,7 +607,7 @@ main(int argc, char **argv)
|
|||
} else {
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (do_file(agent_fd, deleting, key_only,
|
||||
argv[i]) == -1)
|
||||
argv[i], qflag) == -1)
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
|
21
ssh.1
21
ssh.1
|
@ -33,8 +33,8 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: ssh.1,v 1.383 2017/06/09 06:43:01 djm Exp $
|
||||
.Dd $Mdocdate: June 9 2017 $
|
||||
.\" $OpenBSD: ssh.1,v 1.384 2017/09/21 19:16:53 markus Exp $
|
||||
.Dd $Mdocdate: September 21 2017 $
|
||||
.Dt SSH 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -592,21 +592,30 @@ Causes most warning and diagnostic messages to be suppressed.
|
|||
.Ar remote_socket : local_socket
|
||||
.Sm on
|
||||
.Xc
|
||||
.It Fl R Xo
|
||||
.Sm off
|
||||
.Oo Ar bind_address : Oc
|
||||
.Ar port
|
||||
.Sm on
|
||||
.Xc
|
||||
Specifies that connections to the given TCP port or Unix socket on the remote
|
||||
(server) host are to be forwarded to the given host and port, or Unix socket,
|
||||
on the local side.
|
||||
(server) host are to be forwarded to the local side.
|
||||
.Pp
|
||||
This works by allocating a socket to listen to either a TCP
|
||||
.Ar port
|
||||
or to a Unix socket on the remote side.
|
||||
Whenever a connection is made to this port or Unix socket, the
|
||||
connection is forwarded over the secure channel, and a connection
|
||||
is made to either
|
||||
is made from the local machine to either an explicit destination specified by
|
||||
.Ar host
|
||||
port
|
||||
.Ar hostport ,
|
||||
or
|
||||
.Ar local_socket ,
|
||||
from the local machine.
|
||||
or, if no explicit destination was specified,
|
||||
.Nm
|
||||
will act as a SOCKS 4/5 proxy and forward connections to the destinations
|
||||
requested by the remote SOCKS client.
|
||||
.Pp
|
||||
Port forwardings can also be specified in the configuration file.
|
||||
Privileged ports can be forwarded only when
|
||||
|
|
91
ssh.c
91
ssh.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssh.c,v 1.462 2017/08/12 06:46:01 djm Exp $ */
|
||||
/* $OpenBSD: ssh.c,v 1.464 2017/09/21 19:16:53 markus Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -208,7 +208,7 @@ usage(void)
|
|||
exit(255);
|
||||
}
|
||||
|
||||
static int ssh_session2(void);
|
||||
static int ssh_session2(struct ssh *);
|
||||
static void load_public_identity_files(void);
|
||||
static void main_sigchld_handler(int);
|
||||
|
||||
|
@ -596,6 +596,14 @@ main(int ac, char **av)
|
|||
*/
|
||||
initialize_options(&options);
|
||||
|
||||
/*
|
||||
* Prepare main ssh transport/connection structures
|
||||
*/
|
||||
if ((ssh = ssh_alloc_session_state()) == NULL)
|
||||
fatal("Couldn't allocate session state");
|
||||
channel_init_channels(ssh);
|
||||
active_state = ssh; /* XXX legacy API compat */
|
||||
|
||||
/* Parse command-line arguments. */
|
||||
host = NULL;
|
||||
use_syslog = 0;
|
||||
|
@ -860,7 +868,8 @@ main(int ac, char **av)
|
|||
break;
|
||||
|
||||
case 'R':
|
||||
if (parse_forward(&fwd, optarg, 0, 1)) {
|
||||
if (parse_forward(&fwd, optarg, 0, 1) ||
|
||||
parse_forward(&fwd, optarg, 1, 1)) {
|
||||
add_remote_forward(&options, &fwd);
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
|
@ -1108,7 +1117,7 @@ main(int ac, char **av)
|
|||
|
||||
if (options.port == 0)
|
||||
options.port = default_ssh_port();
|
||||
channel_set_af(options.address_family);
|
||||
channel_set_af(ssh, options.address_family);
|
||||
|
||||
/* Tidy and check options */
|
||||
if (options.host_key_alias != NULL)
|
||||
|
@ -1253,8 +1262,7 @@ main(int ac, char **av)
|
|||
if (options.control_path != NULL) {
|
||||
int sock;
|
||||
if ((sock = muxclient(options.control_path)) >= 0) {
|
||||
packet_set_connection(sock, sock);
|
||||
ssh = active_state; /* XXX */
|
||||
ssh_packet_set_connection(ssh, sock, sock);
|
||||
packet_set_mux();
|
||||
goto skip_connect;
|
||||
}
|
||||
|
@ -1274,7 +1282,7 @@ main(int ac, char **av)
|
|||
timeout_ms = options.connection_timeout * 1000;
|
||||
|
||||
/* Open a connection to the remote host. */
|
||||
if (ssh_connect(host, addrs, &hostaddr, options.port,
|
||||
if (ssh_connect(ssh, host, addrs, &hostaddr, options.port,
|
||||
options.address_family, options.connection_attempts,
|
||||
&timeout_ms, options.tcp_keep_alive,
|
||||
options.use_privileged_port) != 0)
|
||||
|
@ -1457,7 +1465,7 @@ main(int ac, char **av)
|
|||
}
|
||||
|
||||
skip_connect:
|
||||
exit_status = ssh_session2();
|
||||
exit_status = ssh_session2(ssh);
|
||||
packet_close();
|
||||
|
||||
if (options.control_path != NULL && muxserver_sock != -1)
|
||||
|
@ -1539,7 +1547,7 @@ fork_postauth(void)
|
|||
|
||||
/* Callback for remote forward global requests */
|
||||
static void
|
||||
ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
|
||||
ssh_confirm_remote_forward(struct ssh *ssh, int type, u_int32_t seq, void *ctxt)
|
||||
{
|
||||
struct Forward *rfwd = (struct Forward *)ctxt;
|
||||
|
||||
|
@ -1557,10 +1565,10 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
|
|||
logit("Allocated port %u for remote forward to %s:%d",
|
||||
rfwd->allocated_port,
|
||||
rfwd->connect_host, rfwd->connect_port);
|
||||
channel_update_permitted_opens(rfwd->handle,
|
||||
rfwd->allocated_port);
|
||||
channel_update_permitted_opens(ssh,
|
||||
rfwd->handle, rfwd->allocated_port);
|
||||
} else {
|
||||
channel_update_permitted_opens(rfwd->handle, -1);
|
||||
channel_update_permitted_opens(ssh, rfwd->handle, -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1589,21 +1597,21 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt)
|
|||
}
|
||||
|
||||
static void
|
||||
client_cleanup_stdio_fwd(int id, void *arg)
|
||||
client_cleanup_stdio_fwd(struct ssh *ssh, int id, void *arg)
|
||||
{
|
||||
debug("stdio forwarding: done");
|
||||
cleanup_exit(0);
|
||||
}
|
||||
|
||||
static void
|
||||
ssh_stdio_confirm(int id, int success, void *arg)
|
||||
ssh_stdio_confirm(struct ssh *ssh, int id, int success, void *arg)
|
||||
{
|
||||
if (!success)
|
||||
fatal("stdio forwarding failed");
|
||||
}
|
||||
|
||||
static void
|
||||
ssh_init_stdio_forwarding(void)
|
||||
ssh_init_stdio_forwarding(struct ssh *ssh)
|
||||
{
|
||||
Channel *c;
|
||||
int in, out;
|
||||
|
@ -1617,15 +1625,15 @@ ssh_init_stdio_forwarding(void)
|
|||
if ((in = dup(STDIN_FILENO)) < 0 ||
|
||||
(out = dup(STDOUT_FILENO)) < 0)
|
||||
fatal("channel_connect_stdio_fwd: dup() in/out failed");
|
||||
if ((c = channel_connect_stdio_fwd(options.stdio_forward_host,
|
||||
if ((c = channel_connect_stdio_fwd(ssh, options.stdio_forward_host,
|
||||
options.stdio_forward_port, in, out)) == NULL)
|
||||
fatal("%s: channel_connect_stdio_fwd failed", __func__);
|
||||
channel_register_cleanup(c->self, client_cleanup_stdio_fwd, 0);
|
||||
channel_register_open_confirm(c->self, ssh_stdio_confirm, NULL);
|
||||
channel_register_cleanup(ssh, c->self, client_cleanup_stdio_fwd, 0);
|
||||
channel_register_open_confirm(ssh, c->self, ssh_stdio_confirm, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
ssh_init_forwarding(void)
|
||||
ssh_init_forwarding(struct ssh *ssh)
|
||||
{
|
||||
int success = 0;
|
||||
int i;
|
||||
|
@ -1644,7 +1652,7 @@ ssh_init_forwarding(void)
|
|||
options.local_forwards[i].connect_path :
|
||||
options.local_forwards[i].connect_host,
|
||||
options.local_forwards[i].connect_port);
|
||||
success += channel_setup_local_fwd_listener(
|
||||
success += channel_setup_local_fwd_listener(ssh,
|
||||
&options.local_forwards[i], &options.fwd_opts);
|
||||
}
|
||||
if (i > 0 && success != i && options.exit_on_forward_failure)
|
||||
|
@ -1666,7 +1674,7 @@ ssh_init_forwarding(void)
|
|||
options.remote_forwards[i].connect_host,
|
||||
options.remote_forwards[i].connect_port);
|
||||
options.remote_forwards[i].handle =
|
||||
channel_request_remote_forwarding(
|
||||
channel_request_remote_forwarding(ssh,
|
||||
&options.remote_forwards[i]);
|
||||
if (options.remote_forwards[i].handle < 0) {
|
||||
if (options.exit_on_forward_failure)
|
||||
|
@ -1675,14 +1683,15 @@ ssh_init_forwarding(void)
|
|||
logit("Warning: Could not request remote "
|
||||
"forwarding.");
|
||||
} else {
|
||||
client_register_global_confirm(ssh_confirm_remote_forward,
|
||||
client_register_global_confirm(
|
||||
ssh_confirm_remote_forward,
|
||||
&options.remote_forwards[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Initiate tunnel forwarding. */
|
||||
if (options.tun_open != SSH_TUNMODE_NO) {
|
||||
if (client_request_tun_fwd(options.tun_open,
|
||||
if (client_request_tun_fwd(ssh, options.tun_open,
|
||||
options.tun_local, options.tun_remote) == -1) {
|
||||
if (options.exit_on_forward_failure)
|
||||
fatal("Could not request tunnel forwarding.");
|
||||
|
@ -1709,7 +1718,7 @@ check_agent_present(void)
|
|||
}
|
||||
|
||||
static void
|
||||
ssh_session2_setup(int id, int success, void *arg)
|
||||
ssh_session2_setup(struct ssh *ssh, int id, int success, void *arg)
|
||||
{
|
||||
extern char **environ;
|
||||
const char *display;
|
||||
|
@ -1722,15 +1731,15 @@ ssh_session2_setup(int id, int success, void *arg)
|
|||
display = getenv("DISPLAY");
|
||||
if (display == NULL && options.forward_x11)
|
||||
debug("X11 forwarding requested but DISPLAY not set");
|
||||
if (options.forward_x11 && client_x11_get_proto(display,
|
||||
if (options.forward_x11 && client_x11_get_proto(ssh, display,
|
||||
options.xauth_location, options.forward_x11_trusted,
|
||||
options.forward_x11_timeout, &proto, &data) == 0) {
|
||||
/* Request forwarding with authentication spoofing. */
|
||||
debug("Requesting X11 forwarding with authentication "
|
||||
"spoofing.");
|
||||
x11_request_forwarding_with_spoofing(id, display, proto,
|
||||
x11_request_forwarding_with_spoofing(ssh, id, display, proto,
|
||||
data, 1);
|
||||
client_expect_confirm(id, "X11 forwarding", CONFIRM_WARN);
|
||||
client_expect_confirm(ssh, id, "X11 forwarding", CONFIRM_WARN);
|
||||
/* XXX exit_on_forward_failure */
|
||||
interactive = 1;
|
||||
}
|
||||
|
@ -1738,7 +1747,7 @@ ssh_session2_setup(int id, int success, void *arg)
|
|||
check_agent_present();
|
||||
if (options.forward_agent) {
|
||||
debug("Requesting authentication agent forwarding.");
|
||||
channel_request_start(id, "auth-agent-req@openssh.com", 0);
|
||||
channel_request_start(ssh, id, "auth-agent-req@openssh.com", 0);
|
||||
packet_send();
|
||||
}
|
||||
|
||||
|
@ -1746,13 +1755,13 @@ ssh_session2_setup(int id, int success, void *arg)
|
|||
packet_set_interactive(interactive,
|
||||
options.ip_qos_interactive, options.ip_qos_bulk);
|
||||
|
||||
client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"),
|
||||
client_session2_setup(ssh, id, tty_flag, subsystem_flag, getenv("TERM"),
|
||||
NULL, fileno(stdin), &command, environ);
|
||||
}
|
||||
|
||||
/* open new channel for a session */
|
||||
static int
|
||||
ssh_session2_open(void)
|
||||
ssh_session2_open(struct ssh *ssh)
|
||||
{
|
||||
Channel *c;
|
||||
int window, packetmax, in, out, err;
|
||||
|
@ -1782,34 +1791,34 @@ ssh_session2_open(void)
|
|||
window >>= 1;
|
||||
packetmax >>= 1;
|
||||
}
|
||||
c = channel_new(
|
||||
c = channel_new(ssh,
|
||||
"session", SSH_CHANNEL_OPENING, in, out, err,
|
||||
window, packetmax, CHAN_EXTENDED_WRITE,
|
||||
"client-session", /*nonblock*/0);
|
||||
|
||||
debug3("ssh_session2_open: channel_new: %d", c->self);
|
||||
debug3("%s: channel_new: %d", __func__, c->self);
|
||||
|
||||
channel_send_open(c->self);
|
||||
channel_send_open(ssh, c->self);
|
||||
if (!no_shell_flag)
|
||||
channel_register_open_confirm(c->self,
|
||||
channel_register_open_confirm(ssh, c->self,
|
||||
ssh_session2_setup, NULL);
|
||||
|
||||
return c->self;
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_session2(void)
|
||||
ssh_session2(struct ssh *ssh)
|
||||
{
|
||||
int id = -1;
|
||||
|
||||
/* XXX should be pre-session */
|
||||
if (!options.control_persist)
|
||||
ssh_init_stdio_forwarding();
|
||||
ssh_init_forwarding();
|
||||
ssh_init_stdio_forwarding(ssh);
|
||||
ssh_init_forwarding(ssh);
|
||||
|
||||
/* Start listening for multiplex clients */
|
||||
if (!packet_get_mux())
|
||||
muxserver_listen();
|
||||
muxserver_listen(ssh);
|
||||
|
||||
/*
|
||||
* If we are in control persist mode and have a working mux listen
|
||||
|
@ -1837,10 +1846,10 @@ ssh_session2(void)
|
|||
* stdio forward setup that we skipped earlier.
|
||||
*/
|
||||
if (options.control_persist && muxserver_sock == -1)
|
||||
ssh_init_stdio_forwarding();
|
||||
ssh_init_stdio_forwarding(ssh);
|
||||
|
||||
if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
|
||||
id = ssh_session2_open();
|
||||
id = ssh_session2_open(ssh);
|
||||
else {
|
||||
packet_set_interactive(
|
||||
options.control_master == SSHCTL_MASTER_NO,
|
||||
|
@ -1875,7 +1884,7 @@ ssh_session2(void)
|
|||
fork_postauth();
|
||||
}
|
||||
|
||||
return client_loop(tty_flag, tty_flag ?
|
||||
return client_loop(ssh, tty_flag, tty_flag ?
|
||||
options.escape_char : SSH_ESCAPECHAR_NONE, id);
|
||||
}
|
||||
|
||||
|
|
31
ssh_config.5
31
ssh_config.5
|
@ -33,8 +33,8 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: ssh_config.5,v 1.253 2017/07/23 23:37:02 djm Exp $
|
||||
.Dd $Mdocdate: July 23 2017 $
|
||||
.\" $OpenBSD: ssh_config.5,v 1.256 2017/09/21 19:16:53 markus Exp $
|
||||
.Dd $Mdocdate: September 21 2017 $
|
||||
.Dt SSH_CONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -1298,13 +1298,19 @@ accept the tokens described in the
|
|||
section.
|
||||
.It Cm RemoteForward
|
||||
Specifies that a TCP port on the remote machine be forwarded over
|
||||
the secure channel to the specified host and port from the local machine.
|
||||
the secure channel.
|
||||
The remote port may either be fowarded to a specified host and port
|
||||
from the local machine, or may act as a SOCKS 4/5 proxy that allows a remote
|
||||
client to connect to arbitrary destinations from the local machine.
|
||||
The first argument must be
|
||||
.Sm off
|
||||
.Oo Ar bind_address : Oc Ar port
|
||||
.Sm on
|
||||
and the second argument must be
|
||||
.Ar host : Ns Ar hostport .
|
||||
If forwarding to a specific destination then the second argument must be
|
||||
.Ar host : Ns Ar hostport ,
|
||||
otherwise if no destination argument is specified then the remote forwarding
|
||||
will be established as a SOCKS proxy.
|
||||
.Pp
|
||||
IPv6 addresses can be specified by enclosing addresses in square brackets.
|
||||
Multiple forwardings may be specified, and additional
|
||||
forwardings can be given on the command line.
|
||||
|
@ -1458,10 +1464,19 @@ file is poorly maintained or when connections to new hosts are
|
|||
frequently made.
|
||||
This option forces the user to manually
|
||||
add all new hosts.
|
||||
.Pp
|
||||
If this flag is set to
|
||||
.Cm no ,
|
||||
ssh will automatically add new host keys to the
|
||||
user known hosts files.
|
||||
.Dq accept-new
|
||||
then ssh will automatically add new host keys to the user
|
||||
known hosts files, but will not permit connections to hosts with
|
||||
changed host keys.
|
||||
If this flag is set to
|
||||
.Dq no
|
||||
or
|
||||
.Dq off ,
|
||||
ssh will automatically add new host keys to the user known hosts files
|
||||
and allow connections to hosts with changed hostkeys to proceed,
|
||||
subject to some restrictions.
|
||||
If this flag is set to
|
||||
.Cm ask
|
||||
(the default),
|
||||
|
|
3
sshbuf.h
3
sshbuf.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sshbuf.h,v 1.8 2016/11/25 23:22:04 djm Exp $ */
|
||||
/* $OpenBSD: sshbuf.h,v 1.9 2017/09/12 06:32:07 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Damien Miller
|
||||
*
|
||||
|
@ -211,6 +211,7 @@ int sshbuf_get_string_direct(struct sshbuf *buf, const u_char **valp,
|
|||
/* Another variant: "peeks" into the buffer without modifying it */
|
||||
int sshbuf_peek_string_direct(const struct sshbuf *buf, const u_char **valp,
|
||||
size_t *lenp);
|
||||
/* XXX peek_u8 / peek_u32 */
|
||||
|
||||
/*
|
||||
* Functions to extract or store SSH wire encoded bignums and elliptic
|
||||
|
|
66
sshconnect.c
66
sshconnect.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sshconnect.c,v 1.283 2017/07/01 13:50:45 djm Exp $ */
|
||||
/* $OpenBSD: sshconnect.c,v 1.287 2017/09/14 04:32:21 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -104,7 +104,7 @@ expand_proxy_command(const char *proxy_command, const char *user,
|
|||
* a connected fd back to us.
|
||||
*/
|
||||
static int
|
||||
ssh_proxy_fdpass_connect(const char *host, u_short port,
|
||||
ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port,
|
||||
const char *proxy_command)
|
||||
{
|
||||
#ifdef WINDOWS
|
||||
|
@ -185,7 +185,8 @@ ssh_proxy_fdpass_connect(const char *host, u_short port,
|
|||
fatal("Couldn't wait for child: %s", strerror(errno));
|
||||
|
||||
/* Set the connection file descriptors. */
|
||||
packet_set_connection(sock, sock);
|
||||
if (ssh_packet_set_connection(ssh, sock, sock) == NULL)
|
||||
return -1; /* ssh_packet_set_connection logs error */
|
||||
|
||||
return 0;
|
||||
#endif /* !WINDOWS */
|
||||
|
@ -195,7 +196,8 @@ ssh_proxy_fdpass_connect(const char *host, u_short port,
|
|||
* Connect to the given ssh server using a proxy command.
|
||||
*/
|
||||
static int
|
||||
ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
|
||||
ssh_proxy_connect(struct ssh *ssh, const char *host, u_short port,
|
||||
const char *proxy_command)
|
||||
{
|
||||
#ifdef WINDOWS
|
||||
fatal("Proxy connect is not supported in Windows yet");
|
||||
|
@ -266,9 +268,9 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
|
|||
free(command_string);
|
||||
|
||||
/* Set the connection file descriptors. */
|
||||
packet_set_connection(pout[0], pin[1]);
|
||||
if (ssh_packet_set_connection(ssh, pout[0], pin[1]) == NULL)
|
||||
return -1; /* ssh_packet_set_connection logs error */
|
||||
|
||||
/* Indicate OK return */
|
||||
return 0;
|
||||
#endif /* !WINDOWS */
|
||||
}
|
||||
|
@ -425,7 +427,7 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
|
|||
* the daemon.
|
||||
*/
|
||||
static int
|
||||
ssh_connect_direct(const char *host, struct addrinfo *aitop,
|
||||
ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop,
|
||||
struct sockaddr_storage *hostaddr, u_short port, int family,
|
||||
int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv)
|
||||
{
|
||||
|
@ -499,27 +501,31 @@ ssh_connect_direct(const char *host, struct addrinfo *aitop,
|
|||
error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
|
||||
|
||||
/* Set the connection. */
|
||||
packet_set_connection(sock, sock);
|
||||
if (ssh_packet_set_connection(ssh, sock, sock) == NULL)
|
||||
return -1; /* ssh_packet_set_connection logs error */
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ssh_connect(const char *host, struct addrinfo *addrs,
|
||||
ssh_connect(struct ssh *ssh, const char *host, struct addrinfo *addrs,
|
||||
struct sockaddr_storage *hostaddr, u_short port, int family,
|
||||
int connection_attempts, int *timeout_ms, int want_keepalive, int needpriv)
|
||||
{
|
||||
if (options.proxy_command == NULL) {
|
||||
return ssh_connect_direct(host, addrs, hostaddr, port, family,
|
||||
connection_attempts, timeout_ms, want_keepalive, needpriv);
|
||||
return ssh_connect_direct(ssh, host, addrs, hostaddr, port,
|
||||
family, connection_attempts, timeout_ms, want_keepalive,
|
||||
needpriv);
|
||||
} else if (strcmp(options.proxy_command, "-") == 0) {
|
||||
packet_set_connection(STDIN_FILENO, STDOUT_FILENO);
|
||||
return 0; /* Always succeeds */
|
||||
if ((ssh_packet_set_connection(ssh,
|
||||
STDIN_FILENO, STDOUT_FILENO)) == NULL)
|
||||
return -1; /* ssh_packet_set_connection logs error */
|
||||
return 0;
|
||||
} else if (options.proxy_use_fdpass) {
|
||||
return ssh_proxy_fdpass_connect(host, port,
|
||||
return ssh_proxy_fdpass_connect(ssh, host, port,
|
||||
options.proxy_command);
|
||||
}
|
||||
return ssh_proxy_connect(host, port, options.proxy_command);
|
||||
return ssh_proxy_connect(ssh, host, port, options.proxy_command);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -896,7 +902,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
|
|||
if (readonly || want_cert)
|
||||
goto fail;
|
||||
/* The host is new. */
|
||||
if (options.strict_host_key_checking == 1) {
|
||||
if (options.strict_host_key_checking ==
|
||||
SSH_STRICT_HOSTKEY_YES) {
|
||||
/*
|
||||
* User has requested strict host key checking. We
|
||||
* will not add the host key automatically. The only
|
||||
|
@ -905,7 +912,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
|
|||
error("No %s host key is known for %.200s and you "
|
||||
"have requested strict checking.", type, host);
|
||||
goto fail;
|
||||
} else if (options.strict_host_key_checking == 2) {
|
||||
} else if (options.strict_host_key_checking ==
|
||||
SSH_STRICT_HOSTKEY_ASK) {
|
||||
char msg1[1024], msg2[1024];
|
||||
|
||||
if (show_other_keys(host_hostkeys, host_key))
|
||||
|
@ -949,8 +957,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
|
|||
hostkey_trusted = 1; /* user explicitly confirmed */
|
||||
}
|
||||
/*
|
||||
* If not in strict mode, add the key automatically to the
|
||||
* local known_hosts file.
|
||||
* If in "new" or "off" strict mode, add the key automatically
|
||||
* to the local known_hosts file.
|
||||
*/
|
||||
if (options.check_host_ip && ip_status == HOST_NEW) {
|
||||
snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);
|
||||
|
@ -992,7 +1000,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
|
|||
* If strict host key checking is in use, the user will have
|
||||
* to edit the key manually and we can only abort.
|
||||
*/
|
||||
if (options.strict_host_key_checking) {
|
||||
if (options.strict_host_key_checking !=
|
||||
SSH_STRICT_HOSTKEY_OFF) {
|
||||
error("%s host key for %.200s was revoked and you have "
|
||||
"requested strict checking.", type, host);
|
||||
goto fail;
|
||||
|
@ -1045,7 +1054,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
|
|||
* If strict host key checking is in use, the user will have
|
||||
* to edit the key manually and we can only abort.
|
||||
*/
|
||||
if (options.strict_host_key_checking) {
|
||||
if (options.strict_host_key_checking !=
|
||||
SSH_STRICT_HOSTKEY_OFF) {
|
||||
error("%s host key for %.200s has changed and you have "
|
||||
"requested strict checking.", type, host);
|
||||
goto fail;
|
||||
|
@ -1132,15 +1142,17 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
|
|||
"\nMatching host key in %s:%lu",
|
||||
host_found->file, host_found->line);
|
||||
}
|
||||
if (options.strict_host_key_checking == 1) {
|
||||
logit("%s", msg);
|
||||
error("Exiting, you have requested strict checking.");
|
||||
goto fail;
|
||||
} else if (options.strict_host_key_checking == 2) {
|
||||
if (options.strict_host_key_checking ==
|
||||
SSH_STRICT_HOSTKEY_ASK) {
|
||||
strlcat(msg, "\nAre you sure you want "
|
||||
"to continue connecting (yes/no)? ", sizeof(msg));
|
||||
if (!confirm(msg))
|
||||
goto fail;
|
||||
} else if (options.strict_host_key_checking !=
|
||||
SSH_STRICT_HOSTKEY_OFF) {
|
||||
logit("%s", msg);
|
||||
error("Exiting, you have requested strict checking.");
|
||||
goto fail;
|
||||
} else {
|
||||
logit("%s", msg);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sshconnect.h,v 1.30 2017/05/30 08:52:19 markus Exp $ */
|
||||
/* $OpenBSD: sshconnect.h,v 1.31 2017/09/12 06:32:07 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
|
@ -32,8 +32,10 @@ struct Sensitive {
|
|||
};
|
||||
|
||||
struct addrinfo;
|
||||
int ssh_connect(const char *, struct addrinfo *, struct sockaddr_storage *,
|
||||
u_short, int, int, int *, int, int);
|
||||
struct ssh;
|
||||
|
||||
int ssh_connect(struct ssh *, const char *, struct addrinfo *,
|
||||
struct sockaddr_storage *, u_short, int, int, int *, int, int);
|
||||
void ssh_kill_proxy_command(void);
|
||||
|
||||
void ssh_login(Sensitive *, const char *, struct sockaddr *, u_short,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sshconnect2.c,v 1.265 2017/08/11 04:47:12 djm Exp $ */
|
||||
/* $OpenBSD: sshconnect2.c,v 1.266 2017/08/27 00:38:41 dtucker Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2008 Damien Miller. All rights reserved.
|
||||
|
@ -900,7 +900,7 @@ int
|
|||
userauth_passwd(Authctxt *authctxt)
|
||||
{
|
||||
static int attempt = 0;
|
||||
char prompt[150];
|
||||
char prompt[256];
|
||||
char *password;
|
||||
const char *host = options.host_key_alias ? options.host_key_alias :
|
||||
authctxt->host;
|
||||
|
@ -940,7 +940,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh)
|
|||
{
|
||||
Authctxt *authctxt = ssh->authctxt;
|
||||
char *info, *lang, *password = NULL, *retype = NULL;
|
||||
char prompt[150];
|
||||
char prompt[256];
|
||||
const char *host;
|
||||
|
||||
debug2("input_userauth_passwd_changereq");
|
||||
|
|
19
sshd.c
19
sshd.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sshd.c,v 1.491 2017/07/01 13:50:45 djm Exp $ */
|
||||
/* $OpenBSD: sshd.c,v 1.492 2017/09/12 06:32:07 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -1714,9 +1714,6 @@ main(int ac, char **av)
|
|||
"enabled authentication methods");
|
||||
}
|
||||
|
||||
/* set default channel AF */
|
||||
channel_set_af(options.address_family);
|
||||
|
||||
/* Check that there are no remaining arguments. */
|
||||
if (optind < ac) {
|
||||
fprintf(stderr, "Extra argument %s.\n", av[optind]);
|
||||
|
@ -2075,8 +2072,14 @@ main(int ac, char **av)
|
|||
packet_set_connection(sock_in, sock_out);
|
||||
packet_set_server();
|
||||
ssh = active_state; /* XXX */
|
||||
|
||||
check_ip_options(ssh);
|
||||
|
||||
/* Prepare the channels layer */
|
||||
channel_init_channels(ssh);
|
||||
channel_set_af(ssh, options.address_family);
|
||||
process_permitopen(ssh, &options);
|
||||
|
||||
/* Set SO_KEEPALIVE if requested. */
|
||||
if (options.tcp_keep_alive && packet_connection_is_on_socket() &&
|
||||
setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0)
|
||||
|
@ -2200,10 +2203,10 @@ main(int ac, char **av)
|
|||
options.client_alive_count_max);
|
||||
|
||||
/* Try to send all our hostkeys to the client */
|
||||
notify_hostkeys(active_state);
|
||||
notify_hostkeys(ssh);
|
||||
|
||||
/* Start session. */
|
||||
do_authenticated(authctxt);
|
||||
do_authenticated(ssh, authctxt);
|
||||
|
||||
/* The connection has been terminated. */
|
||||
packet_get_bytes(&ibytes, &obytes);
|
||||
|
@ -2331,8 +2334,10 @@ do_ssh2_kex(void)
|
|||
void
|
||||
cleanup_exit(int i)
|
||||
{
|
||||
struct ssh *ssh = active_state; /* XXX */
|
||||
|
||||
if (the_authctxt) {
|
||||
do_cleanup(the_authctxt);
|
||||
do_cleanup(ssh, the_authctxt);
|
||||
if (use_privsep && privsep_is_preauth &&
|
||||
pmonitor != NULL && pmonitor->m_pid > 1) {
|
||||
debug("Killing privsep child %d", pmonitor->m_pid);
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $OpenBSD: sshd_config.5,v 1.250 2017/07/23 23:37:02 djm Exp $
|
||||
.Dd $Mdocdate: July 23 2017 $
|
||||
.\" $OpenBSD: sshd_config.5,v 1.253 2017/09/27 06:45:53 jmc Exp $
|
||||
.Dd $Mdocdate: September 27 2017 $
|
||||
.Dt SSHD_CONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -223,6 +223,18 @@ requires successful authentication using two different public keys.
|
|||
.Pp
|
||||
Note that each authentication method listed should also be explicitly enabled
|
||||
in the configuration.
|
||||
.Pp
|
||||
The available authentication methods are:
|
||||
.Qq gssapi-with-mic ,
|
||||
.Qq hostbased ,
|
||||
.Qq keyboard-interactive ,
|
||||
.Qq none
|
||||
(used for access to password-less accounts when
|
||||
.Cm PermitEmptyPassword
|
||||
is enabled),
|
||||
.Qq password
|
||||
and
|
||||
.Qq publickey .
|
||||
.It Cm AuthorizedKeysCommand
|
||||
Specifies a program to be used to look up the user's public keys.
|
||||
The program must be owned by root, not writable by group or others and
|
||||
|
@ -563,11 +575,13 @@ TCP and StreamLocal.
|
|||
This option overrides all other forwarding-related options and may
|
||||
simplify restricted configurations.
|
||||
.It Cm ExposeAuthInfo
|
||||
Enables writing a file containing a list of authentication methods and
|
||||
Writes a temporary file containing a list of authentication methods and
|
||||
public credentials (e.g. keys) used to authenticate the user.
|
||||
The location of the file is exposed to the user session through the
|
||||
.Ev SSH_USER_AUTH
|
||||
environment variable.
|
||||
The default is
|
||||
.Cm no .
|
||||
.It Cm FingerprintHash
|
||||
Specifies the hash algorithm used when logging key fingerprints.
|
||||
Valid options are:
|
||||
|
|
4
ssherr.c
4
ssherr.c
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssherr.c,v 1.6 2017/05/07 23:15:59 djm Exp $ */
|
||||
/* $OpenBSD: ssherr.c,v 1.7 2017/09/12 06:32:08 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Damien Miller
|
||||
*
|
||||
|
@ -137,6 +137,8 @@ ssh_err(int n)
|
|||
return "Protocol error";
|
||||
case SSH_ERR_KEY_LENGTH:
|
||||
return "Invalid key length";
|
||||
case SSH_ERR_NUMBER_TOO_LARGE:
|
||||
return "number is too large";
|
||||
default:
|
||||
return "unknown error";
|
||||
}
|
||||
|
|
3
ssherr.h
3
ssherr.h
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: ssherr.h,v 1.4 2017/05/07 23:15:59 djm Exp $ */
|
||||
/* $OpenBSD: ssherr.h,v 1.5 2017/09/12 06:32:08 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2011 Damien Miller
|
||||
*
|
||||
|
@ -78,6 +78,7 @@
|
|||
#define SSH_ERR_CONN_CORRUPT -54
|
||||
#define SSH_ERR_PROTOCOL_ERROR -55
|
||||
#define SSH_ERR_KEY_LENGTH -56
|
||||
#define SSH_ERR_NUMBER_TOO_LARGE -57
|
||||
|
||||
/* Translate a numeric error code to a human-readable error string */
|
||||
const char *ssh_err(int n);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* $OpenBSD: version.h,v 1.79 2017/03/20 01:18:59 djm Exp $ */
|
||||
/* $OpenBSD: version.h,v 1.80 2017/09/30 22:26:33 djm Exp $ */
|
||||
|
||||
#define SSH_VERSION "OpenSSH_7.5"
|
||||
#define SSH_VERSION "OpenSSH_7.6"
|
||||
|
||||
#define SSH_PORTABLE "p1"
|
||||
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE
|
||||
|
|
Loading…
Reference in New Issue