mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-08 08:58:00 +00:00
e9e6c03c6e
With the new --open-unconditional-agent-socket option, every time Uppity receives an SSH connection, it will immediately open a Unix- domain socket and attempt to do agent forwarding on it, in the sense that any connection to that socket will be turned into an "auth-agent@openssh.com" CHANNEL_OPEN request on whichever SSH connection it was associated with. That connection-global socket is independent of any that are created as part of setting up a session channel. The pathname of the socket file is written to the server's event log (there being no other sensible place to send it). The aim is that this allows me to test the behaviour of an SSH client if the server tries to open an agent-forwarding channel outside the usual context. In particular, it allows me to test the change I just made in the previous commit, that if you enable agent forwarding in the client configuration, then auth-agent channels opened by the server are accepted even if no session channel opened by the client has sent an auth-agent-req. More importantly, it allows me to check that I _haven't_ accidentally arranged that those channels are accepted even when agent forwarding is _not_ permitted by the client configuration! Implementation details: the agent forwarding socket was previously implemented as part of the internal sesschan structure. I've moved it out into a little sub-struct of its own which can be created independently of a sesschan.
144 lines
5.6 KiB
C
144 lines
5.6 KiB
C
typedef struct AuthPolicy AuthPolicy;
|
|
|
|
struct SshServerConfig {
|
|
const char *application_name;
|
|
const char *session_starting_dir;
|
|
|
|
RSAKey *rsa_kex_key;
|
|
|
|
/*
|
|
* In all of these ptrlens, setting the 'ptr' member to NULL means
|
|
* that we're not overriding the default configuration.
|
|
*/
|
|
ptrlen banner; /* default here is 'no banner' */
|
|
ptrlen kex_override[NKEXLIST];
|
|
|
|
bool exit_signal_numeric; /* mimic an old server bug */
|
|
|
|
unsigned long ssh1_cipher_mask;
|
|
bool ssh1_allow_compression;
|
|
bool bare_connection;
|
|
|
|
bool stunt_pretend_to_accept_any_pubkey;
|
|
bool stunt_open_unconditional_agent_socket;
|
|
};
|
|
|
|
Plug *ssh_server_plug(
|
|
Conf *conf, const SshServerConfig *ssc,
|
|
ssh_key *const *hostkeys, int nhostkeys,
|
|
RSAKey *hostkey1, AuthPolicy *authpolicy, LogPolicy *logpolicy,
|
|
const SftpServerVtable *sftpserver_vt);
|
|
void ssh_server_start(Plug *plug, Socket *socket);
|
|
|
|
void server_instance_terminated(LogPolicy *logpolicy);
|
|
void platform_logevent(const char *msg);
|
|
|
|
#define AUTHMETHODS(X) \
|
|
X(NONE) \
|
|
X(PASSWORD) \
|
|
X(PUBLICKEY) \
|
|
X(KBDINT) \
|
|
X(TIS) \
|
|
X(CRYPTOCARD) \
|
|
/* end of list */
|
|
|
|
#define AUTHMETHOD_BIT_INDEX(name) AUTHMETHOD_BIT_INDEX_##name,
|
|
enum { AUTHMETHODS(AUTHMETHOD_BIT_INDEX) AUTHMETHOD_BIT_INDEX_dummy };
|
|
#define AUTHMETHOD_BIT_VALUE(name) \
|
|
AUTHMETHOD_##name = 1 << AUTHMETHOD_BIT_INDEX_##name,
|
|
enum { AUTHMETHODS(AUTHMETHOD_BIT_VALUE) AUTHMETHOD_BIT_VALUE_dummy };
|
|
|
|
typedef struct AuthKbdInt AuthKbdInt;
|
|
typedef struct AuthKbdIntPrompt AuthKbdIntPrompt;
|
|
struct AuthKbdInt {
|
|
char *title, *instruction; /* both need freeing */
|
|
int nprompts;
|
|
AuthKbdIntPrompt *prompts; /* the array itself needs freeing */
|
|
};
|
|
struct AuthKbdIntPrompt {
|
|
char *prompt; /* needs freeing */
|
|
bool echo;
|
|
};
|
|
|
|
unsigned auth_methods(AuthPolicy *);
|
|
bool auth_none(AuthPolicy *, ptrlen username);
|
|
|
|
int auth_password(AuthPolicy *, ptrlen username, ptrlen password,
|
|
ptrlen *opt_new_password);
|
|
/* auth_password returns 1 for 'accepted', 0 for 'rejected', and 2 for
|
|
* 'ok but now you need to change your password' */
|
|
|
|
bool auth_publickey(AuthPolicy *, ptrlen username, ptrlen public_blob);
|
|
/* auth_publickey_ssh1 must return the whole public key given the modulus,
|
|
* because the SSH-1 client never transmits the exponent over the wire.
|
|
* The key remains owned by the AuthPolicy. */
|
|
|
|
AuthKbdInt *auth_kbdint_prompts(AuthPolicy *, ptrlen username);
|
|
/* auth_kbdint_prompts returns NULL to trigger auth failure */
|
|
int auth_kbdint_responses(AuthPolicy *, const ptrlen *responses);
|
|
/* auth_kbdint_responses returns >0 for success, <0 for failure, and 0
|
|
* to indicate that we haven't decided yet and further prompts are
|
|
* coming */
|
|
|
|
/* The very similar SSH-1 TIS and CryptoCard methods are combined into
|
|
* a single API for AuthPolicy, which takes a method argument */
|
|
char *auth_ssh1int_challenge(AuthPolicy *, unsigned method, ptrlen username);
|
|
bool auth_ssh1int_response(AuthPolicy *, ptrlen response);
|
|
|
|
RSAKey *auth_publickey_ssh1(
|
|
AuthPolicy *ap, ptrlen username, mp_int *rsa_modulus);
|
|
/* auth_successful returns false if further authentication is needed */
|
|
bool auth_successful(AuthPolicy *, ptrlen username, unsigned method);
|
|
|
|
PacketProtocolLayer *ssh2_userauth_server_new(
|
|
PacketProtocolLayer *successor_layer, AuthPolicy *authpolicy,
|
|
const SshServerConfig *ssc);
|
|
void ssh2_userauth_server_set_transport_layer(
|
|
PacketProtocolLayer *userauth, PacketProtocolLayer *transport);
|
|
|
|
void ssh2connection_server_configure(
|
|
PacketProtocolLayer *ppl, const SftpServerVtable *sftpserver_vt,
|
|
const SshServerConfig *ssc);
|
|
void ssh1connection_server_configure(
|
|
PacketProtocolLayer *ppl, const SshServerConfig *ssc);
|
|
|
|
PacketProtocolLayer *ssh1_login_server_new(
|
|
PacketProtocolLayer *successor_layer, RSAKey *hostkey,
|
|
AuthPolicy *authpolicy, const SshServerConfig *ssc);
|
|
|
|
Channel *sesschan_new(SshChannel *c, LogContext *logctx,
|
|
const SftpServerVtable *sftpserver_vt,
|
|
const SshServerConfig *ssc);
|
|
|
|
Backend *pty_backend_create(
|
|
Seat *seat, LogContext *logctx, Conf *conf, char **argv, const char *cmd,
|
|
struct ssh_ttymodes ttymodes, bool pipes_instead_of_pty, const char *dir,
|
|
const char *const *env_vars_to_unset);
|
|
int pty_backend_exit_signum(Backend *be);
|
|
ptrlen pty_backend_exit_signame(Backend *be, char **aux_msg);
|
|
|
|
/*
|
|
* Establish a listening X server. Return value is the _number_ of
|
|
* Sockets that it established pointing at the given Plug. (0
|
|
* indicates complete failure.) The socket pointers themselves are
|
|
* written into sockets[], up to a possible total of MAX_X11_SOCKETS.
|
|
*
|
|
* The supplied Conf has necessary environment variables written into
|
|
* it. (And is also used to open the port listeners, though that
|
|
* shouldn't affect anything.)
|
|
*/
|
|
#define MAX_X11_SOCKETS 2
|
|
int platform_make_x11_server(Plug *plug, const char *progname, int mindisp,
|
|
const char *screen_number_suffix,
|
|
ptrlen authproto, ptrlen authdata,
|
|
Socket **sockets, Conf *conf);
|
|
|
|
Conf *make_ssh_server_conf(void);
|
|
|
|
/* Provided by Unix front end programs to uxsftpserver.c */
|
|
void make_unix_sftp_filehandle_key(void *data, size_t size);
|
|
|
|
typedef struct agentfwd agentfwd;
|
|
agentfwd *agentfwd_new(ConnectionLayer *cl, char **socketname_out);
|
|
void agentfwd_free(agentfwd *agent);
|