PageRenderTime 54ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/portage/win32libs/libssh/0001-implement-support-for-putty-s-pageant.patch

https://gitlab.com/brcha/emerge
Patch | 489 lines | 451 code | 38 blank | 0 comment | 0 complexity | 365bc3736fbeb3966f6eac38e05829e2 MD5 | raw file
  1. From 3608d35c272326e5b513cda7d963752c297eb04a Mon Sep 17 00:00:00 2001
  2. From: Patrick Spendrin <ps_ml@gmx.de>
  3. Date: Wed, 1 Feb 2012 15:20:50 +0100
  4. Subject: [PATCH 1/2] implement support for putty's pageant
  5. ---
  6. include/libssh/agent.h | 2 -
  7. src/CMakeLists.txt | 6 +++
  8. src/agent.c | 74 ++++++++++++++++++++++++++++----
  9. src/auth.c | 4 --
  10. src/keys.c | 2 -
  11. src/session.c | 4 --
  12. src/winpgntc.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++
  13. src/winpgntc.h | 34 +++++++++++++++
  14. 8 files changed, 211 insertions(+), 22 deletions(-)
  15. create mode 100644 src/winpgntc.c
  16. create mode 100644 src/winpgntc.h
  17. diff --git a/include/libssh/agent.h b/include/libssh/agent.h
  18. index b620b33..e877466 100644
  19. --- a/include/libssh/agent.h
  20. +++ b/include/libssh/agent.h
  21. @@ -53,7 +53,6 @@ struct ssh_agent_struct {
  22. unsigned int count;
  23. };
  24. -#ifndef _WIN32
  25. /* agent.c */
  26. /**
  27. * @brief Create a new ssh agent structure.
  28. @@ -91,7 +90,6 @@ struct ssh_public_key_struct *agent_get_first_ident(struct ssh_session_struct *s
  29. ssh_string agent_sign_data(struct ssh_session_struct *session,
  30. struct ssh_buffer_struct *data,
  31. struct ssh_public_key_struct *pubkey);
  32. -#endif
  33. #endif /* __AGENT_H */
  34. /* vim: set ts=2 sw=2 et cindent: */
  35. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
  36. index e158665..ffc7a10 100644
  37. --- a/src/CMakeLists.txt
  38. +++ b/src/CMakeLists.txt
  39. @@ -113,6 +113,12 @@ set(libssh_SRCS
  40. threads.c
  41. wrapper.c
  42. )
  43. +if (WIN32)
  44. + set(libssh_SRCS
  45. + ${libssh_SRCS}
  46. + winpgntc.c
  47. + )
  48. +endif (WIN32)
  49. if (WITH_SFTP)
  50. set(libssh_SRCS
  51. diff --git a/src/agent.c b/src/agent.c
  52. index a457d5e..66cb6ca 100644
  53. --- a/src/agent.c
  54. +++ b/src/agent.c
  55. @@ -34,32 +34,39 @@
  56. * the agent returns the signed data
  57. */
  58. -#ifndef _WIN32
  59. -
  60. #include <stdlib.h>
  61. #include <errno.h>
  62. #include <string.h>
  63. #include <stdio.h>
  64. +#ifdef _WIN32
  65. +#include <winsock2.h>
  66. +#include <windows.h>
  67. +#else
  68. #include <unistd.h>
  69. -
  70. -#ifndef _WIN32
  71. #include <arpa/inet.h>
  72. #endif
  73. #include "libssh/agent.h"
  74. -#include "libssh/priv.h"
  75. -#include "libssh/socket.h"
  76. #include "libssh/buffer.h"
  77. #include "libssh/session.h"
  78. #include "libssh/keys.h"
  79. +#ifndef _WIN32
  80. +#include "libssh/priv.h"
  81. +#include "libssh/socket.h"
  82. #include "libssh/poll.h"
  83. -
  84. +#else
  85. +#include "winpgntc.h"
  86. +#endif
  87. /* macro to check for "agent failure" message */
  88. #define agent_failed(x) \
  89. (((x) == SSH_AGENT_FAILURE) || ((x) == SSH_COM_AGENT2_FAILURE) || \
  90. ((x) == SSH2_AGENT_FAILURE))
  91. +#ifdef _WIN32
  92. +#define AGENT_COPYDATA_ID 0x804e50ba /* random goop */
  93. +#endif
  94. +
  95. static uint32_t agent_get_u32(const void *vp) {
  96. const uint8_t *p = (const uint8_t *)vp;
  97. uint32_t v;
  98. @@ -81,6 +88,7 @@ static void agent_put_u32(void *vp, uint32_t v) {
  99. p[3] = (uint8_t)v & 0xff;
  100. }
  101. +#ifndef _WIN32
  102. static size_t atomicio(ssh_socket s, void *buf, size_t n, int do_read) {
  103. char *b = buf;
  104. size_t pos = 0;
  105. @@ -121,6 +129,7 @@ static size_t atomicio(ssh_socket s, void *buf, size_t n, int do_read) {
  106. return pos;
  107. }
  108. +#endif
  109. ssh_agent agent_new(struct ssh_session_struct *session) {
  110. ssh_agent agent = NULL;
  111. @@ -132,16 +141,19 @@ ssh_agent agent_new(struct ssh_session_struct *session) {
  112. ZERO_STRUCTP(agent);
  113. agent->count = 0;
  114. +#ifndef _WIN32
  115. agent->sock = ssh_socket_new(session);
  116. if (agent->sock == NULL) {
  117. SAFE_FREE(agent);
  118. return NULL;
  119. }
  120. +#endif
  121. return agent;
  122. }
  123. void agent_close(struct ssh_agent_struct *agent) {
  124. +#ifndef _WIN32
  125. if (agent == NULL) {
  126. return;
  127. }
  128. @@ -149,6 +161,7 @@ void agent_close(struct ssh_agent_struct *agent) {
  129. if (getenv("SSH_AUTH_SOCK")) {
  130. ssh_socket_close(agent->sock);
  131. }
  132. +#endif
  133. }
  134. void agent_free(ssh_agent agent) {
  135. @@ -156,15 +169,18 @@ void agent_free(ssh_agent agent) {
  136. if (agent->ident) {
  137. ssh_buffer_free(agent->ident);
  138. }
  139. +#ifndef _WIN32
  140. if (agent->sock) {
  141. agent_close(agent);
  142. ssh_socket_free(agent->sock);
  143. }
  144. +#endif
  145. SAFE_FREE(agent);
  146. }
  147. }
  148. static int agent_connect(ssh_session session) {
  149. +#ifndef _WIN32
  150. const char *auth_sock = NULL;
  151. if (session == NULL || session->agent == NULL) {
  152. @@ -181,6 +197,9 @@ static int agent_connect(ssh_session session) {
  153. }
  154. return -1;
  155. +#else
  156. + return 0;
  157. +#endif
  158. }
  159. #if 0
  160. @@ -205,6 +224,7 @@ static int agent_decode_reply(struct ssh_session_struct *session, int type) {
  161. static int agent_talk(struct ssh_session_struct *session,
  162. struct ssh_buffer_struct *request, struct ssh_buffer_struct *reply) {
  163. +#ifndef _WIN32
  164. uint32_t len = 0;
  165. uint8_t payload[1024] = {0};
  166. @@ -259,7 +279,39 @@ static int agent_talk(struct ssh_session_struct *session,
  167. }
  168. len -= n;
  169. }
  170. +#else
  171. + uint32_t inlen = 0, outlen = 0, i = 0;
  172. + uint8_t payload[1024] = {0};
  173. + uint8_t outload[1024] = {0};
  174. + uint8_t *t = outload;
  175. +
  176. + inlen = buffer_get_len(request);
  177. + ssh_log(session, SSH_LOG_PACKET, "agent_talk - len of request: %u", inlen);
  178. + agent_put_u32(payload, inlen);
  179. +
  180. + /* FIXME: make a clean copy here */
  181. + for(i = 0; i < inlen; i++) {
  182. + if(i == 1024) exit(1);
  183. + payload[i+4] = request->data[i];
  184. + }
  185. + agent_query((void*)payload, inlen + 4, &t, &outlen);
  186. +
  187. + if (outlen > 256 * 1024) {
  188. + ssh_set_error(session, SSH_FATAL,
  189. + "Authentication response too long: %u", outlen);
  190. + return -1;
  191. + }
  192. + ssh_log(session, SSH_LOG_PACKET, "agent_talk - response length: %u", outlen);
  193. +
  194. + outlen = outlen + 4;
  195. + /* the first 4 bytes are the size of the buffer */
  196. + if (buffer_add_data(reply, (t + 4), outlen) < 0) {
  197. + ssh_log(session, SSH_LOG_FUNCTIONS,
  198. + "Not enough space");
  199. + return -1;
  200. + }
  201. +#endif
  202. return 0;
  203. }
  204. @@ -483,7 +535,7 @@ int agent_is_running(ssh_session session) {
  205. if (session == NULL || session->agent == NULL) {
  206. return 0;
  207. }
  208. -
  209. +#ifndef _WIN32
  210. if (ssh_socket_is_open(session->agent->sock)) {
  211. return 1;
  212. } else {
  213. @@ -494,9 +546,11 @@ int agent_is_running(ssh_session session) {
  214. }
  215. }
  216. +#else
  217. + if(FindWindow(TEXT("Pageant"), TEXT("Pageant")))
  218. + return 1;
  219. +#endif
  220. return 0;
  221. }
  222. -#endif /* _WIN32 */
  223. -
  224. /* vim: set ts=2 sw=2 et cindent: */
  225. diff --git a/src/auth.c b/src/auth.c
  226. index 009340f..3fbd133 100644
  227. --- a/src/auth.c
  228. +++ b/src/auth.c
  229. @@ -812,7 +812,6 @@ error:
  230. return rc;
  231. }
  232. -#ifndef _WIN32
  233. /**
  234. * @brief Try to authenticate through public key with an ssh agent.
  235. *
  236. @@ -945,7 +944,6 @@ error:
  237. leave_function();
  238. return rc;
  239. }
  240. -#endif /* _WIN32 */
  241. /**
  242. * @brief Try to authenticate by password.
  243. @@ -1127,7 +1125,6 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
  244. }
  245. /* Try authentication with ssh-agent first */
  246. -#ifndef _WIN32
  247. if (agent_is_running(session)) {
  248. char *privkey_file = NULL;
  249. @@ -1188,7 +1185,6 @@ int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
  250. publickey_free(pubkey);
  251. } /* for each privkey */
  252. } /* if agent is running */
  253. -#endif
  254. for (it = ssh_list_get_iterator(session->identity);
  255. diff --git a/src/keys.c b/src/keys.c
  256. index de6b8f2..d6a2d9b 100644
  257. --- a/src/keys.c
  258. +++ b/src/keys.c
  259. @@ -1125,7 +1125,6 @@ static ssh_string RSA_do_sign(const unsigned char *payload, int len, RSA *privke
  260. }
  261. #endif
  262. -#ifndef _WIN32
  263. ssh_string ssh_do_sign_with_agent(ssh_session session,
  264. struct ssh_buffer_struct *buf, struct ssh_public_key_struct *publickey) {
  265. struct ssh_buffer_struct *sigbuf = NULL;
  266. @@ -1172,7 +1171,6 @@ ssh_string ssh_do_sign_with_agent(ssh_session session,
  267. return signature;
  268. }
  269. -#endif /* _WIN32 */
  270. /*
  271. * This function concats in a buffer the values needed to do a signature
  272. diff --git a/src/session.c b/src/session.c
  273. index 121a629..edf49a9 100644
  274. --- a/src/session.c
  275. +++ b/src/session.c
  276. @@ -101,12 +101,10 @@ ssh_session ssh_new(void) {
  277. session->ssh1 = 0;
  278. #endif
  279. -#ifndef _WIN32
  280. session->agent = agent_new(session);
  281. if (session->agent == NULL) {
  282. goto err;
  283. }
  284. -#endif /* _WIN32 */
  285. session->identity = ssh_list_new();
  286. if (session->identity == NULL) {
  287. @@ -193,9 +191,7 @@ void ssh_free(ssh_session session) {
  288. }
  289. ssh_list_free(session->channels);
  290. session->channels=NULL;
  291. -#ifndef _WIN32
  292. agent_free(session->agent);
  293. -#endif /* _WIN32 */
  294. if (session->client_kex.methods) {
  295. for (i = 0; i < 10; i++) {
  296. SAFE_FREE(session->client_kex.methods[i]);
  297. diff --git a/src/winpgntc.c b/src/winpgntc.c
  298. new file mode 100644
  299. index 0000000..03abad4
  300. --- /dev/null
  301. +++ b/src/winpgntc.c
  302. @@ -0,0 +1,107 @@
  303. +/*
  304. + * winpgntc.c - interact with pageant on windows
  305. + *
  306. + * This file is part of the SSH Library
  307. + *
  308. + * Copyright (c) 2012 Patrick Spendrin <ps_ml@gmx.de>
  309. + *
  310. + * The SSH Library is free software; you can redistribute it and/or modify
  311. + * it under the terms of the GNU Lesser General Public License as published by
  312. + * the Free Software Foundation; either version 2.1 of the License, or (at your
  313. + * option) any later version.
  314. + *
  315. + * The SSH Library is distributed in the hope that it will be useful, but
  316. + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  317. + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  318. + * License for more details.
  319. + *
  320. + * You should have received a copy of the GNU Lesser General Public License
  321. + * along with the SSH Library; see the file COPYING. If not, write to
  322. + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  323. + * MA 02111-1307, USA.
  324. + */
  325. +
  326. +/* This file is based on the winpgntc.c from Putty sources:
  327. + PuTTY is copyright 1997-2012 Simon Tatham.
  328. +
  329. + Portions copyright Robert de Bath, Joris van Rantwijk, Delian Delchev,
  330. + Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry, Justin
  331. + Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus Kuhn, Colin
  332. + Watson, and CORE SDI S.A.
  333. +
  334. + Permission is hereby granted, free of charge, to any person obtaining a
  335. + copy of this software and associated documentation files (the "Software"),
  336. + to deal in the Software without restriction, including without limitation
  337. + the rights to use, copy, modify, merge, publish, distribute, sublicense,
  338. + and/or sell copies of the Software, and to permit persons to whom the
  339. + Software is furnished to do so, subject to the following conditions:
  340. +
  341. + The above copyright notice and this permission notice shall be included in
  342. + all copies or substantial portions of the Software.
  343. +
  344. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  345. + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  346. + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  347. + SIMON TATHAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  348. + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  349. + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  350. +
  351. +#include <stdio.h>
  352. +#include <stdlib.h>
  353. +
  354. +#include "libssh/agent.h"
  355. +
  356. +#define AGENT_COPYDATA_ID 0x804e50ba /* random goop */
  357. +#define AGENT_MAX_MSGLEN 8192
  358. +
  359. +#define GET_32BIT(cp) \
  360. + (((unsigned long)(unsigned char)(cp)[0] << 24) | \
  361. + ((unsigned long)(unsigned char)(cp)[1] << 16) | \
  362. + ((unsigned long)(unsigned char)(cp)[2] << 8) | \
  363. + ((unsigned long)(unsigned char)(cp)[3]))
  364. +
  365. +int agent_query(void *in, int inlen, void **out, int *outlen)
  366. +{
  367. + HWND hwnd;
  368. + char mapname[25];
  369. + HANDLE filemap;
  370. + unsigned char *p, *ret;
  371. + int id, retlen;
  372. + COPYDATASTRUCT cds;
  373. +
  374. + *out = NULL;
  375. + *outlen = 0;
  376. +
  377. + hwnd = FindWindow("Pageant", "Pageant");
  378. + if (!hwnd)
  379. + return 1; /* *out == NULL, so failure */
  380. + sprintf(mapname, "PageantRequest%08x", (unsigned)GetCurrentThreadId());
  381. + filemap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
  382. + 0, AGENT_MAX_MSGLEN, mapname);
  383. + if (filemap == NULL || filemap == INVALID_HANDLE_VALUE)
  384. + return 1; /* *out == NULL, so failure */
  385. + p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
  386. + memcpy(p, in, inlen);
  387. + cds.dwData = AGENT_COPYDATA_ID;
  388. + cds.cbData = 1 + strlen(mapname);
  389. + cds.lpData = mapname;
  390. +
  391. + /*
  392. + * The user either passed a null callback (indicating that the
  393. + * query is required to be synchronous) or CreateThread failed.
  394. + * Either way, we need a synchronous request.
  395. + */
  396. + id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds);
  397. + if (id > 0) {
  398. + retlen = 4 + GET_32BIT(p);
  399. + ret = (unsigned char *)malloc(retlen*sizeof(unsigned char));
  400. + if (ret) {
  401. + memcpy(ret, p, retlen);
  402. + *out = ret;
  403. + *outlen = retlen;
  404. + }
  405. + }
  406. + UnmapViewOfFile(p);
  407. + CloseHandle(filemap);
  408. + return 1;
  409. +}
  410. diff --git a/src/winpgntc.h b/src/winpgntc.h
  411. new file mode 100644
  412. index 0000000..2bf3302
  413. --- /dev/null
  414. +++ b/src/winpgntc.h
  415. @@ -0,0 +1,34 @@
  416. +/*
  417. + * winpgntc.h - interact with pageant on windows
  418. + *
  419. + * This file is part of the SSH Library
  420. + *
  421. + * Copyright (c) 2012 Patrick Spendrin <ps_ml@gmx.de>
  422. + *
  423. + * The SSH Library is free software; you can redistribute it and/or modify
  424. + * it under the terms of the GNU Lesser General Public License as published by
  425. + * the Free Software Foundation; either version 2.1 of the License, or (at your
  426. + * option) any later version.
  427. + *
  428. + * The SSH Library is distributed in the hope that it will be useful, but
  429. + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  430. + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  431. + * License for more details.
  432. + *
  433. + * You should have received a copy of the GNU Lesser General Public License
  434. + * along with the SSH Library; see the file COPYING. If not, write to
  435. + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  436. + * MA 02111-1307, USA.
  437. + */
  438. +
  439. +
  440. +#ifndef __WINPGNTC_H
  441. +#define __WINPGNTC_H
  442. +
  443. +#ifdef _WIN32
  444. +#include "libssh/agent.h"
  445. +
  446. +int agent_query(void *in, int inlen, void **out, int *outlen);
  447. +
  448. +#endif
  449. +#endif /* __WINPGNTC_H */
  450. --
  451. 1.7.4.msysgit.0