Revision: 9626 https://osdn.net/projects/ttssh2/scm/svn/commits/9626 Author: nmaya Date: 2021-12-24 01:48:04 +0900 (Fri, 24 Dec 2021) Log Message: ----------- PuTTY 0.76 にアップデート - 展開して使うソースを PuTTY 0.76 に変更 - コピーして使うソースも PuTTY 0.76 にアップデート Modified Paths: -------------- branches/putty_0_76/ttssh2/putty/libputty.c branches/putty_0_76/ttssh2/putty/libputty.h branches/putty_0_76/ttssh2/putty/putty.v16.vcxproj branches/putty_0_76/ttssh2/putty/putty.v16.vcxproj.filters branches/putty_0_76/ttssh2/ttxssh/ssh.c Added Paths: ----------- branches/putty_0_76/ttssh2/putty/putty-import.c -------------- next part -------------- Modified: branches/putty_0_76/ttssh2/putty/libputty.c =================================================================== --- branches/putty_0_76/ttssh2/putty/libputty.c 2021-12-23 16:34:36 UTC (rev 9625) +++ branches/putty_0_76/ttssh2/putty/libputty.c 2021-12-23 16:48:04 UTC (rev 9626) @@ -1,4 +1,3 @@ -// PuTTY is copyright 1997-2007 Simon Tatham. /* * Copyright (C) 1994-1998 T. Teranishi * (C) 2004- TeraTerm Project @@ -27,31 +26,59 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +// PuTTY is copyright 1997-2021 Simon Tatham. /* * putty \x83v\x83\x8D\x83W\x83F\x83N\x83g\x82\xCD - * - PuTTY \x82̃\\x81[\x83X\x83t\x83@\x83C\x83\x8B (\x83v\x83\x8D\x83W\x83F\x83N\x83g\x82ɓǂݍ\x9E\x82ރt\x83@\x83C\x83\x8B\x82͍ŏ\xAC\x8C\xC0) - * - libputty.c/h + * - libputty.c/h * PuTTY \x82̋@\x94\\x82𗘗p\x82\xB7\x82\xE9\x83C\x83\x93\x83^\x81[\x83t\x83F\x81[\x83X - * PuTTY \x82̃\\x81[\x83X\x83t\x83@\x83C\x83\x8B\x82\xA9\x82\xE7\x95K\x97v\x82Ȋ\x94\x82݂̂\xF0\x83R\x83s\x81[ + * PuTTY \x82̓\xE0\x95\x94\x8C^\x82Ƃ̕ϊ\xB7 + * - PuTTY \x82̃\\x81[\x83X\x83R\x81[\x83h (\x83v\x83\x8D\x83W\x83F\x83N\x83g\x82ɓǂݍ\x9E\x82ރt\x83@\x83C\x83\x8B\x82͍ŏ\xAC\x8C\xC0) + * -- \x93W\x8AJ\x82\xB5\x82\xBD PuTTY \x82̃\\x81[\x83X\x83t\x83@\x83C\x83\x8B\x82\xF0\x82\xBB\x82̂܂ܓǂݍ\x9E\x82\xE0\x82\xCC (Putty Files \x83O\x83\x8B\x81[\x83v\x93\xE0) + * -- putty \x83v\x83\x8D\x83W\x83F\x83N\x83g\x91\xA4\x82ɃR\x83s\x81[\x82\xB5\x82\xBD\x83\\x81[\x83X\x83R\x81[\x83h (putty-import.c) + * static \x82Ȃ\xBD\x82߂ɌĂяo\x82\xB9\x82Ȃ\xA2\x8A\x94\x82\xCC static \x82\xF0\x8AO\x82\xB7 + * putty \x82Ŏg\x82\xA4\x95\x94\x95\xAA\x82\xBE\x82\xAF\x82\x88 (putty \x82Ŏg\x82\xED\x82Ȃ\xA2\x95\x94\x95\xAA\x82ő\x9D\x82\xA6\x82Ă\xB5\x82܂\xA4\x88ˑ\xB6\x82\xF0\x97}\x90\xA7) * \x82\xA9\x82\xE7\x90ÓI\x83\x89\x83C\x83u\x83\x89\x83\x8A libputty.lib \x82\xAC\x82\xB5\x81ATTXSSH \x82\xA9\x82烊\x83\x93\x83N\x82\xB3\x82\xEA\x82ė\x98\x97p\x82\xB3\x82\xEA\x82\xE9\x81B * \x82\xBB\x82̂\xBD\x82߁ATTXSSH \x91\xA4\x82̒\xE8\x8B`\x82͎\x9D\x82\xBF\x8D\x9E\x82܂Ȃ\xA2\x81B */ +#include <stdio.h> #include <windows.h> #include <assert.h> -#include "sshbn.h" - -// from SSHBN.C (ver 0.60) -#define BIGNUM_INTERNAL -typedef BignumInt *Bignum; - #include "ssh.h" +#include "mpint.h" #include "libputty.h" +// pageant.c +typedef struct KeyListEntry { + ptrlen blob, comment; + uint32_t flags; +} KeyListEntry; +typedef struct KeyList { + strbuf *raw_data; + KeyListEntry *keys; + size_t nkeys; + bool broken; +} KeyList; + +// putty.h +// aqsync.c +extern void agent_query_synchronous(strbuf *in, void **out, int *outlen); + +// pageant.c +extern void keylist_free(KeyList *kl); + +// pageant.c +extern KeyList *pageant_get_keylist(unsigned ssh_version); + +// putty.h +// windows/winpgntc.c +extern bool agent_exists(void); + + /* * for SSH2 * \x8C\xAE\x82̈ꗗ\x82\xE9 @@ -58,20 +85,47 @@ */ int putty_get_ssh2_keylist(unsigned char **keylist) { - int keylistlen; + KeyList *kl; + int keylistlen = 0; + strbuf *sb_keylist = strbuf_new(); + size_t i; - *keylist = get_keylist2(&keylistlen); - if (*keylist == NULL){ - // \x8E擾\x82Ɏ\xB8\x94s - return 0; + kl = pageant_get_keylist(2); + if (kl) { + if (kl->broken) { + keylist_free(kl); + strbuf_free(sb_keylist); + return 0; + } + + put_uint32(sb_keylist, kl->nkeys); + keylistlen += 4; + for (i = 0; i < kl->nkeys; i++) { + put_uint32(sb_keylist, kl->keys[i].blob.len); + keylistlen += 4; + put_datapl(sb_keylist, kl->keys[i].blob); + keylistlen += kl->keys[i].blob.len; + put_uint32(sb_keylist, kl->keys[i].comment.len); + keylistlen += 4; + put_datapl(sb_keylist, kl->keys[i].comment); + keylistlen += kl->keys[i].comment.len; + } + keylist_free(kl); + + *keylist = strbuf_to_str(sb_keylist); + + return keylistlen; } - return keylistlen; + + strbuf_free(sb_keylist); + return 0; } /* * for SSH2 * \x8C\xF6\x8AJ\x8C\xAE\x82ƃf\x81[\x83^\x82\xF0\x93n\x82\xB5\x81A - * \x94閧\x8C\xAE\x82ɂ\xE6\x82\xC1\x82ď\x90\x96\xBC\x82\xB3\x82ꂽ\x83f\x81[\x83^\x82\xE9 + * \x94閧\x8C\xAE\x82ɂ\xE6\x82鏐\x96\xBC\x82\xE9 + * ssh2userauth.c (PuTTY 0.76) \x82\xA9\x82\xE7\x8Dč\\x90\xAC */ void *putty_sign_ssh2_key(unsigned char *pubkey /* length(4byte) + data */, unsigned char *data, @@ -80,43 +134,34 @@ { void *ret; - unsigned char *request, *response; + unsigned char *response; void *vresponse; - int resplen; - int pubkeylen, reqlen; - int flags = 0; + int response_len; + int pubkeylen; + strbuf *agentreq = strbuf_new_for_agent_query(); + int signflags = 0; - pubkeylen = GET_32BIT(pubkey); - reqlen = 4 + 1 + (4 + pubkeylen) + (4 + datalen) + 4; - request = (unsigned char *)malloc(reqlen); + put_byte(agentreq, SSH2_AGENTC_SIGN_REQUEST); + pubkeylen = GET_32BIT_MSB_FIRST(pubkey); + put_data(agentreq, pubkey, 4 + pubkeylen); + put_uint32(agentreq, datalen); + put_data(agentreq, data, datalen); + put_uint32(agentreq, signflags); + agent_query_synchronous(agentreq, &vresponse, &response_len); + strbuf_free(agentreq); - // request length - PUT_32BIT(request, reqlen); - // request type - request[4] = SSH2_AGENTC_SIGN_REQUEST; - // public key (length + data) - memcpy(request + 5, pubkey, 4 + pubkeylen); - // sign data length - PUT_32BIT(request + 5 + 4 + pubkeylen, datalen); - // sign data - memcpy(request + 5 + 4 + pubkeylen + 4, data, datalen); - // flags word - PUT_32BIT(request + 5 + 4 + pubkeylen + 4 + datalen, flags); - - agent_query(request, reqlen, &vresponse, &resplen, NULL, NULL); - response = vresponse; - if (resplen < 5 || response[4] != SSH2_AGENT_SIGN_RESPONSE) { + if (response_len < 5 || response[4] != SSH2_AGENT_SIGN_RESPONSE) { sfree(response); return NULL; } - ret = snewn(resplen-5, unsigned char); - memcpy(ret, response+5, resplen-5); + ret = snewn(response_len-5, unsigned char); + memcpy(ret, response+5, response_len-5); sfree(response); if (outlen) - *outlen = resplen-5; + *outlen = response_len-5; return ret; } @@ -127,14 +172,38 @@ */ int putty_get_ssh1_keylist(unsigned char **keylist) { - int keylistlen; + KeyList *kl; + int keylistlen = 0; + strbuf *sb_keylist = strbuf_new(); + size_t i; - *keylist = get_keylist1(&keylistlen); - if (*keylist == NULL){ - // \x8E擾\x82Ɏ\xB8\x94s - return 0; + kl = pageant_get_keylist(1); + if (kl) { + if (kl->broken) { + keylist_free(kl); + strbuf_free(sb_keylist); + return 0; + } + + put_uint32(sb_keylist, kl->nkeys); + keylistlen += 4; + for (i = 0; i < kl->nkeys; i++) { + put_data(sb_keylist, kl->keys[i].blob.ptr, kl->keys[i].blob.len); + keylistlen += kl->keys[i].blob.len; + put_uint32(sb_keylist, kl->keys[i].comment.len); + keylistlen += 4; + put_datapl(sb_keylist, kl->keys[i].comment); + keylistlen += kl->keys[i].comment.len; + } + keylist_free(kl); + + *keylist = strbuf_to_str(sb_keylist); + + return keylistlen; } - return keylistlen; + + strbuf_free(sb_keylist); + return 0; } /* @@ -141,6 +210,7 @@ * for SSH1 * \x8C\xF6\x8AJ\x8C\xAE\x82ƈÍ\x86\x89\xBB\x83f\x81[\x83^\x82\xF0\x93n\x82\xB5 * \x95\x9C\x8D\x86\x83f\x81[\x83^\x82̃n\x83b\x83V\x83\x85\x82\xE9 + * ssh1login.c (PuTTY 0.76) \x82\xA9\x82\xE7\x8Dč\\x90\xAC */ void *putty_hash_ssh1_challenge(unsigned char *pubkey, int pubkeylen, @@ -151,47 +221,31 @@ { void *ret; - unsigned char *request, *response, *p; + unsigned char *response; void *vresponse; - int resplen; - int reqlen; + int response_len; + strbuf *agentreq = strbuf_new_for_agent_query(); - reqlen = 4 + 1 + pubkeylen + datalen + 16 + 4; - request = (unsigned char *)malloc(reqlen); - p = request; + put_byte(agentreq, SSH1_AGENTC_RSA_CHALLENGE); + put_data(agentreq, pubkey, pubkeylen); + put_data(agentreq, data, datalen); + put_data(agentreq, session_id, 16); + put_uint32(agentreq, 1); // response format + agent_query_synchronous(agentreq, &vresponse, &response_len); + strbuf_free(agentreq); - // request length - PUT_32BIT(request, reqlen); - // request type - request[4] = SSH1_AGENTC_RSA_CHALLENGE; - p += 5; - - // public key - memcpy(p, pubkey, pubkeylen); - p += pubkeylen; - // challange from server - memcpy(p, data, datalen); - p += datalen; - // session_id - memcpy(p, session_id, 16); - p += 16; - // response format - PUT_32BIT(p, 1); - - agent_query(request, reqlen, &vresponse, &resplen, NULL, NULL); - response = vresponse; - if (resplen < 5 || response[4] != SSH1_AGENT_RSA_RESPONSE) { + if (response_len < 5+16 || response[4] != SSH1_AGENT_RSA_RESPONSE) { sfree(response); return NULL; } - ret = snewn(resplen-5, unsigned char); - memcpy(ret, response+5, resplen-5); + ret = snewn(response_len-5, unsigned char); + memcpy(ret, response+5, response_len-5); sfree(response); if (outlen) - *outlen = resplen-5; + *outlen = response_len-5; return ret; } @@ -198,7 +252,7 @@ int putty_get_ssh1_keylen(unsigned char *key, int maxlen) { - return rsa_public_blob_len(key, maxlen); + return rsa_ssh1_public_blob_len(make_ptrlen(key, maxlen)); } const char *putty_get_version() @@ -207,173 +261,15 @@ return ver; } -/* - * Following functions are copied from putty source. - */ - -// from SSHBN.C (ver 0.63) -static Bignum newbn(int length) +void putty_agent_query_synchronous(void *in, int inlen, void **out, int *outlen) { - Bignum b; + strbuf *buf = strbuf_new(); - assert(length >= 0 && length < INT_MAX / BIGNUM_INT_BITS); - - b = snewn(length + 1, BignumInt); - if (!b) - abort(); /* FIXME */ - memset(b, 0, (length + 1) * sizeof(*b)); - b[0] = length; - return b; + put_data(buf, in, inlen); + agent_query_synchronous(buf, out, outlen); + strbuf_free(buf); } -// from SSHBN.C (ver 0.65) -Bignum bignum_from_bytes(const unsigned char *data, int nbytes) -{ - Bignum result; - int w, i; - - assert(nbytes >= 0 && nbytes < INT_MAX / 8); - - w = (nbytes + BIGNUM_INT_BYTES - 1) / BIGNUM_INT_BYTES; /* bytes->words */ - - result = newbn(w); - for (i = 1; i <= w; i++) - result[i] = 0; - for (i = nbytes; i--;) { - unsigned char byte = *data++; - result[1 + i / BIGNUM_INT_BYTES] |= - (BignumInt)byte << (8 * i % BIGNUM_INT_BITS); - } - - while (result[0] > 1 && result[result[0]] == 0) - result[0]--; - return result; -} - -// from SSHBN.C (ver 0.60) -/* -* Read an SSH-1-format bignum from a data buffer. Return the number -* of bytes consumed, or -1 if there wasn't enough data. -*/ -int ssh1_read_bignum(const unsigned char *data, int len, Bignum * result) -{ - const unsigned char *p = data; - int i; - int w, b; - - if (len < 2) - return -1; - - w = 0; - for (i = 0; i < 2; i++) - w = (w << 8) + *p++; - b = (w + 7) / 8; /* bits -> bytes */ - - if (len < b + 2) - return -1; - - if (!result) /* just return length */ - return b + 2; - - *result = bignum_from_bytes(p, b); - - return p + b - data; -} - -// from SSHRSA.C (putty 0.60) -/* Given a public blob, determine its length. */ -int rsa_public_blob_len(void *data, int maxlen) -{ - unsigned char *p = (unsigned char *)data; - int n; - - if (maxlen < 4) - return -1; - p += 4; /* length word */ - maxlen -= 4; - - n = ssh1_read_bignum(p, maxlen, NULL); /* exponent */ - if (n < 0) - return -1; - p += n; - - n = ssh1_read_bignum(p, maxlen, NULL); /* modulus */ - if (n < 0) - return -1; - p += n; - - return p - (unsigned char *)data; -} - -// from WINDOWS\WINPGNT.C (putty 0.63) -/* - * Acquire a keylist1 from the primary Pageant; this means either - * calling make_keylist1 (if that's us) or sending a message to the - * primary Pageant (if it's not). - */ -static void *get_keylist1(int *length) -{ - void *ret; - - unsigned char request[5], *response; - void *vresponse; - int resplen; - request[4] = SSH1_AGENTC_REQUEST_RSA_IDENTITIES; - PUT_32BIT(request, 1); - - agent_query(request, 5, &vresponse, &resplen, NULL, NULL); - - response = vresponse; - if (resplen < 5 || response[4] != SSH1_AGENT_RSA_IDENTITIES_ANSWER) { - sfree(response); - return NULL; - } - - ret = snewn(resplen-5, unsigned char); - memcpy(ret, response+5, resplen-5); - sfree(response); - - if (length) - *length = resplen-5; - - return ret; -} - -// from WINDOWS\WINPGNT.C (putty 0.63) -/* - * Acquire a keylist2 from the primary Pageant; this means either - * calling make_keylist2 (if that's us) or sending a message to the - * primary Pageant (if it's not). - */ -static void *get_keylist2(int *length) -{ - void *ret; - - unsigned char request[5], *response; - void *vresponse; - int resplen; - - request[4] = SSH2_AGENTC_REQUEST_IDENTITIES; - PUT_32BIT(request, 1); - - agent_query(request, 5, &vresponse, &resplen, NULL, NULL); - - response = vresponse; - if (resplen < 5 || response[4] != SSH2_AGENT_IDENTITIES_ANSWER) { - sfree(response); - return NULL; - } - - ret = snewn(resplen-5, unsigned char); - memcpy(ret, response+5, resplen-5); - sfree(response); - - if (length) - *length = resplen-5; - - return ret; -} - BOOL putty_agent_exists() { if (agent_exists()) { @@ -382,20 +278,3 @@ return FALSE; } -// from WINDOWS\WINDOW.C (putty 0.60) -/* - * Print a modal (Really Bad) message box and perform a fatal exit. - */ -void modalfatalbox(char *fmt, ...) -{ - va_list ap; - char *stuff, morestuff[100]; - - va_start(ap, fmt); - stuff = dupvprintf(fmt, ap); - va_end(ap); - sprintf(morestuff, "%.70s Fatal Error", "TTSSH"); - MessageBox(NULL, stuff, morestuff, - MB_SYSTEMMODAL | MB_ICONERROR | MB_OK); - sfree(stuff); -} Modified: branches/putty_0_76/ttssh2/putty/libputty.h =================================================================== --- branches/putty_0_76/ttssh2/putty/libputty.h 2021-12-23 16:34:36 UTC (rev 9625) +++ branches/putty_0_76/ttssh2/putty/libputty.h 2021-12-23 16:48:04 UTC (rev 9626) @@ -25,24 +25,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. */ -// PuTTY is copyright 1997-2007 Simon Tatham. +// PuTTY is copyright 1997-2021 Simon Tatham. -// pageant.h -// \x96{\x93\x96\x82\xCD pageant.h \x82\xF0 include \x8Fo\x97\x88\x82\xE9\x82悤\x82ɂ\xB7\x82\xE9\x95\x{30AA0A2}\x82\xA2\x82̂\xA9\x82\xE0\x82\xB5\x82\xEA\x82Ȃ\xA2\x82\xAF\x82\xEA\x82\xC7 -// \x8A\x94\x82̃v\x83\x8D\x83g\x83^\x83C\x83v\x90錾\x82\xE0\x82\xB1\x82\xB1\x82ɂ\xA0\x82\xE9\x82̂Ŏ\xE6\x82肠\x82\xA6\x82\xB8\x82\xB1\x82\xB1\x82ŁB -#define AGENT_MAX_MSGLEN 8192 - -// \x83G\x83\x89\x81[\x89\x9E\x93\x9A\x97p -#define SSH_AGENT_FAILURE_MSG "\x00\x00\x00\x01\x05" - -// MISC.C -extern void safefree(void *); - -// WINDOWS\WINPGNTC.C -extern int agent_exists(void); -extern void *agent_query(void *in, int inlen, void **out, int *outlen, - void (*callback)(void *, void *, int), void *callback_ctx); - int putty_get_ssh2_keylist(unsigned char **keylist); void *putty_sign_ssh2_key(unsigned char *pubkey, unsigned char *data, @@ -57,7 +41,16 @@ int *outlen); int putty_get_ssh1_keylen(unsigned char *key, int maxlen); const char *putty_get_version(); +void putty_agent_query_synchronous(void *in, int inlen, void **out, int *outlen); BOOL putty_agent_exists(); -static void *get_keylist1(int *length); -static void *get_keylist2(int *length); +// \x83G\x83\x89\x81[\x89\x9E\x93\x9A\x97p +#define SSH_AGENT_FAILURE_MSG "\x00\x00\x00\x01\x05" + +// pageant.h +#define AGENT_MAX_MSGLEN 262144 + +// puttymen.h +// memory.c +extern void safefree(void *); + Added: branches/putty_0_76/ttssh2/putty/putty-import.c =================================================================== --- branches/putty_0_76/ttssh2/putty/putty-import.c (rev 0) +++ branches/putty_0_76/ttssh2/putty/putty-import.c 2021-12-23 16:48:04 UTC (rev 9626) @@ -0,0 +1,446 @@ +/* + * Copyright (C) 1994-1998 T. Teranishi + * (C) 2004- TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// PuTTY is copyright 1997-2021 Simon Tatham. + +/* + * \x83\\x81[\x83X\x91S\x91̂\xF0\x82\xBB\x82̂܂܃v\x83\x8D\x83W\x83F\x83N\x83g\x82ɒlj\xC1\x82\xB7\x82\xE9\x82ƁA + * \x8Eg\x82\xED\x82Ȃ\xA2\x95\x94\x95\xAA\x82ňˑ\xB6\x90悪\x91\x9D\x82\xA6\x81A\x82\xB3\x82\xE7\x82ɂ\xBB\x82̈ˑ\xB6\x90悪\x91\x9D\x82\xA6\x82\xBD\x82苣\x8D\x87\x82\xAA\x8BN\x82\xAB\x82\xE9\x82̂ŁA + * PuTTY \x82̃\\x81[\x83X\x82\xA9\x82\xE7\x83R\x83s\x81[\x82\xB5\x82Ă\xAB\x82\xBD\x83R\x81[\x83h + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "ssh.h" +#include "mpint.h" +#include "putty.h" +#include "network.h" +#include "sshcr.h" +#include "pageant.h" + + +// from pageant.c (PuTTY 0.76) +#define DECL_EXT_ENUM(id, name) id, +enum Extension { KNOWN_EXTENSIONS(DECL_EXT_ENUM) EXT_UNKNOWN }; +#define DEF_EXT_NAMES(id, name) PTRLEN_DECL_LITERAL(name), +static const ptrlen extension_names[] = { KNOWN_EXTENSIONS(DEF_EXT_NAMES) }; + +// from pageant.c (PuTTY 0.76) +typedef struct PageantClientOp { + strbuf *buf; + bool request_made; + BinarySink_DELEGATE_IMPLEMENTATION; + BinarySource_IMPLEMENTATION; +} PageantClientOp; + +// from pageant.c (PuTTY 0.76) +typedef struct KeyListEntry { + ptrlen blob, comment; + uint32_t flags; +} KeyListEntry; + +// from pageant.c (PuTTY 0.76) +typedef struct KeyList { + strbuf *raw_data; + KeyListEntry *keys; + size_t nkeys; + bool broken; +} KeyList; + +// from pageant.c (PuTTY 0.76) +static PageantClientOp *pageant_client_op_new(void) +{ + PageantClientOp *pco = snew(PageantClientOp); + pco->buf = strbuf_new_for_agent_query(); + pco->request_made = false; + BinarySink_DELEGATE_INIT(pco, pco->buf); + BinarySource_INIT(pco, "", 0); + return pco; +} + +// from pageant.c (PuTTY 0.76) +static void pageant_client_op_free(PageantClientOp *pco) +{ + if (pco->buf) + strbuf_free(pco->buf); + sfree(pco); +} + +// from pageant.c (PuTTY 0.76) +static unsigned pageant_client_op_query(PageantClientOp *pco) +{ + /* Since we use the same strbuf for the request and the response, + * check by assertion that we aren't embarrassingly sending a + * previous response back to the agent */ + assert(!pco->request_made); + pco->request_made = true; + + void *response_raw; + int resplen_raw; + agent_query_synchronous(pco->buf, &response_raw, &resplen_raw); + strbuf_clear(pco->buf); + put_data(pco->buf, response_raw, resplen_raw); + sfree(response_raw); + + /* The data coming back from agent_query_synchronous will have + * its length field prepended. So we start by parsing it as an + * SSH-formatted string, and then reinitialise our + * BinarySource with the interior of that string. */ + BinarySource_INIT_PL(pco, ptrlen_from_strbuf(pco->buf)); + BinarySource_INIT_PL(pco, get_string(pco)); + + /* Strip off and directly return the type byte, which every client + * will need, to save a boilerplate get_byte at each call site */ + unsigned reply_type = get_byte(pco); + if (get_err(pco)) + reply_type = 256; /* out-of-range code */ + return reply_type; +} + +// from pageant.c (PuTTY 0.76) +void keylist_free(KeyList *kl) +{ + sfree(kl->keys); + strbuf_free(kl->raw_data); + sfree(kl); +} + +// from pageant.c (PuTTY 0.76) +static PageantClientOp *pageant_request_keylist_1(void) +{ + PageantClientOp *pco = pageant_client_op_new(); + put_byte(pco, SSH1_AGENTC_REQUEST_RSA_IDENTITIES); + if (pageant_client_op_query(pco) == SSH1_AGENT_RSA_IDENTITIES_ANSWER) + return pco; + pageant_client_op_free(pco); + return NULL; +} + +// from pageant.c (PuTTY 0.76) +static PageantClientOp *pageant_request_keylist_2(void) +{ + PageantClientOp *pco = pageant_client_op_new(); + put_byte(pco, SSH2_AGENTC_REQUEST_IDENTITIES); + if (pageant_client_op_query(pco) == SSH2_AGENT_IDENTITIES_ANSWER) + return pco; + pageant_client_op_free(pco); + return NULL; +} + +// from pageant.c (PuTTY 0.76) +static PageantClientOp *pageant_request_keylist_extended(void) +{ + PageantClientOp *pco = pageant_client_op_new(); + put_byte(pco, SSH2_AGENTC_EXTENSION); + put_stringpl(pco, extension_names[EXT_LIST_EXTENDED]); + if (pageant_client_op_query(pco) == SSH_AGENT_SUCCESS) + return pco; + pageant_client_op_free(pco); + return NULL; +} + +// from pageant.c (PuTTY 0.76) +KeyList *pageant_get_keylist(unsigned ssh_version) +{ + PageantClientOp *pco; + bool list_is_extended = false; + + if (ssh_version == 1) { + pco = pageant_request_keylist_1(); + } else { + if ((pco = pageant_request_keylist_extended()) != NULL) + list_is_extended = true; + else + pco = pageant_request_keylist_2(); + } + + if (!pco) + return NULL; + + KeyList *kl = snew(KeyList); + kl->nkeys = get_uint32(pco); + kl->keys = snewn(kl->nkeys, struct KeyListEntry); + kl->broken = false; + + for (size_t i = 0; i < kl->nkeys && !get_err(pco); i++) { + if (ssh_version == 1) { + int bloblen = rsa_ssh1_public_blob_len( + make_ptrlen(get_ptr(pco), get_avail(pco))); + if (bloblen < 0) { + kl->broken = true; + bloblen = 0; + } + kl->keys[i].blob = get_data(pco, bloblen); + } else { + kl->keys[i].blob = get_string(pco); + } + kl->keys[i].comment = get_string(pco); + + if (list_is_extended) { + ptrlen key_ext_info = get_string(pco); + BinarySource src[1]; + BinarySource_BARE_INIT_PL(src, key_ext_info); + + kl->keys[i].flags = get_uint32(src); + } else { + kl->keys[i].flags = 0; + } + } + + if (get_err(pco)) + kl->broken = true; + kl->raw_data = pco->buf; + pco->buf = NULL; + pageant_client_op_free(pco); + return kl; +} + +// from sshrsa.c (PuTTY 0.76) +/* Given an SSH-1 public key blob, determine its length. */ +int rsa_ssh1_public_blob_len(ptrlen data) +{ + BinarySource src[1]; + + BinarySource_BARE_INIT_PL(src, data); + + /* Expect a length word, then exponent and modulus. (It doesn't + * even matter which order.) */ + get_uint32(src); + mp_free(get_mp_ssh1(src)); + mp_free(get_mp_ssh1(src)); + + if (get_err(src)) + return -1; + + /* Return the number of bytes consumed. */ + return src->pos; +} + +// from windows/winmiscs.c (PuTTY 0.76) +/* + * Windows implementation of smemclr (see misc.c) using SecureZeroMemory. + */ +void smemclr(void *b, size_t n) { + if (b && n > 0) + SecureZeroMemory(b, n); +} + +// from be_misc.c (PuTTY 0.76) +void log_proxy_stderr(Plug *plug, ProxyStderrBuf *psb, + const void *vdata, size_t len) +{ + const char *data = (const char *)vdata; + + /* + * This helper function allows us to collect the data written to a + * local proxy command's standard error in whatever size chunks we + * happen to get from its pipe, and whenever we have a complete + * line, we pass it to plug_log. + * + * (We also do this when the buffer in psb fills up, to avoid just + * allocating more and more memory forever, and also to keep Event + * Log lines reasonably bounded in size.) + * + * Prerequisites: a plug to log to, and a ProxyStderrBuf stored + * somewhere to collect any not-yet-output partial line. + */ + + while (len > 0) { + /* + * Copy as much data into psb->buf as will fit. + */ + assert(psb->size < lenof(psb->buf)); + size_t to_consume = lenof(psb->buf) - psb->size; + if (to_consume > len) + to_consume = len; + memcpy(psb->buf + psb->size, data, to_consume); + data += to_consume; + len -= to_consume; + psb->size += to_consume; + + /* + * Output any full lines in psb->buf. + */ + size_t pos = 0; + while (pos < psb->size) { + char *nlpos = memchr(psb->buf + pos, '\n', psb->size - pos); + if (!nlpos) + break; + + /* + * Found a newline in the buffer, so we can output a line. + */ + size_t endpos = nlpos - psb->buf; + while (endpos > pos && (psb->buf[endpos-1] == '\n' || + psb->buf[endpos-1] == '\r')) + endpos--; + char *msg = dupprintf( + "proxy: %.*s", (int)(endpos - pos), psb->buf + pos); + plug_log(plug, PLUGLOG_PROXY_MSG, NULL, 0, msg, 0); + sfree(msg); + + pos = nlpos - psb->buf + 1; + assert(pos <= psb->size); + } + + /* + * If the buffer is completely full and we didn't output + * anything, then output the whole thing, flagging it as a + * truncated line. + */ + if (pos == 0 && psb->size == lenof(psb->buf)) { + char *msg = dupprintf( + "proxy (partial line): %.*s", (int)psb->size, psb->buf); + plug_log(plug, PLUGLOG_PROXY_MSG, NULL, 0, msg, 0); + sfree(msg); + + pos = psb->size = 0; + } + + /* + * Now move any remaining data up to the front of the buffer. + */ + size_t newsize = psb->size - pos; + if (newsize) + memmove(psb->buf, psb->buf + pos, newsize); + psb->size = newsize; + + /* + * And loop round again if there's more data to be read from + * our input. + */ + } +} + +// from be_misc.c (PuTTY 0.76) +void psb_init(ProxyStderrBuf *psb) +{ + psb->size = 0; +} + +// from windows/winpgnt.c (PuTTY 0.76) +void noise_ultralight(NoiseSourceId id, unsigned long data) +{ + /* Pageant doesn't use random numbers, so we ignore this */ +} + +// from windows/window.c (PuTTY 0.76) +/* + * Print a modal (Really Bad) message box and perform a fatal exit. + */ +void modalfatalbox(const char *fmt, ...) +{ + va_list ap; + char *message, *title; + + va_start(ap, fmt); + message = dupvprintf(fmt, ap); + va_end(ap); + title = dupprintf("%s Fatal Error", "TTSSH"); + MessageBox(NULL, message, title, + MB_SYSTEMMODAL | MB_ICONERROR | MB_OK); + sfree(message); + sfree(title); +} + +// from misc.c (PuTTY 0.76) +void out_of_memory(void) +{ + modalfatalbox("Out of memory"); +} + + +/* +putty_get_ssh1_keylen()@libputty.c + rsa_ssh1_public_blob_len()@sshrsa.c ... import + +memory.c / mpint.c / utils.c + smemclr()@windows/winmiscs.c ... import + +safemalloc()@memory.c + out_of_memory()@misc.c ... import + modalfatalbox()@windows/window.c ... import + +wm_copydata_agent_query()@windows\winpgnt.c + got_advapi()@windows\winsecur.c ... include winsecur.c + +agent_named_pipe_name()@windows\winpgnt.c + get_username()@windows\winmisc.c ... include winmisc.c + +agent_connect()@windows\winpgnt.c + new_named_pipe_client()@winnpc.c ... include winnpc.c + connect_to_named_pipe()@winnpc.c + new_error_socket_consume_string()@errsock.c ... include errsock.c + make_handle_socket()@winsocket.c ... include winsocket.c + handle_input_new()@winhandl.c ... include winhandl.c + handle_output_new()@winhandl.c + psb_init()@be_misc.c ... import + handle_stderr()@winhsock.c + log_proxy_stderr()@be_misc.c ... import + +agent_named_pipe_name()@windows\winpgnt.c + capi_obfuscate_string()@windows\wincapi.c ... include wincapi.c + ssh_sha25****@sshsh***** ... include sshsh256.c + +handle_got_event()@windows\winhandl.c + noise_ultralight()@windows/winpgnt.c + +sk_handle_set_frozen()@windows\winhsock.c + queue_toplevel_callback()@callback.c ... include callback.c +sk_handle_close()@windows\winhsock.c + delete_callbacks_for_context()@callback.c + +winmisc.c refers to tree234 ... include tree234.c + + + +if include be_misc.c ... +backend_socket_log()@be_misc.c + sk_getaddr()@windows\winnet.c + sk_addr_needs_port()@windows\winnet.c + conf_get_int()@conf.c + logevent()@logging.c + +if include sshrsa.c ... +rsa_components()@sshrsa.c + key_components_new()@sshpubk.c + key_components_add_text()@sshpubk.c + key_components_add_mp()@sshpubk.c +ssh_rsakex_encrypt()@sshrsa.c + hash_simple()@sshauxcrypt.c +ssh_rsakex_decrypt()@sshrsa.c + hash_simple()@sshauxcrypt.c +rsa_ssh1_encrypt()@sshrsa.c + random_read()@sshrand.c + +if include sshauxcropt.c ... +mac_simple()@sshauxcropt.c coflicts mac_simple()@keyfiles-putty.c +*/ Modified: branches/putty_0_76/ttssh2/putty/putty.v16.vcxproj =================================================================== --- branches/putty_0_76/ttssh2/putty/putty.v16.vcxproj 2021-12-23 16:34:36 UTC (rev 9625) +++ branches/putty_0_76/ttssh2/putty/putty.v16.vcxproj 2021-12-23 16:48:04 UTC (rev 9626) @@ -71,14 +71,25 @@ </ClCompile> </ItemDefinitionGroup> <ItemGroup> - <ClCompile Include="..\..\libs\putty\CONF.C" /> - <ClCompile Include="..\..\libs\putty\MISC.C" /> - <ClCompile Include="..\..\libs\putty\TREE234.C" /> - <ClCompile Include="..\..\libs\putty\VERSION.C" /> - <ClCompile Include="..\..\libs\putty\WINDOWS\WINMISC.C" /> - <ClCompile Include="..\..\libs\putty\WINDOWS\WINPGNTC.C" /> - <ClCompile Include="..\..\libs\putty\WINDOWS\WINSECUR.C" /> + <ClCompile Include="..\..\libs\putty\aqsync.c" /> + <ClCompile Include="..\..\libs\putty\callback.c" /> + <ClCompile Include="..\..\libs\putty\errsock.c" /> + <ClCompile Include="..\..\libs\putty\marshal.c" /> + <ClCompile Include="..\..\libs\putty\memory.c" /> + <ClCompile Include="..\..\libs\putty\mpint.c" /> + <ClCompile Include="..\..\libs\putty\sshsh256.c" /> + <ClCompile Include="..\..\libs\putty\tree234.c" /> + <ClCompile Include="..\..\libs\putty\utils.c" /> + <ClCompile Include="..\..\libs\putty\version.c" /> + <ClCompile Include="..\..\libs\putty\windows\wincapi.c" /> + <ClCompile Include="..\..\libs\putty\windows\winhandl.c" /> + <ClCompile Include="..\..\libs\putty\windows\winhsock.c" /> + <ClCompile Include="..\..\libs\putty\windows\winmisc.c" /> + <ClCompile Include="..\..\libs\putty\windows\winnpc.c" /> + <ClCompile Include="..\..\libs\putty\windows\winpgntc.c" /> + <ClCompile Include="..\..\libs\putty\windows\winsecur.c" /> <ClCompile Include="libputty.c" /> + <ClCompile Include="putty-import.c" /> </ItemGroup> <ItemGroup> <ClInclude Include="libputty.h" /> Modified: branches/putty_0_76/ttssh2/putty/putty.v16.vcxproj.filters =================================================================== --- branches/putty_0_76/ttssh2/putty/putty.v16.vcxproj.filters 2021-12-23 16:34:36 UTC (rev 9625) +++ branches/putty_0_76/ttssh2/putty/putty.v16.vcxproj.filters 2021-12-23 16:48:04 UTC (rev 9626) @@ -6,28 +6,59 @@ </Filter> </ItemGroup> <ItemGroup> - <ClCompile Include="..\..\libs\putty\CONF.C"> + <ClCompile Include="..\..\libs\putty\aqsync.c"> <Filter>Putty Files</Filter> </ClCompile> - <ClCompile Include="..\..\libs\putty\MISC.C"> + <ClCompile Include="..\..\libs\putty\callback.c"> <Filter>Putty Files</Filter> </ClCompile> - <ClCompile Include="..\..\libs\putty\TREE234.C"> + <ClCompile Include="..\..\libs\putty\errsock.c"> <Filter>Putty Files</Filter> </ClCompile> - <ClCompile Include="..\..\libs\putty\VERSION.C"> + <ClCompile Include="..\..\libs\putty\marshal.c"> <Filter>Putty Files</Filter> </ClCompile> - <ClCompile Include="..\..\libs\putty\WINDOWS\WINMISC.C"> + <ClCompile Include="..\..\libs\putty\memory.c"> <Filter>Putty Files</Filter> </ClCompile> - <ClCompile Include="..\..\libs\putty\WINDOWS\WINPGNTC.C"> + <ClCompile Include="..\..\libs\putty\mpint.c"> <Filter>Putty Files</Filter> </ClCompile> - <ClCompile Include="..\..\libs\putty\WINDOWS\WINSECUR.C"> + <ClCompile Include="..\..\libs\putty\sshsh256.c"> <Filter>Putty Files</Filter> </ClCompile> + <ClCompile Include="..\..\libs\putty\tree234.c"> + <Filter>Putty Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libs\putty\utils.c"> + <Filter>Putty Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libs\putty\version.c"> + <Filter>Putty Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libs\putty\windows\wincapi.c"> + <Filter>Putty Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libs\putty\windows\winhandl.c"> + <Filter>Putty Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libs\putty\windows\winhsock.c"> + <Filter>Putty Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libs\putty\windows\winmisc.c"> + <Filter>Putty Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libs\putty\windows\winnpc.c"> + <Filter>Putty Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libs\putty\windows\winpgntc.c"> + <Filter>Putty Files</Filter> + </ClCompile> + <ClCompile Include="..\..\libs\putty\windows\winsecur.c"> + <Filter>Putty Files</Filter> + </ClCompile> <ClCompile Include="libputty.c" /> + <ClCompile Include="putty-import.c" /> </ItemGroup> <ItemGroup> <ClInclude Include="libputty.h" /> Modified: branches/putty_0_76/ttssh2/ttxssh/ssh.c =================================================================== --- branches/putty_0_76/ttssh2/ttxssh/ssh.c 2021-12-23 16:34:36 UTC (rev 9625) +++ branches/putty_0_76/ttssh2/ttxssh/ssh.c 2021-12-23 16:48:04 UTC (rev 9626) @@ -9503,9 +9503,9 @@ data = agent_msg->buf; } - agent_query(data, *agent_request_len, &response, &resplen, NULL, NULL); + putty_agent_query_synchronous(data, *agent_request_len, &response, &resplen); if (response == NULL || resplen < 5) { - logprintf(LOG_LEVEL_NOTICE, "%s Agent Forwarding Error: agent_query is failed.", __FUNCTION__); + logprintf(LOG_LEVEL_NOTICE, "%s Agent Forwarding Error: putty_agent_query_synchronous is failed.", __FUNCTION__); goto error; }