• R/O
  • SSH
  • HTTPS

ttssh2: Commit


Commit MetaInfo

Revision9626 (tree)
Time2021-12-24 01:48:04
Authornmaya

Log Message

PuTTY 0.76 にアップデート

- 展開して使うソースを PuTTY 0.76 に変更
- コピーして使うソースも PuTTY 0.76 にアップデート

Change Summary

Incremental Difference

--- branches/putty_0_76/ttssh2/putty/libputty.c (revision 9625)
+++ branches/putty_0_76/ttssh2/putty/libputty.c (revision 9626)
@@ -1,4 +1,3 @@
1-// PuTTY is copyright 1997-2007 Simon Tatham.
21 /*
32 * Copyright (C) 1994-1998 T. Teranishi
43 * (C) 2004- TeraTerm Project
@@ -27,31 +26,59 @@
2726 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2827 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2928 */
29+// PuTTY is copyright 1997-2021 Simon Tatham.
3030
3131 /*
3232 * putty プロジェクトは
33- * - PuTTY のソースファイル (プロジェクトに読み込むファイルは最小限)
34- * - libputty.c/h
33+ * - libputty.c/h
3534 * PuTTY の機能を利用するインターフェース
36- * PuTTY のソースファイルから必要な関数のみをコピー
35+ * PuTTY の内部型との変換
36+ * - PuTTY のソースコード (プロジェクトに読み込むファイルは最小限)
37+ * -- 展開した PuTTY のソースファイルをそのまま読み込んだもの (Putty Files グループ内)
38+ * -- putty プロジェクト側にコピーしたソースコード (putty-import.c)
39+ * static なために呼び出せない関数の static を外す
40+ * putty で使う部分だけを抜粋 (putty で使わない部分で増えてしまう依存を抑制)
3741 * から静的ライブラリ libputty.lib を生成し、TTXSSH からリンクされて利用される。
3842 * そのため、TTXSSH 側の定義は持ち込まない。
3943 */
4044
45+#include <stdio.h>
4146 #include <windows.h>
4247 #include <assert.h>
4348
44-#include "sshbn.h"
45-
46-// from SSHBN.C (ver 0.60)
47-#define BIGNUM_INTERNAL
48-typedef BignumInt *Bignum;
49-
5049 #include "ssh.h"
50+#include "mpint.h"
5151
5252 #include "libputty.h"
5353
5454
55+// pageant.c
56+typedef struct KeyListEntry {
57+ ptrlen blob, comment;
58+ uint32_t flags;
59+} KeyListEntry;
60+typedef struct KeyList {
61+ strbuf *raw_data;
62+ KeyListEntry *keys;
63+ size_t nkeys;
64+ bool broken;
65+} KeyList;
66+
67+// putty.h
68+// aqsync.c
69+extern void agent_query_synchronous(strbuf *in, void **out, int *outlen);
70+
71+// pageant.c
72+extern void keylist_free(KeyList *kl);
73+
74+// pageant.c
75+extern KeyList *pageant_get_keylist(unsigned ssh_version);
76+
77+// putty.h
78+// windows/winpgntc.c
79+extern bool agent_exists(void);
80+
81+
5582 /*
5683 * for SSH2
5784 * 鍵の一覧を得る
@@ -58,20 +85,47 @@
5885 */
5986 int putty_get_ssh2_keylist(unsigned char **keylist)
6087 {
61- int keylistlen;
88+ KeyList *kl;
89+ int keylistlen = 0;
90+ strbuf *sb_keylist = strbuf_new();
91+ size_t i;
6292
63- *keylist = get_keylist2(&keylistlen);
64- if (*keylist == NULL){
65- // 取得に失敗
66- return 0;
93+ kl = pageant_get_keylist(2);
94+ if (kl) {
95+ if (kl->broken) {
96+ keylist_free(kl);
97+ strbuf_free(sb_keylist);
98+ return 0;
99+ }
100+
101+ put_uint32(sb_keylist, kl->nkeys);
102+ keylistlen += 4;
103+ for (i = 0; i < kl->nkeys; i++) {
104+ put_uint32(sb_keylist, kl->keys[i].blob.len);
105+ keylistlen += 4;
106+ put_datapl(sb_keylist, kl->keys[i].blob);
107+ keylistlen += kl->keys[i].blob.len;
108+ put_uint32(sb_keylist, kl->keys[i].comment.len);
109+ keylistlen += 4;
110+ put_datapl(sb_keylist, kl->keys[i].comment);
111+ keylistlen += kl->keys[i].comment.len;
112+ }
113+ keylist_free(kl);
114+
115+ *keylist = strbuf_to_str(sb_keylist);
116+
117+ return keylistlen;
67118 }
68- return keylistlen;
119+
120+ strbuf_free(sb_keylist);
121+ return 0;
69122 }
70123
71124 /*
72125 * for SSH2
73126 * 公開鍵とデータを渡し、
74- * 秘密鍵によって署名されたデータを得る
127+ * 秘密鍵による署名を得る
128+ * ssh2userauth.c (PuTTY 0.76) から再構成
75129 */
76130 void *putty_sign_ssh2_key(unsigned char *pubkey /* length(4byte) + data */,
77131 unsigned char *data,
@@ -80,43 +134,34 @@
80134 {
81135 void *ret;
82136
83- unsigned char *request, *response;
137+ unsigned char *response;
84138 void *vresponse;
85- int resplen;
86- int pubkeylen, reqlen;
87- int flags = 0;
139+ int response_len;
140+ int pubkeylen;
141+ strbuf *agentreq = strbuf_new_for_agent_query();
142+ int signflags = 0;
88143
89- pubkeylen = GET_32BIT(pubkey);
90- reqlen = 4 + 1 + (4 + pubkeylen) + (4 + datalen) + 4;
91- request = (unsigned char *)malloc(reqlen);
144+ put_byte(agentreq, SSH2_AGENTC_SIGN_REQUEST);
145+ pubkeylen = GET_32BIT_MSB_FIRST(pubkey);
146+ put_data(agentreq, pubkey, 4 + pubkeylen);
147+ put_uint32(agentreq, datalen);
148+ put_data(agentreq, data, datalen);
149+ put_uint32(agentreq, signflags);
150+ agent_query_synchronous(agentreq, &vresponse, &response_len);
151+ strbuf_free(agentreq);
92152
93- // request length
94- PUT_32BIT(request, reqlen);
95- // request type
96- request[4] = SSH2_AGENTC_SIGN_REQUEST;
97- // public key (length + data)
98- memcpy(request + 5, pubkey, 4 + pubkeylen);
99- // sign data length
100- PUT_32BIT(request + 5 + 4 + pubkeylen, datalen);
101- // sign data
102- memcpy(request + 5 + 4 + pubkeylen + 4, data, datalen);
103- // flags word
104- PUT_32BIT(request + 5 + 4 + pubkeylen + 4 + datalen, flags);
105-
106- agent_query(request, reqlen, &vresponse, &resplen, NULL, NULL);
107-
108153 response = vresponse;
109- if (resplen < 5 || response[4] != SSH2_AGENT_SIGN_RESPONSE) {
154+ if (response_len < 5 || response[4] != SSH2_AGENT_SIGN_RESPONSE) {
110155 sfree(response);
111156 return NULL;
112157 }
113158
114- ret = snewn(resplen-5, unsigned char);
115- memcpy(ret, response+5, resplen-5);
159+ ret = snewn(response_len-5, unsigned char);
160+ memcpy(ret, response+5, response_len-5);
116161 sfree(response);
117162
118163 if (outlen)
119- *outlen = resplen-5;
164+ *outlen = response_len-5;
120165
121166 return ret;
122167 }
@@ -127,14 +172,38 @@
127172 */
128173 int putty_get_ssh1_keylist(unsigned char **keylist)
129174 {
130- int keylistlen;
175+ KeyList *kl;
176+ int keylistlen = 0;
177+ strbuf *sb_keylist = strbuf_new();
178+ size_t i;
131179
132- *keylist = get_keylist1(&keylistlen);
133- if (*keylist == NULL){
134- // 取得に失敗
135- return 0;
180+ kl = pageant_get_keylist(1);
181+ if (kl) {
182+ if (kl->broken) {
183+ keylist_free(kl);
184+ strbuf_free(sb_keylist);
185+ return 0;
186+ }
187+
188+ put_uint32(sb_keylist, kl->nkeys);
189+ keylistlen += 4;
190+ for (i = 0; i < kl->nkeys; i++) {
191+ put_data(sb_keylist, kl->keys[i].blob.ptr, kl->keys[i].blob.len);
192+ keylistlen += kl->keys[i].blob.len;
193+ put_uint32(sb_keylist, kl->keys[i].comment.len);
194+ keylistlen += 4;
195+ put_datapl(sb_keylist, kl->keys[i].comment);
196+ keylistlen += kl->keys[i].comment.len;
197+ }
198+ keylist_free(kl);
199+
200+ *keylist = strbuf_to_str(sb_keylist);
201+
202+ return keylistlen;
136203 }
137- return keylistlen;
204+
205+ strbuf_free(sb_keylist);
206+ return 0;
138207 }
139208
140209 /*
@@ -141,6 +210,7 @@
141210 * for SSH1
142211 * 公開鍵と暗号化データを渡し
143212 * 復号データのハッシュを得る
213+ * ssh1login.c (PuTTY 0.76) から再構成
144214 */
145215 void *putty_hash_ssh1_challenge(unsigned char *pubkey,
146216 int pubkeylen,
@@ -151,47 +221,31 @@
151221 {
152222 void *ret;
153223
154- unsigned char *request, *response, *p;
224+ unsigned char *response;
155225 void *vresponse;
156- int resplen;
157- int reqlen;
226+ int response_len;
227+ strbuf *agentreq = strbuf_new_for_agent_query();
158228
159- reqlen = 4 + 1 + pubkeylen + datalen + 16 + 4;
160- request = (unsigned char *)malloc(reqlen);
161- p = request;
229+ put_byte(agentreq, SSH1_AGENTC_RSA_CHALLENGE);
230+ put_data(agentreq, pubkey, pubkeylen);
231+ put_data(agentreq, data, datalen);
232+ put_data(agentreq, session_id, 16);
233+ put_uint32(agentreq, 1); // response format
234+ agent_query_synchronous(agentreq, &vresponse, &response_len);
235+ strbuf_free(agentreq);
162236
163- // request length
164- PUT_32BIT(request, reqlen);
165- // request type
166- request[4] = SSH1_AGENTC_RSA_CHALLENGE;
167- p += 5;
168-
169- // public key
170- memcpy(p, pubkey, pubkeylen);
171- p += pubkeylen;
172- // challange from server
173- memcpy(p, data, datalen);
174- p += datalen;
175- // session_id
176- memcpy(p, session_id, 16);
177- p += 16;
178- // response format
179- PUT_32BIT(p, 1);
180-
181- agent_query(request, reqlen, &vresponse, &resplen, NULL, NULL);
182-
183237 response = vresponse;
184- if (resplen < 5 || response[4] != SSH1_AGENT_RSA_RESPONSE) {
238+ if (response_len < 5+16 || response[4] != SSH1_AGENT_RSA_RESPONSE) {
185239 sfree(response);
186240 return NULL;
187241 }
188242
189- ret = snewn(resplen-5, unsigned char);
190- memcpy(ret, response+5, resplen-5);
243+ ret = snewn(response_len-5, unsigned char);
244+ memcpy(ret, response+5, response_len-5);
191245 sfree(response);
192246
193247 if (outlen)
194- *outlen = resplen-5;
248+ *outlen = response_len-5;
195249
196250 return ret;
197251 }
@@ -198,7 +252,7 @@
198252
199253 int putty_get_ssh1_keylen(unsigned char *key, int maxlen)
200254 {
201- return rsa_public_blob_len(key, maxlen);
255+ return rsa_ssh1_public_blob_len(make_ptrlen(key, maxlen));
202256 }
203257
204258 const char *putty_get_version()
@@ -207,173 +261,15 @@
207261 return ver;
208262 }
209263
210-/*
211- * Following functions are copied from putty source.
212- */
213-
214-// from SSHBN.C (ver 0.63)
215-static Bignum newbn(int length)
264+void putty_agent_query_synchronous(void *in, int inlen, void **out, int *outlen)
216265 {
217- Bignum b;
266+ strbuf *buf = strbuf_new();
218267
219- assert(length >= 0 && length < INT_MAX / BIGNUM_INT_BITS);
220-
221- b = snewn(length + 1, BignumInt);
222- if (!b)
223- abort(); /* FIXME */
224- memset(b, 0, (length + 1) * sizeof(*b));
225- b[0] = length;
226- return b;
268+ put_data(buf, in, inlen);
269+ agent_query_synchronous(buf, out, outlen);
270+ strbuf_free(buf);
227271 }
228272
229-// from SSHBN.C (ver 0.65)
230-Bignum bignum_from_bytes(const unsigned char *data, int nbytes)
231-{
232- Bignum result;
233- int w, i;
234-
235- assert(nbytes >= 0 && nbytes < INT_MAX / 8);
236-
237- w = (nbytes + BIGNUM_INT_BYTES - 1) / BIGNUM_INT_BYTES; /* bytes->words */
238-
239- result = newbn(w);
240- for (i = 1; i <= w; i++)
241- result[i] = 0;
242- for (i = nbytes; i--;) {
243- unsigned char byte = *data++;
244- result[1 + i / BIGNUM_INT_BYTES] |=
245- (BignumInt)byte << (8 * i % BIGNUM_INT_BITS);
246- }
247-
248- while (result[0] > 1 && result[result[0]] == 0)
249- result[0]--;
250- return result;
251-}
252-
253-// from SSHBN.C (ver 0.60)
254-/*
255-* Read an SSH-1-format bignum from a data buffer. Return the number
256-* of bytes consumed, or -1 if there wasn't enough data.
257-*/
258-int ssh1_read_bignum(const unsigned char *data, int len, Bignum * result)
259-{
260- const unsigned char *p = data;
261- int i;
262- int w, b;
263-
264- if (len < 2)
265- return -1;
266-
267- w = 0;
268- for (i = 0; i < 2; i++)
269- w = (w << 8) + *p++;
270- b = (w + 7) / 8; /* bits -> bytes */
271-
272- if (len < b + 2)
273- return -1;
274-
275- if (!result) /* just return length */
276- return b + 2;
277-
278- *result = bignum_from_bytes(p, b);
279-
280- return p + b - data;
281-}
282-
283-// from SSHRSA.C (putty 0.60)
284-/* Given a public blob, determine its length. */
285-int rsa_public_blob_len(void *data, int maxlen)
286-{
287- unsigned char *p = (unsigned char *)data;
288- int n;
289-
290- if (maxlen < 4)
291- return -1;
292- p += 4; /* length word */
293- maxlen -= 4;
294-
295- n = ssh1_read_bignum(p, maxlen, NULL); /* exponent */
296- if (n < 0)
297- return -1;
298- p += n;
299-
300- n = ssh1_read_bignum(p, maxlen, NULL); /* modulus */
301- if (n < 0)
302- return -1;
303- p += n;
304-
305- return p - (unsigned char *)data;
306-}
307-
308-// from WINDOWS\WINPGNT.C (putty 0.63)
309-/*
310- * Acquire a keylist1 from the primary Pageant; this means either
311- * calling make_keylist1 (if that's us) or sending a message to the
312- * primary Pageant (if it's not).
313- */
314-static void *get_keylist1(int *length)
315-{
316- void *ret;
317-
318- unsigned char request[5], *response;
319- void *vresponse;
320- int resplen;
321- request[4] = SSH1_AGENTC_REQUEST_RSA_IDENTITIES;
322- PUT_32BIT(request, 1);
323-
324- agent_query(request, 5, &vresponse, &resplen, NULL, NULL);
325-
326- response = vresponse;
327- if (resplen < 5 || response[4] != SSH1_AGENT_RSA_IDENTITIES_ANSWER) {
328- sfree(response);
329- return NULL;
330- }
331-
332- ret = snewn(resplen-5, unsigned char);
333- memcpy(ret, response+5, resplen-5);
334- sfree(response);
335-
336- if (length)
337- *length = resplen-5;
338-
339- return ret;
340-}
341-
342-// from WINDOWS\WINPGNT.C (putty 0.63)
343-/*
344- * Acquire a keylist2 from the primary Pageant; this means either
345- * calling make_keylist2 (if that's us) or sending a message to the
346- * primary Pageant (if it's not).
347- */
348-static void *get_keylist2(int *length)
349-{
350- void *ret;
351-
352- unsigned char request[5], *response;
353- void *vresponse;
354- int resplen;
355-
356- request[4] = SSH2_AGENTC_REQUEST_IDENTITIES;
357- PUT_32BIT(request, 1);
358-
359- agent_query(request, 5, &vresponse, &resplen, NULL, NULL);
360-
361- response = vresponse;
362- if (resplen < 5 || response[4] != SSH2_AGENT_IDENTITIES_ANSWER) {
363- sfree(response);
364- return NULL;
365- }
366-
367- ret = snewn(resplen-5, unsigned char);
368- memcpy(ret, response+5, resplen-5);
369- sfree(response);
370-
371- if (length)
372- *length = resplen-5;
373-
374- return ret;
375-}
376-
377273 BOOL putty_agent_exists()
378274 {
379275 if (agent_exists()) {
@@ -382,20 +278,3 @@
382278 return FALSE;
383279 }
384280
385-// from WINDOWS\WINDOW.C (putty 0.60)
386-/*
387- * Print a modal (Really Bad) message box and perform a fatal exit.
388- */
389-void modalfatalbox(char *fmt, ...)
390-{
391- va_list ap;
392- char *stuff, morestuff[100];
393-
394- va_start(ap, fmt);
395- stuff = dupvprintf(fmt, ap);
396- va_end(ap);
397- sprintf(morestuff, "%.70s Fatal Error", "TTSSH");
398- MessageBox(NULL, stuff, morestuff,
399- MB_SYSTEMMODAL | MB_ICONERROR | MB_OK);
400- sfree(stuff);
401-}
--- branches/putty_0_76/ttssh2/putty/libputty.h (revision 9625)
+++ branches/putty_0_76/ttssh2/putty/libputty.h (revision 9626)
@@ -25,24 +25,8 @@
2525 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2727 */
28-// PuTTY is copyright 1997-2007 Simon Tatham.
28+// PuTTY is copyright 1997-2021 Simon Tatham.
2929
30-// pageant.h
31-// 本当は pageant.h を include 出来るようにする方がいいのかもしれないけれど
32-// 関数のプロトタイプ宣言もここにあるので取りあえずここで。
33-#define AGENT_MAX_MSGLEN 8192
34-
35-// エラー応答用
36-#define SSH_AGENT_FAILURE_MSG "\x00\x00\x00\x01\x05"
37-
38-// MISC.C
39-extern void safefree(void *);
40-
41-// WINDOWS\WINPGNTC.C
42-extern int agent_exists(void);
43-extern void *agent_query(void *in, int inlen, void **out, int *outlen,
44- void (*callback)(void *, void *, int), void *callback_ctx);
45-
4630 int putty_get_ssh2_keylist(unsigned char **keylist);
4731 void *putty_sign_ssh2_key(unsigned char *pubkey,
4832 unsigned char *data,
@@ -57,7 +41,16 @@
5741 int *outlen);
5842 int putty_get_ssh1_keylen(unsigned char *key, int maxlen);
5943 const char *putty_get_version();
44+void putty_agent_query_synchronous(void *in, int inlen, void **out, int *outlen);
6045 BOOL putty_agent_exists();
6146
62-static void *get_keylist1(int *length);
63-static void *get_keylist2(int *length);
47+// エラー応答用
48+#define SSH_AGENT_FAILURE_MSG "\x00\x00\x00\x01\x05"
49+
50+// pageant.h
51+#define AGENT_MAX_MSGLEN 262144
52+
53+// puttymen.h
54+// memory.c
55+extern void safefree(void *);
56+
--- branches/putty_0_76/ttssh2/putty/putty-import.c (nonexistent)
+++ branches/putty_0_76/ttssh2/putty/putty-import.c (revision 9626)
@@ -0,0 +1,446 @@
1+/*
2+ * Copyright (C) 1994-1998 T. Teranishi
3+ * (C) 2004- TeraTerm Project
4+ * All rights reserved.
5+ *
6+ * Redistribution and use in source and binary forms, with or without
7+ * modification, are permitted provided that the following conditions
8+ * are met:
9+ *
10+ * 1. Redistributions of source code must retain the above copyright
11+ * notice, this list of conditions and the following disclaimer.
12+ * 2. Redistributions in binary form must reproduce the above copyright
13+ * notice, this list of conditions and the following disclaimer in the
14+ * documentation and/or other materials provided with the distribution.
15+ * 3. The name of the author may not be used to endorse or promote products
16+ * derived from this software without specific prior written permission.
17+ *
18+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+ */
29+// PuTTY is copyright 1997-2021 Simon Tatham.
30+
31+/*
32+ * ソース全体をそのままプロジェクトに追加すると、
33+ * 使わない部分で依存先が増え、さらにその依存先が増えたり競合が起きるので、
34+ * PuTTY のソースからコピーしてきたコード
35+ */
36+
37+#include <stdio.h>
38+#include <stdlib.h>
39+#include <string.h>
40+#include <assert.h>
41+
42+#include "ssh.h"
43+#include "mpint.h"
44+#include "putty.h"
45+#include "network.h"
46+#include "sshcr.h"
47+#include "pageant.h"
48+
49+
50+// from pageant.c (PuTTY 0.76)
51+#define DECL_EXT_ENUM(id, name) id,
52+enum Extension { KNOWN_EXTENSIONS(DECL_EXT_ENUM) EXT_UNKNOWN };
53+#define DEF_EXT_NAMES(id, name) PTRLEN_DECL_LITERAL(name),
54+static const ptrlen extension_names[] = { KNOWN_EXTENSIONS(DEF_EXT_NAMES) };
55+
56+// from pageant.c (PuTTY 0.76)
57+typedef struct PageantClientOp {
58+ strbuf *buf;
59+ bool request_made;
60+ BinarySink_DELEGATE_IMPLEMENTATION;
61+ BinarySource_IMPLEMENTATION;
62+} PageantClientOp;
63+
64+// from pageant.c (PuTTY 0.76)
65+typedef struct KeyListEntry {
66+ ptrlen blob, comment;
67+ uint32_t flags;
68+} KeyListEntry;
69+
70+// from pageant.c (PuTTY 0.76)
71+typedef struct KeyList {
72+ strbuf *raw_data;
73+ KeyListEntry *keys;
74+ size_t nkeys;
75+ bool broken;
76+} KeyList;
77+
78+// from pageant.c (PuTTY 0.76)
79+static PageantClientOp *pageant_client_op_new(void)
80+{
81+ PageantClientOp *pco = snew(PageantClientOp);
82+ pco->buf = strbuf_new_for_agent_query();
83+ pco->request_made = false;
84+ BinarySink_DELEGATE_INIT(pco, pco->buf);
85+ BinarySource_INIT(pco, "", 0);
86+ return pco;
87+}
88+
89+// from pageant.c (PuTTY 0.76)
90+static void pageant_client_op_free(PageantClientOp *pco)
91+{
92+ if (pco->buf)
93+ strbuf_free(pco->buf);
94+ sfree(pco);
95+}
96+
97+// from pageant.c (PuTTY 0.76)
98+static unsigned pageant_client_op_query(PageantClientOp *pco)
99+{
100+ /* Since we use the same strbuf for the request and the response,
101+ * check by assertion that we aren't embarrassingly sending a
102+ * previous response back to the agent */
103+ assert(!pco->request_made);
104+ pco->request_made = true;
105+
106+ void *response_raw;
107+ int resplen_raw;
108+ agent_query_synchronous(pco->buf, &response_raw, &resplen_raw);
109+ strbuf_clear(pco->buf);
110+ put_data(pco->buf, response_raw, resplen_raw);
111+ sfree(response_raw);
112+
113+ /* The data coming back from agent_query_synchronous will have
114+ * its length field prepended. So we start by parsing it as an
115+ * SSH-formatted string, and then reinitialise our
116+ * BinarySource with the interior of that string. */
117+ BinarySource_INIT_PL(pco, ptrlen_from_strbuf(pco->buf));
118+ BinarySource_INIT_PL(pco, get_string(pco));
119+
120+ /* Strip off and directly return the type byte, which every client
121+ * will need, to save a boilerplate get_byte at each call site */
122+ unsigned reply_type = get_byte(pco);
123+ if (get_err(pco))
124+ reply_type = 256; /* out-of-range code */
125+ return reply_type;
126+}
127+
128+// from pageant.c (PuTTY 0.76)
129+void keylist_free(KeyList *kl)
130+{
131+ sfree(kl->keys);
132+ strbuf_free(kl->raw_data);
133+ sfree(kl);
134+}
135+
136+// from pageant.c (PuTTY 0.76)
137+static PageantClientOp *pageant_request_keylist_1(void)
138+{
139+ PageantClientOp *pco = pageant_client_op_new();
140+ put_byte(pco, SSH1_AGENTC_REQUEST_RSA_IDENTITIES);
141+ if (pageant_client_op_query(pco) == SSH1_AGENT_RSA_IDENTITIES_ANSWER)
142+ return pco;
143+ pageant_client_op_free(pco);
144+ return NULL;
145+}
146+
147+// from pageant.c (PuTTY 0.76)
148+static PageantClientOp *pageant_request_keylist_2(void)
149+{
150+ PageantClientOp *pco = pageant_client_op_new();
151+ put_byte(pco, SSH2_AGENTC_REQUEST_IDENTITIES);
152+ if (pageant_client_op_query(pco) == SSH2_AGENT_IDENTITIES_ANSWER)
153+ return pco;
154+ pageant_client_op_free(pco);
155+ return NULL;
156+}
157+
158+// from pageant.c (PuTTY 0.76)
159+static PageantClientOp *pageant_request_keylist_extended(void)
160+{
161+ PageantClientOp *pco = pageant_client_op_new();
162+ put_byte(pco, SSH2_AGENTC_EXTENSION);
163+ put_stringpl(pco, extension_names[EXT_LIST_EXTENDED]);
164+ if (pageant_client_op_query(pco) == SSH_AGENT_SUCCESS)
165+ return pco;
166+ pageant_client_op_free(pco);
167+ return NULL;
168+}
169+
170+// from pageant.c (PuTTY 0.76)
171+KeyList *pageant_get_keylist(unsigned ssh_version)
172+{
173+ PageantClientOp *pco;
174+ bool list_is_extended = false;
175+
176+ if (ssh_version == 1) {
177+ pco = pageant_request_keylist_1();
178+ } else {
179+ if ((pco = pageant_request_keylist_extended()) != NULL)
180+ list_is_extended = true;
181+ else
182+ pco = pageant_request_keylist_2();
183+ }
184+
185+ if (!pco)
186+ return NULL;
187+
188+ KeyList *kl = snew(KeyList);
189+ kl->nkeys = get_uint32(pco);
190+ kl->keys = snewn(kl->nkeys, struct KeyListEntry);
191+ kl->broken = false;
192+
193+ for (size_t i = 0; i < kl->nkeys && !get_err(pco); i++) {
194+ if (ssh_version == 1) {
195+ int bloblen = rsa_ssh1_public_blob_len(
196+ make_ptrlen(get_ptr(pco), get_avail(pco)));
197+ if (bloblen < 0) {
198+ kl->broken = true;
199+ bloblen = 0;
200+ }
201+ kl->keys[i].blob = get_data(pco, bloblen);
202+ } else {
203+ kl->keys[i].blob = get_string(pco);
204+ }
205+ kl->keys[i].comment = get_string(pco);
206+
207+ if (list_is_extended) {
208+ ptrlen key_ext_info = get_string(pco);
209+ BinarySource src[1];
210+ BinarySource_BARE_INIT_PL(src, key_ext_info);
211+
212+ kl->keys[i].flags = get_uint32(src);
213+ } else {
214+ kl->keys[i].flags = 0;
215+ }
216+ }
217+
218+ if (get_err(pco))
219+ kl->broken = true;
220+ kl->raw_data = pco->buf;
221+ pco->buf = NULL;
222+ pageant_client_op_free(pco);
223+ return kl;
224+}
225+
226+// from sshrsa.c (PuTTY 0.76)
227+/* Given an SSH-1 public key blob, determine its length. */
228+int rsa_ssh1_public_blob_len(ptrlen data)
229+{
230+ BinarySource src[1];
231+
232+ BinarySource_BARE_INIT_PL(src, data);
233+
234+ /* Expect a length word, then exponent and modulus. (It doesn't
235+ * even matter which order.) */
236+ get_uint32(src);
237+ mp_free(get_mp_ssh1(src));
238+ mp_free(get_mp_ssh1(src));
239+
240+ if (get_err(src))
241+ return -1;
242+
243+ /* Return the number of bytes consumed. */
244+ return src->pos;
245+}
246+
247+// from windows/winmiscs.c (PuTTY 0.76)
248+/*
249+ * Windows implementation of smemclr (see misc.c) using SecureZeroMemory.
250+ */
251+void smemclr(void *b, size_t n) {
252+ if (b && n > 0)
253+ SecureZeroMemory(b, n);
254+}
255+
256+// from be_misc.c (PuTTY 0.76)
257+void log_proxy_stderr(Plug *plug, ProxyStderrBuf *psb,
258+ const void *vdata, size_t len)
259+{
260+ const char *data = (const char *)vdata;
261+
262+ /*
263+ * This helper function allows us to collect the data written to a
264+ * local proxy command's standard error in whatever size chunks we
265+ * happen to get from its pipe, and whenever we have a complete
266+ * line, we pass it to plug_log.
267+ *
268+ * (We also do this when the buffer in psb fills up, to avoid just
269+ * allocating more and more memory forever, and also to keep Event
270+ * Log lines reasonably bounded in size.)
271+ *
272+ * Prerequisites: a plug to log to, and a ProxyStderrBuf stored
273+ * somewhere to collect any not-yet-output partial line.
274+ */
275+
276+ while (len > 0) {
277+ /*
278+ * Copy as much data into psb->buf as will fit.
279+ */
280+ assert(psb->size < lenof(psb->buf));
281+ size_t to_consume = lenof(psb->buf) - psb->size;
282+ if (to_consume > len)
283+ to_consume = len;
284+ memcpy(psb->buf + psb->size, data, to_consume);
285+ data += to_consume;
286+ len -= to_consume;
287+ psb->size += to_consume;
288+
289+ /*
290+ * Output any full lines in psb->buf.
291+ */
292+ size_t pos = 0;
293+ while (pos < psb->size) {
294+ char *nlpos = memchr(psb->buf + pos, '\n', psb->size - pos);
295+ if (!nlpos)
296+ break;
297+
298+ /*
299+ * Found a newline in the buffer, so we can output a line.
300+ */
301+ size_t endpos = nlpos - psb->buf;
302+ while (endpos > pos && (psb->buf[endpos-1] == '\n' ||
303+ psb->buf[endpos-1] == '\r'))
304+ endpos--;
305+ char *msg = dupprintf(
306+ "proxy: %.*s", (int)(endpos - pos), psb->buf + pos);
307+ plug_log(plug, PLUGLOG_PROXY_MSG, NULL, 0, msg, 0);
308+ sfree(msg);
309+
310+ pos = nlpos - psb->buf + 1;
311+ assert(pos <= psb->size);
312+ }
313+
314+ /*
315+ * If the buffer is completely full and we didn't output
316+ * anything, then output the whole thing, flagging it as a
317+ * truncated line.
318+ */
319+ if (pos == 0 && psb->size == lenof(psb->buf)) {
320+ char *msg = dupprintf(
321+ "proxy (partial line): %.*s", (int)psb->size, psb->buf);
322+ plug_log(plug, PLUGLOG_PROXY_MSG, NULL, 0, msg, 0);
323+ sfree(msg);
324+
325+ pos = psb->size = 0;
326+ }
327+
328+ /*
329+ * Now move any remaining data up to the front of the buffer.
330+ */
331+ size_t newsize = psb->size - pos;
332+ if (newsize)
333+ memmove(psb->buf, psb->buf + pos, newsize);
334+ psb->size = newsize;
335+
336+ /*
337+ * And loop round again if there's more data to be read from
338+ * our input.
339+ */
340+ }
341+}
342+
343+// from be_misc.c (PuTTY 0.76)
344+void psb_init(ProxyStderrBuf *psb)
345+{
346+ psb->size = 0;
347+}
348+
349+// from windows/winpgnt.c (PuTTY 0.76)
350+void noise_ultralight(NoiseSourceId id, unsigned long data)
351+{
352+ /* Pageant doesn't use random numbers, so we ignore this */
353+}
354+
355+// from windows/window.c (PuTTY 0.76)
356+/*
357+ * Print a modal (Really Bad) message box and perform a fatal exit.
358+ */
359+void modalfatalbox(const char *fmt, ...)
360+{
361+ va_list ap;
362+ char *message, *title;
363+
364+ va_start(ap, fmt);
365+ message = dupvprintf(fmt, ap);
366+ va_end(ap);
367+ title = dupprintf("%s Fatal Error", "TTSSH");
368+ MessageBox(NULL, message, title,
369+ MB_SYSTEMMODAL | MB_ICONERROR | MB_OK);
370+ sfree(message);
371+ sfree(title);
372+}
373+
374+// from misc.c (PuTTY 0.76)
375+void out_of_memory(void)
376+{
377+ modalfatalbox("Out of memory");
378+}
379+
380+
381+/*
382+putty_get_ssh1_keylen()@libputty.c
383+ rsa_ssh1_public_blob_len()@sshrsa.c ... import
384+
385+memory.c / mpint.c / utils.c
386+ smemclr()@windows/winmiscs.c ... import
387+
388+safemalloc()@memory.c
389+ out_of_memory()@misc.c ... import
390+ modalfatalbox()@windows/window.c ... import
391+
392+wm_copydata_agent_query()@windows\winpgnt.c
393+ got_advapi()@windows\winsecur.c ... include winsecur.c
394+
395+agent_named_pipe_name()@windows\winpgnt.c
396+ get_username()@windows\winmisc.c ... include winmisc.c
397+
398+agent_connect()@windows\winpgnt.c
399+ new_named_pipe_client()@winnpc.c ... include winnpc.c
400+ connect_to_named_pipe()@winnpc.c
401+ new_error_socket_consume_string()@errsock.c ... include errsock.c
402+ make_handle_socket()@winsocket.c ... include winsocket.c
403+ handle_input_new()@winhandl.c ... include winhandl.c
404+ handle_output_new()@winhandl.c
405+ psb_init()@be_misc.c ... import
406+ handle_stderr()@winhsock.c
407+ log_proxy_stderr()@be_misc.c ... import
408+
409+agent_named_pipe_name()@windows\winpgnt.c
410+ capi_obfuscate_string()@windows\wincapi.c ... include wincapi.c
411+ ssh_sha256@sshsh256.c ... include sshsh256.c
412+
413+handle_got_event()@windows\winhandl.c
414+ noise_ultralight()@windows/winpgnt.c
415+
416+sk_handle_set_frozen()@windows\winhsock.c
417+ queue_toplevel_callback()@callback.c ... include callback.c
418+sk_handle_close()@windows\winhsock.c
419+ delete_callbacks_for_context()@callback.c
420+
421+winmisc.c refers to tree234 ... include tree234.c
422+
423+
424+
425+if include be_misc.c ...
426+backend_socket_log()@be_misc.c
427+ sk_getaddr()@windows\winnet.c
428+ sk_addr_needs_port()@windows\winnet.c
429+ conf_get_int()@conf.c
430+ logevent()@logging.c
431+
432+if include sshrsa.c ...
433+rsa_components()@sshrsa.c
434+ key_components_new()@sshpubk.c
435+ key_components_add_text()@sshpubk.c
436+ key_components_add_mp()@sshpubk.c
437+ssh_rsakex_encrypt()@sshrsa.c
438+ hash_simple()@sshauxcrypt.c
439+ssh_rsakex_decrypt()@sshrsa.c
440+ hash_simple()@sshauxcrypt.c
441+rsa_ssh1_encrypt()@sshrsa.c
442+ random_read()@sshrand.c
443+
444+if include sshauxcropt.c ...
445+mac_simple()@sshauxcropt.c coflicts mac_simple()@keyfiles-putty.c
446+*/
--- branches/putty_0_76/ttssh2/ttxssh/ssh.c (revision 9625)
+++ branches/putty_0_76/ttssh2/ttxssh/ssh.c (revision 9626)
@@ -9503,9 +9503,9 @@
95039503 data = agent_msg->buf;
95049504 }
95059505
9506- agent_query(data, *agent_request_len, &response, &resplen, NULL, NULL);
9506+ putty_agent_query_synchronous(data, *agent_request_len, &response, &resplen);
95079507 if (response == NULL || resplen < 5) {
9508- logprintf(LOG_LEVEL_NOTICE, "%s Agent Forwarding Error: agent_query is failed.", __FUNCTION__);
9508+ logprintf(LOG_LEVEL_NOTICE, "%s Agent Forwarding Error: putty_agent_query_synchronous is failed.", __FUNCTION__);
95099509 goto error;
95109510 }
95119511
Show on old repository browser