ifeq "$(RELEASE)" "" set Ndate $(!builddate)
ifneq "$(Ndate)" "" in . do echo $(Ndate) | perl -pe 's/(....)(..)(..)/$$1-$$2-$$3/' > date
ifneq "$(Ndate)" "" read Date date
-set Epoch 15746 # update this at every release
+set Epoch 15860 # update this at every release
ifneq "$(Ndate)" "" in . do echo $(Ndate) | perl -ne 'use Time::Local; /(....)(..)(..)/ and print timegm(0,0,0,$$3,$$2-1,$$1) / 86400 - $(Epoch)' > days
ifneq "$(Ndate)" "" read Days days
\H{pgpkeys-pubkey} Public keys
-We maintain a set of three keys, stored with different levels of
-security due to being used in different ways. See \k{pgpkeys-security}
-below for details.
+We maintain multiple keys, stored with different levels of security
+due to being used in different ways. See \k{pgpkeys-security} below
+for details.
-The three keys we provide are:
+The keys we provide are:
\dt Snapshot Key
\dd Used to sign manually released versions of PuTTY.
+\dt Secure Contact Key
+
+\dd An encryption-capable key suitable for people to send confidential
+messages to the PuTTY team, e.g. reports of vulnerabilities.
+
\dt Master Key
-\dd Used to tie the other two keys into the GPG web of trust. The
-Master Key signs the other two keys, and other GPG users have signed
+\dd Used to tie all the above keys into the GPG web of trust. The
+Master Key signs all the other keys, and other GPG users have signed
it in turn.
-The current issue of those three keys are available for download from
-the PuTTY website, and are also available on PGP keyservers using the
-key IDs listed below.
+The current issue of those keys are available for download from the
+PuTTY website, and are also available on PGP keyservers using the key
+IDs listed below.
\dt \W{http://www.chiark.greenend.org.uk/~sgtatham/putty/keys/master-2015.asc}{\s{Master Key}}
\cw{2048R/9DFE2648B43434E4}). Fingerprint:
\cw{0054\_DDAA\_8ADA\_15D2\_768A\_\_6DE7\_9DFE\_2648\_B434\_34E4}
+\dt \W{http://www.chiark.greenend.org.uk/~sgtatham/putty/keys/contact-2016.asc}{\s{Secure Contact Key}}
+
+\dd RSA, 2048-bit. Main key ID: \cw{2048R/8A0AF00B} (long version:
+\cw{2048R/C4FCAAD08A0AF00B}). Encryption subkey ID:
+\cw{2048R/50C2CF5C} (long version: \cw{2048R/9EB39CC150C2CF5C}.
+Fingerprint:
+\cw{8A26\_250E\_763F\_E359\_75F3\_\_118F\_C4FC\_AAD0\_8A0A\_F00B}
+
\dt \W{http://www.chiark.greenend.org.uk/~sgtatham/putty/keys/snapshot-2015.asc}{\s{Snapshot Key}}
\dd RSA, 2048-bit. Key ID: \cw{2048R/D15F7E8A} (long version:
local machines. So an attacker wanting to steal it would have to also
steal the passphrase.
+\S{pgpkeys-contact} The Secure Contact Key
+
+The Secure Contact Key is stored with a similar level of security to
+the Release Key: it is stored with a passphrase, and no automated
+script has access to it.
+
\S{pgpkeys-master} The Master Keys
The Master Key signs almost nothing. Its purpose is to bind the other
\H{pgpkeys-rollover} Key rollover
-Our current three keys were generated in September 2015. Prior to
-that, we had a much older set of keys generated in 2000. For each of
-the three key types above, we provided both an RSA key \e{and} a DSA
-key (because at the time we generated them, RSA was not in practice
-available to everyone, due to export restrictions).
+Our current keys were generated in September 2015, except for the
+Secure Contact Key which was generated in February 2016 (we didn't
+think of it until later).
+
+Prior to that, we had a much older set of keys generated in 2000. For
+each of the key types above (other than the Secure Contact Key), we
+provided both an RSA key \e{and} a DSA key (because at the time we
+generated them, RSA was not in practice available to everyone, due to
+export restrictions).
The new Master Key is signed with both of the old ones, to show that
it really is owned by the same people and not substituted by an
\c Z:\sysosd>plink
\c Plink: command-line connection utility
-\c Release 0.66
+\c Release 0.67
\c Usage: plink [options] [user@]host [command]
\c ("host" can also be a PuTTY saved session name)
\c Options:
\c -N don't start a shell/command (SSH-2 only)
\c -nc host:port
\c open tunnel in place of session (SSH-2 only)
-\c -shareexists
-\c test whether a connection-sharing upstream exists
+\c -sshlog file
+\c -sshrawlog file
+\c log protocol details to a file
Once this works, you are ready to use Plink.
\c Z:\owendadmin>pscp
\c PuTTY Secure Copy client
-\c Release 0.66
+\c Release 0.67
\c Usage: pscp [options] [user@]host:source target
\c pscp [options] source [source...] [user@]host:target
\c pscp [options] -ls [user@]host:filespec
\c -unsafe allow server-side wildcards (DANGEROUS)
\c -sftp force use of SFTP protocol
\c -scp force use of SCP protocol
+\c -sshlog file
+\c -sshrawlog file
+\c log protocol details to a file
(PSCP's interface is much like the Unix \c{scp} command, if you're
familiar with that.)
(cp)[0] = (unsigned char)((value) >> 8), \
(cp)[1] = (unsigned char)(value) )
+/* Replace NULL with the empty string, permitting an idiom in which we
+ * get a string (pointer,length) pair that might be NULL,0 and can
+ * then safely say things like printf("%.*s", length, NULLTOEMPTY(ptr)) */
+#define NULLTOEMPTY(s) ((s)?(s):"")
+
#endif
{
char sizestr[40];
- if (sscanf(act->buf, "%lo %s %n", &act->permissions,
+ if (sscanf(act->buf, "%lo %39s %n", &act->permissions,
sizestr, &i) != 2)
bump("Protocol error: Illegal file descriptor format");
act->size = uint64_from_decimal(sizestr);
ssh_pkt_getstring(pktin, &host, &hostsize);
port = ssh_pkt_getuint32(pktin);
- pf.dhost = dupprintf("%.*s", hostsize, host);
+ pf.dhost = dupprintf("%.*s", hostsize, NULLTOEMPTY(host));
pf.dport = port;
pfp = find234(ssh->rportfwds, &pf, NULL);
int msglen;
ssh_pkt_getstring(pktin, &msg, &msglen);
- logeventf(ssh, "Remote debug message: %.*s", msglen, msg);
+ logeventf(ssh, "Remote debug message: %.*s", msglen, NULLTOEMPTY(msg));
}
static void ssh1_msg_disconnect(Ssh ssh, struct Packet *pktin)
int msglen;
ssh_pkt_getstring(pktin, &msg, &msglen);
- bombout(("Server sent disconnect message:\n\"%.*s\"", msglen, msg));
+ bombout(("Server sent disconnect message:\n\"%.*s\"",
+ msglen, NULLTOEMPTY(msg)));
}
static void ssh_msg_ignore(Ssh ssh, struct Packet *pktin)
reason_code = 0; /* ensure reasons[reason_code] in range */
ssh_pkt_getstring(pktin, &reason_string, &reason_length);
logeventf(ssh, "Forwarded connection refused by server: %s [%.*s]",
- reasons[reason_code], reason_length, reason_string);
+ reasons[reason_code], reason_length,
+ NULLTOEMPTY(reason_string));
pfd_close(c->u.pfd.pf);
} else if (c->type == CHAN_ZOMBIE) {
char *addrstr;
ssh_pkt_getstring(pktin, &peeraddr, &peeraddrlen);
- addrstr = snewn(peeraddrlen+1, char);
- memcpy(addrstr, peeraddr, peeraddrlen);
- addrstr[peeraddrlen] = '\0';
+ addrstr = dupprintf("%.*s", peeraddrlen, NULLTOEMPTY(peeraddr));
peerport = ssh_pkt_getuint32(pktin);
logeventf(ssh, "Received X11 connect request from %s:%d",
char *shost;
int shostlen;
ssh_pkt_getstring(pktin, &shost, &shostlen);/* skip address */
- pf.shost = dupprintf("%.*s", shostlen, shost);
+ pf.shost = dupprintf("%.*s", shostlen, NULLTOEMPTY(shost));
pf.sport = ssh_pkt_getuint32(pktin);
ssh_pkt_getstring(pktin, &peeraddr, &peeraddrlen);
peerport = ssh_pkt_getuint32(pktin);
realpf = find234(ssh->rportfwds, &pf, NULL);
logeventf(ssh, "Received remote port %s:%d open request "
- "from %s:%d", pf.shost, pf.sport, peeraddr, peerport);
+ "from %.*s:%d", pf.shost, pf.sport,
+ peeraddrlen, NULLTOEMPTY(peeraddr), peerport);
sfree(pf.shost);
if (realpf == NULL) {
s->cur_prompt->to_server = TRUE;
s->cur_prompt->name = dupstr("New SSH password");
s->cur_prompt->instruction =
- dupprintf("%.*s", prompt_len, prompt);
+ dupprintf("%.*s", prompt_len, NULLTOEMPTY(prompt));
s->cur_prompt->instr_reqd = TRUE;
/*
* There's no explicit requirement in the protocol
logevent(buf);
sfree(buf);
buf = dupprintf("Disconnection message text: %.*s",
- msglen, msg);
+ msglen, NULLTOEMPTY(msg));
logevent(buf);
bombout(("Server sent disconnect message\ntype %d (%s):\n\"%.*s\"",
reason,
(reason > 0 && reason < lenof(ssh2_disconnect_reasons)) ?
ssh2_disconnect_reasons[reason] : "unknown",
- msglen, msg));
+ msglen, NULLTOEMPTY(msg)));
sfree(buf);
}
ssh2_pkt_getbool(pktin);
ssh_pkt_getstring(pktin, &msg, &msglen);
- logeventf(ssh, "Remote debug message: %.*s", msglen, msg);
+ logeventf(ssh, "Remote debug message: %.*s", msglen, NULLTOEMPTY(msg));
}
static void ssh2_msg_transport(Ssh ssh, struct Packet *pktin)
\r
[Setup]\r
AppName=PuTTY\r
-AppVerName=PuTTY version 0.66\r
-VersionInfoTextVersion=Release 0.66\r
-AppVersion=0.66\r
-VersionInfoVersion=0.66.0.0\r
+AppVerName=PuTTY version 0.67\r
+VersionInfoTextVersion=Release 0.67\r
+AppVersion=0.67\r
+VersionInfoVersion=0.67.0.0\r
AppPublisher=Simon Tatham\r
AppPublisherURL=http://www.chiark.greenend.org.uk/~sgtatham/putty/\r
AppReadmeFile={app}\README.txt\r
ret = new_error_socket(err, plug);
sfree(err);
CloseHandle(pipehandle);
- sfree(usersid);
return ret;
}
sfree(err);
CloseHandle(pipehandle);
LocalFree(psd);
- sfree(usersid);
return ret;
}
LocalFree(psd);
- sfree(usersid);
return make_handle_socket(pipehandle, pipehandle, NULL, plug, TRUE);
}
debug(("couldn't get default SID\n"));
#endif
CloseHandle(filemap);
- sfree(ourself);
return 0;
}
rc));
#endif
CloseHandle(filemap);
- sfree(ourself);
sfree(ourself2);
return 0;
}
!EqualSid(mapowner, ourself2)) {
CloseHandle(filemap);
LocalFree(psd);
- sfree(ourself);
sfree(ourself2);
return 0; /* security ID mismatch! */
}
debug(("security stuff matched\n"));
#endif
LocalFree(psd);
- sfree(ourself);
sfree(ourself2);
} else {
#ifdef DEBUG_IPC
sfree(mapname);
if (psd)
LocalFree(psd);
- sfree(usersid);
return 1;
}
DWORD toklen, sidlen;
PSID sid = NULL, ret = NULL;
+ if (usersid)
+ return usersid;
+
if (!got_advapi())
goto cleanup;
/* Success. Move sid into the return value slot, and null it out
* to stop the cleanup code freeing it. */
- ret = sid;
+ ret = usersid = sid;
sid = NULL;
cleanup: