#define logevent(s) logevent(ssh->frontend, s)
/* logevent, only printf-formatted. */
-static void logeventf(Ssh ssh, char *fmt, ...)
+static void logeventf(Ssh ssh, const char *fmt, ...)
{
va_list ap;
char *buf;
if (ssh->cipher)
ssh->cipher->decrypt(ssh->v1_cipher_ctx, ssh->pktin.data, st->biglen);
- st->realcrc = crc32(ssh->pktin.data, st->biglen - 4);
+ st->realcrc = crc32_compute(ssh->pktin.data, st->biglen - 4);
st->gotcrc = GET_32BIT(ssh->pktin.data + st->biglen - 4);
if (st->gotcrc != st->realcrc) {
bombout(("Incorrect CRC received on packet"));
if (ssh->v1_compressing) {
unsigned char *decompblk;
int decomplen;
- zlib_decompress_block(ssh->sc_comp_ctx,
- ssh->pktin.body - 1, ssh->pktin.length + 1,
- &decompblk, &decomplen);
+ if (!zlib_decompress_block(ssh->sc_comp_ctx,
+ ssh->pktin.body - 1, ssh->pktin.length + 1,
+ &decompblk, &decomplen)) {
+ bombout(("Zlib decompression encountered invalid data"));
+ crStop(0);
+ }
if (ssh->pktin.maxlen < st->pad + decomplen) {
ssh->pktin.maxlen = st->pad + decomplen;
for (i = 0; i < pad; i++)
ssh->pktout.data[i + 4] = random_byte();
- crc = crc32(ssh->pktout.data + 4, biglen - 4);
+ crc = crc32_compute(ssh->pktout.data + 4, biglen - 4);
PUT_32BIT(ssh->pktout.data + biglen, crc);
PUT_32BIT(ssh->pktout.data, len);
(ssh->cfg.sshbug_ignore1 == AUTO &&
(!strcmp(imp, "1.2.18") || !strcmp(imp, "1.2.19") ||
!strcmp(imp, "1.2.20") || !strcmp(imp, "1.2.21") ||
- !strcmp(imp, "1.2.22") || !strcmp(imp, "Cisco-1.25")))) {
+ !strcmp(imp, "1.2.22") || !strcmp(imp, "Cisco-1.25") ||
+ !strcmp(imp, "OSU_1.4alpha3")))) {
/*
* These versions don't support SSH1_MSG_IGNORE, so we have
* to use a different defence against password length
if (ssh->cfg.sshbug_plainpw1 == FORCE_ON ||
(ssh->cfg.sshbug_plainpw1 == AUTO &&
- (!strcmp(imp, "Cisco-1.25")))) {
+ (!strcmp(imp, "Cisco-1.25") || !strcmp(imp, "OSU_1.4alpha3")))) {
/*
* These versions need a plain password sent; they can't
* handle having a null and a random length of data after
if (ssh->cfg.sshbug_hmac2 == FORCE_ON ||
(ssh->cfg.sshbug_hmac2 == AUTO &&
+ !wc_match("* VShell", imp) &&
(wc_match("2.1.0*", imp) || wc_match("2.0.*", imp) ||
wc_match("2.2.0*", imp) || wc_match("2.3.0*", imp) ||
wc_match("2.1 *", imp)))) {
if (ssh->cfg.sshbug_derivekey2 == FORCE_ON ||
(ssh->cfg.sshbug_derivekey2 == AUTO &&
+ !wc_match("* VShell", imp) &&
(wc_match("2.0.0*", imp) || wc_match("2.0.10*", imp) ))) {
/*
* These versions have the key-derivation bug (failing to
}
}
-static int ssh_closing(Plug plug, char *error_msg, int error_code,
+static int ssh_closing(Plug plug, const char *error_msg, int error_code,
int calling_back)
{
Ssh ssh = (Ssh) plug;
if (error_msg) {
/* A socket error has occurred. */
logevent(error_msg);
- connection_fatal(ssh->frontend, error_msg);
+ connection_fatal(ssh->frontend, "%s", error_msg);
} else {
/* Otherwise, the remote side closed the connection normally. */
}
* Also places the canonical host name into `realhost'. It must be
* freed by the caller.
*/
-static char *connect_to_host(Ssh ssh, char *host, int port,
- char **realhost, int nodelay)
+static const char *connect_to_host(Ssh ssh, char *host, int port,
+ char **realhost, int nodelay)
{
static const struct plug_function_table fn_table = {
ssh_closing,
};
SockAddr addr;
- char *err;
+ const char *err;
ssh->savedhost = snewn(1 + strlen(host), char);
if (!ssh->savedhost)
*/
logeventf(ssh, "Looking up host \"%s\"", host);
addr = name_lookup(host, port, realhost, &ssh->cfg);
- if ((err = sk_addr_error(addr)) != NULL)
+ if ((err = sk_addr_error(addr)) != NULL) {
+ sk_addr_free(addr);
return err;
+ }
/*
* Open socket.
return 0;
}
-void ssh_agent_callback(void *sshv, void *reply, int replylen)
+static void ssh_agent_callback(void *sshv, void *reply, int replylen)
{
Ssh ssh = (Ssh) sshv;
do_ssh2_authconn(ssh, NULL, -1, 0);
}
-void ssh_agentf_callback(void *cv, void *reply, int replylen)
+static void ssh_agentf_callback(void *cv, void *reply, int replylen)
{
struct ssh_channel *c = (struct ssh_channel *)cv;
Ssh ssh = c->ssh;
/* Load the public half of ssh->cfg.keyfile so we notice if it's in Pageant */
if (!filename_is_null(ssh->cfg.keyfile)) {
if (!rsakey_pubblob(&ssh->cfg.keyfile,
- &s->publickey_blob, &s->publickey_bloblen))
+ &s->publickey_blob, &s->publickey_bloblen, NULL))
s->publickey_blob = NULL;
} else
s->publickey_blob = NULL;
s->tried_publickey = 1;
{
- int ret = loadrsakey(&ssh->cfg.keyfile, &s->key, s->password);
+ const char *error = NULL;
+ int ret = loadrsakey(&ssh->cfg.keyfile, &s->key, s->password,
+ &error);
if (ret == 0) {
c_write_str(ssh, "Couldn't load private key from ");
c_write_str(ssh, filename_to_str(&ssh->cfg.keyfile));
- c_write_str(ssh, ".\r\n");
+ c_write_str(ssh, " (");
+ c_write_str(ssh, error);
+ c_write_str(ssh, ").\r\n");
continue; /* go and try password */
}
if (ret == -1) {
} else {
while (*ssh->portfwd_strptr) ssh->portfwd_strptr++;
dport = dserv = -1;
+ ssh->portfwd_strptr++; /* eat the NUL and move to next one */
}
sport = atoi(sports);
sserv = 0;
struct ssh_rportfwd pf;
int hostsize, port;
char host[256], buf[1024];
- char *p, *h, *e;
+ char *p, *h;
+ const char *e;
c = snew(struct ssh_channel);
c->ssh = ssh;
if (keytype == SSH_KEYTYPE_SSH2) {
s->publickey_blob =
ssh2_userkey_loadpub(&ssh->cfg.keyfile, NULL,
- &s->publickey_bloblen);
+ &s->publickey_bloblen, NULL);
} else {
char *msgbuf;
logeventf(ssh, "Unable to use this key file (%s)",
pub_blob =
(unsigned char *)ssh2_userkey_loadpub(&ssh->cfg.keyfile,
&algorithm,
- &pub_blob_len);
+ &pub_blob_len,
+ NULL);
if (pub_blob) {
ssh2_pkt_init(ssh, SSH2_MSG_USERAUTH_REQUEST);
ssh2_pkt_addstring(ssh, s->username);
* We have our passphrase. Now try the actual authentication.
*/
struct ssh2_userkey *key;
+ const char *error = NULL;
- key = ssh2_load_userkey(&ssh->cfg.keyfile, s->password);
+ key = ssh2_load_userkey(&ssh->cfg.keyfile, s->password,
+ &error);
if (key == SSH2_WRONG_PASSPHRASE || key == NULL) {
if (key == SSH2_WRONG_PASSPHRASE) {
c_write_str(ssh, "Wrong passphrase\r\n");
s->tried_pubkey_config = FALSE;
} else {
- c_write_str(ssh, "Unable to load private key\r\n");
+ c_write_str(ssh, "Unable to load private key (");
+ c_write_str(ssh, error);
+ c_write_str(ssh, ")\r\n");
s->tried_pubkey_config = TRUE;
}
/* Send a spurious AUTH_NONE to return to the top. */
} else {
while (*ssh->portfwd_strptr) ssh->portfwd_strptr++;
dport = dserv = -1;
+ ssh->portfwd_strptr++; /* eat the NUL and move to next one */
}
sport = atoi(sports);
sserv = 0;
if (realpf == NULL) {
error = "Remote port is not recognised";
} else {
- char *e = pfd_newconnect(&c->u.pfd.s, realpf->dhost,
- realpf->dport, c, &ssh->cfg);
+ const char *e = pfd_newconnect(&c->u.pfd.s,
+ realpf->dhost,
+ realpf->dport, c,
+ &ssh->cfg);
logeventf(ssh, "Received remote port open request"
" for %s:%d", realpf->dhost, realpf->dport);
if (e != NULL) {
*
* Returns an error message, or NULL on success.
*/
-static char *ssh_init(void *frontend_handle, void **backend_handle,
- Config *cfg,
- char *host, int port, char **realhost, int nodelay)
+static const char *ssh_init(void *frontend_handle, void **backend_handle,
+ Config *cfg,
+ char *host, int port, char **realhost, int nodelay)
{
- char *p;
+ const char *p;
Ssh ssh;
ssh = snew(struct ssh_tag);