agent.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
  1. /* agent.c - Talking to gpg-agent.
  2. Copyright (C) 2006, 2007, 2008 g10 Code GmbH
  3. This file is part of Scute.
  4. Scute is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. Scute is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with Scute; if not, write to the Free Software Foundation,
  14. Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  15. In addition, as a special exception, g10 Code GmbH gives permission
  16. to link this library: with the Mozilla Foundation's code for
  17. Mozilla (or with modified versions of it that use the same license
  18. as the "Mozilla" code), and distribute the linked executables. You
  19. must obey the GNU General Public License in all respects for all of
  20. the code used other than "Mozilla". If you modify this file, you
  21. may extend this exception to your version of the file, but you are
  22. not obligated to do so. If you do not wish to do so, delete this
  23. exception statement from your version. */
  24. #if HAVE_CONFIG_H
  25. #include <config.h>
  26. #endif
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29. #include <locale.h>
  30. #include <errno.h>
  31. #include <string.h>
  32. #include <stdarg.h>
  33. #ifdef HAVE_W32_SYSTEM
  34. #define PATHSEP_C ';'
  35. #define WINVER 0x0500 /* Required for AllowSetForegroundWindow. */
  36. #include <windows.h>
  37. #else
  38. #define PATHSEP_C ':'
  39. #endif
  40. #include <assuan.h>
  41. #include <gpg-error.h>
  42. #include "debug.h"
  43. #include "support.h"
  44. #include "cert.h"
  45. #include "agent.h"
  46. /* The global agent context. */
  47. static assuan_context_t agent_ctx = NULL;
  48. /* The version number of the agent. */
  49. static int agent_version_major;
  50. static int agent_version_minor;
  51. /* Hack required for Windows. */
  52. void
  53. gnupg_allow_set_foregound_window (pid_t pid)
  54. {
  55. if (!pid || pid == (pid_t)(-1))
  56. return;
  57. #ifdef HAVE_W32_SYSTEM
  58. else if (!AllowSetForegroundWindow (pid))
  59. DEBUG (DBG_CRIT, "AllowSetForegroundWindow(%lu) failed: %i\n",
  60. (unsigned long)pid, GetLastError ());
  61. #endif
  62. }
  63. #ifdef HAVE_W32_SYSTEM
  64. /* Helper function to build_w32_commandline. */
  65. static char *
  66. build_w32_commandline_copy (char *buffer, const char *string)
  67. {
  68. char *p = buffer;
  69. const char *s;
  70. if (!*string) /* Empty string. */
  71. p = stpcpy (p, "\"\"");
  72. else if (strpbrk (string, " \t\n\v\f\""))
  73. {
  74. /* Need top do some kind of quoting. */
  75. p = stpcpy (p, "\"");
  76. for (s=string; *s; s++)
  77. {
  78. *p++ = *s;
  79. if (*s == '\"')
  80. *p++ = *s;
  81. }
  82. *p++ = '\"';
  83. *p = 0;
  84. }
  85. else
  86. p = stpcpy (p, string);
  87. return p;
  88. }
  89. /* Build a command line for use with W32's CreateProcess. On success
  90. CMDLINE gets the address of a newly allocated string. */
  91. static gpg_error_t
  92. build_w32_commandline (const char *pgmname, const char * const *argv,
  93. char **cmdline)
  94. {
  95. int i, n;
  96. const char *s;
  97. char *buf, *p;
  98. *cmdline = NULL;
  99. n = 0;
  100. s = pgmname;
  101. n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */
  102. for (; *s; s++)
  103. if (*s == '\"')
  104. n++; /* Need to double inner quotes. */
  105. for (i=0; (s=argv[i]); i++)
  106. {
  107. n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */
  108. for (; *s; s++)
  109. if (*s == '\"')
  110. n++; /* Need to double inner quotes. */
  111. }
  112. n++;
  113. buf = p = malloc (n);
  114. if (!buf)
  115. return gpg_error_from_syserror ();
  116. p = build_w32_commandline_copy (p, pgmname);
  117. for (i=0; argv[i]; i++)
  118. {
  119. *p++ = ' ';
  120. p = build_w32_commandline_copy (p, argv[i]);
  121. }
  122. *cmdline= buf;
  123. return 0;
  124. }
  125. /* Spawn a new process and immediatley detach from it. The name of
  126. the program to exec is PGMNAME and its arguments are in ARGV (the
  127. programname is automatically passed as first argument). An error
  128. is returned if pgmname is not executable; to make this work it is
  129. necessary to provide an absolute file name. All standard file
  130. descriptors are connected to /dev/null. */
  131. static gpg_error_t
  132. spawn_process_detached (const char *pgmname, const char *argv[])
  133. {
  134. gpg_error_t err;
  135. SECURITY_ATTRIBUTES sec_attr;
  136. PROCESS_INFORMATION pi =
  137. {
  138. NULL, /* Returns process handle. */
  139. 0, /* Returns primary thread handle. */
  140. 0, /* Returns pid. */
  141. 0 /* Returns tid. */
  142. };
  143. STARTUPINFO si;
  144. int cr_flags;
  145. char *cmdline;
  146. if (access (pgmname, X_OK))
  147. return gpg_error_from_syserror ();
  148. /* Prepare security attributes. */
  149. memset (&sec_attr, 0, sizeof sec_attr );
  150. sec_attr.nLength = sizeof sec_attr;
  151. sec_attr.bInheritHandle = FALSE;
  152. /* Build the command line. */
  153. err = build_w32_commandline (pgmname, argv, &cmdline);
  154. if (err)
  155. return err;
  156. /* Start the process. */
  157. memset (&si, 0, sizeof si);
  158. si.cb = sizeof (si);
  159. si.dwFlags = STARTF_USESHOWWINDOW;
  160. si.wShowWindow = SW_MINIMIZE;
  161. cr_flags = (CREATE_DEFAULT_ERROR_MODE
  162. | GetPriorityClass (GetCurrentProcess ())
  163. | CREATE_NEW_PROCESS_GROUP
  164. | DETACHED_PROCESS);
  165. DEBUG (DBG_INFO, "CreateProcess(detached), path=`%s' cmdline=`%s'\n",
  166. pgmname, cmdline);
  167. if (!CreateProcess (pgmname, /* Program to start. */
  168. cmdline, /* Command line arguments. */
  169. &sec_attr, /* Process security attributes. */
  170. &sec_attr, /* Thread security attributes. */
  171. FALSE, /* Inherit handles. */
  172. cr_flags, /* Creation flags. */
  173. NULL, /* Environment. */
  174. NULL, /* Use current drive/directory. */
  175. &si, /* Startup information. */
  176. &pi /* Returns process information. */
  177. ))
  178. {
  179. DEBUG (DBG_CRIT, "CreateProcess(detached) failed: %i\n",
  180. GetLastError ());
  181. free (cmdline);
  182. return gpg_error (GPG_ERR_GENERAL);
  183. }
  184. free (cmdline);
  185. cmdline = NULL;
  186. DEBUG (DBG_INFO, "CreateProcess(detached) ready: hProcess=%p hThread=%p"
  187. " dwProcessID=%d dwThreadId=%d\n", pi.hProcess, pi.hThread,
  188. (int) pi.dwProcessId, (int) pi.dwThreadId);
  189. CloseHandle (pi.hThread);
  190. return 0;
  191. }
  192. #endif
  193. /* Establish a connection to a running GPG agent. */
  194. static gpg_error_t
  195. agent_connect (assuan_context_t *ctx_r)
  196. {
  197. /* If we ever failed to connect via a socket we will force the use
  198. of the pipe based server for the lifetime of the process. */
  199. static int force_pipe_server = 0;
  200. gpg_error_t err = 0;
  201. char *infostr;
  202. char *ptr;
  203. assuan_context_t ctx = NULL;
  204. err = assuan_new (&ctx);
  205. if (err)
  206. return err;
  207. restart:
  208. infostr = force_pipe_server ? NULL : getenv ("GPG_AGENT_INFO");
  209. if (!infostr || !*infostr)
  210. {
  211. char *sockname;
  212. /* First check whether we can connect at the standard
  213. socket. */
  214. sockname = make_filename (default_homedir (), "S.gpg-agent", NULL);
  215. if (! sockname)
  216. return gpg_error_from_errno (errno);
  217. err = assuan_socket_connect (ctx, sockname, 0, 0);
  218. if (err)
  219. {
  220. const char *agent_program;
  221. /* With no success start a new server. */
  222. DEBUG (DBG_INFO, "no running GPG agent at %s, starting one\n",
  223. sockname);
  224. agent_program = get_gpg_agent_path ();
  225. #ifdef HAVE_W32_SYSTEM
  226. {
  227. /* Under Windows we start the server in daemon mode. This
  228. is because the default is to use the standard socket
  229. and thus there is no need for the GPG_AGENT_INFO
  230. envvar. This is possible as we don't have a real unix
  231. domain socket but use a plain file and thus there is no
  232. need to care about non-local file systems. */
  233. const char *argv[3];
  234. argv[0] = "--daemon";
  235. argv[1] = "--use-standard-socket";
  236. argv[2] = NULL;
  237. err = spawn_process_detached (agent_program, argv);
  238. if (err)
  239. DEBUG (DBG_CRIT, "failed to start agent `%s': %s\n",
  240. agent_program, gpg_strerror (err));
  241. else
  242. {
  243. /* Give the agent some time to prepare itself. */
  244. Sleep (3 * 1000);
  245. /* Now try again to connect the agent. */
  246. err = assuan_socket_connect (ctx_r, sockname, 0, 0);
  247. }
  248. }
  249. #else /*!HAVE_W32_SYSTEM*/
  250. {
  251. const char *pgmname;
  252. const char *argv[3];
  253. int no_close_list[3];
  254. int i;
  255. if ( !(pgmname = strrchr (agent_program, '/')))
  256. pgmname = agent_program;
  257. else
  258. pgmname++;
  259. argv[0] = pgmname;
  260. argv[1] = "--server";
  261. argv[2] = NULL;
  262. i=0;
  263. no_close_list[i++] = fileno (stderr);
  264. no_close_list[i] = -1;
  265. /* Connect to the agent and perform initial handshaking. */
  266. err = assuan_pipe_connect (ctx, agent_program, argv,
  267. no_close_list, NULL, NULL, 0);
  268. }
  269. #endif /*!HAVE_W32_SYSTEM*/
  270. }
  271. free (sockname);
  272. }
  273. else
  274. {
  275. int pid;
  276. int protocol_version;
  277. infostr = strdup (infostr);
  278. if (!infostr)
  279. return gpg_error_from_errno (errno);
  280. if (!(ptr = strchr (infostr, PATHSEP_C)) || ptr == infostr)
  281. {
  282. DEBUG (DBG_CRIT, "malformed GPG_AGENT_INFO environment variable");
  283. free (infostr);
  284. force_pipe_server = 1;
  285. goto restart;
  286. }
  287. *(ptr++) = 0;
  288. pid = atoi (ptr);
  289. while (*ptr && *ptr != PATHSEP_C)
  290. ptr++;
  291. protocol_version = *ptr ? atoi (ptr + 1) : 0;
  292. if (protocol_version != 1)
  293. {
  294. DEBUG (DBG_CRIT, "GPG agent protocol version '%d' not supported",
  295. protocol_version);
  296. free (infostr);
  297. force_pipe_server = 1;
  298. goto restart;
  299. }
  300. err = assuan_socket_connect (ctx, infostr, pid, 0);
  301. free (infostr);
  302. if (err)
  303. {
  304. DEBUG (DBG_CRIT, "cannot connect to GPG agent: %s", gpg_strerror (err));
  305. force_pipe_server = 1;
  306. goto restart;
  307. }
  308. }
  309. if (err)
  310. {
  311. assuan_release (ctx);
  312. DEBUG (DBG_CRIT, "cannot connect to GPG agent: %s", gpg_strerror (err));
  313. return gpg_error (GPG_ERR_NO_AGENT);
  314. }
  315. if (_scute_debug_flags & DBG_ASSUAN)
  316. assuan_set_log_stream (*ctx_r, _scute_debug_stream);
  317. *ctx_r = ctx;
  318. return 0;
  319. }
  320. /* This is the default inquiry callback. It mainly handles the
  321. Pinentry notifications. */
  322. static gpg_error_t
  323. default_inq_cb (void *opaque, const char *line)
  324. {
  325. (void)opaque;
  326. if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17]))
  327. {
  328. gnupg_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10));
  329. /* We do not pass errors to avoid breaking other code. */
  330. }
  331. else
  332. DEBUG (DBG_CRIT, "ignoring gpg-agent inquiry `%s'\n", line);
  333. return 0;
  334. }
  335. /* Send a simple command to the agent. */
  336. static gpg_error_t
  337. agent_simple_cmd (assuan_context_t ctx, const char *fmt, ...)
  338. {
  339. gpg_error_t err;
  340. char *optstr;
  341. va_list arg;
  342. int res;
  343. va_start (arg, fmt);
  344. res = vasprintf (&optstr, fmt, arg);
  345. va_end (arg);
  346. if (res < 0)
  347. return gpg_error_from_errno (errno);
  348. err = assuan_transact (ctx, optstr, NULL, NULL, default_inq_cb,
  349. NULL, NULL, NULL);
  350. if (err)
  351. DEBUG (DBG_CRIT, "gpg-agent command '%s' failed: %s", optstr,
  352. gpg_strerror (err));
  353. free (optstr);
  354. return err;
  355. }
  356. /* Read and stroe the agent's version number. */
  357. static gpg_error_t
  358. read_version_cb (void *opaque, const void *buffer, size_t length)
  359. {
  360. char version[20];
  361. const char *s;
  362. if (length > sizeof (version) -1)
  363. length = sizeof (version) - 1;
  364. strncpy (version, buffer, length);
  365. version[length] = 0;
  366. agent_version_major = atoi (version);
  367. s = strchr (version, '.');
  368. agent_version_minor = s? atoi (s+1) : 0;
  369. return 0;
  370. }
  371. /* Configure the GPG agent at connection CTX. */
  372. static gpg_error_t
  373. agent_configure (assuan_context_t ctx)
  374. {
  375. gpg_error_t err = 0;
  376. char *dft_display = NULL;
  377. char *dft_ttyname = NULL;
  378. char *dft_ttytype = NULL;
  379. #if defined(HAVE_SETLOCALE) && (defined(LC_CTYPE) || defined(LC_MESSAGES))
  380. char *old_lc = NULL;
  381. char *dft_lc = NULL;
  382. #endif
  383. char *dft_xauthority = NULL;
  384. char *dft_pinentry_user_data = NULL;
  385. err = agent_simple_cmd (ctx, "RESET");
  386. if (err)
  387. return err;
  388. /* Set up display, terminal and locale options. */
  389. dft_display = getenv ("DISPLAY");
  390. if (dft_display)
  391. err = agent_simple_cmd (ctx, "OPTION display=%s", dft_display);
  392. if (err)
  393. return err;
  394. dft_ttyname = getenv ("GPG_TTY");
  395. if ((!dft_ttyname || !*dft_ttyname) && ttyname (0))
  396. dft_ttyname = ttyname (0);
  397. if (dft_ttyname)
  398. {
  399. err = agent_simple_cmd (ctx, "OPTION ttyname=%s", dft_ttyname);
  400. if (err)
  401. return err;
  402. }
  403. dft_ttytype = getenv ("TERM");
  404. if (dft_ttytype)
  405. err = agent_simple_cmd (ctx, "OPTION ttytype=%s", dft_ttytype);
  406. if (err)
  407. return err;
  408. #if defined(HAVE_SETLOCALE) && defined(LC_CTYPE)
  409. old_lc = setlocale (LC_CTYPE, NULL);
  410. if (old_lc)
  411. {
  412. old_lc = strdup (old_lc);
  413. if (!old_lc)
  414. return gpg_error_from_errno (errno);
  415. }
  416. dft_lc = setlocale (LC_CTYPE, "");
  417. if (dft_lc)
  418. err = agent_simple_cmd ("OPTION lc-ctype=%s", dft_lc);
  419. if (old_lc)
  420. {
  421. setlocale (LC_CTYPE, old_lc);
  422. free (old_lc);
  423. }
  424. #endif
  425. if (err)
  426. return err;
  427. #if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)
  428. old_lc = setlocale (LC_MESSAGES, NULL);
  429. if (old_lc)
  430. {
  431. old_lc = strdup (old_lc);
  432. if (!old_lc)
  433. err = gpg_error_from_errno (errno);
  434. }
  435. dft_lc = setlocale (LC_MESSAGES, "");
  436. if (dft_lc)
  437. err = agent_simple_cmd ("OPTION lc-messages=%s", dft_lc);
  438. if (old_lc)
  439. {
  440. setlocale (LC_MESSAGES, old_lc);
  441. free (old_lc);
  442. }
  443. #endif
  444. dft_xauthority = getenv ("XAUTHORITY");
  445. if (dft_xauthority)
  446. err = agent_simple_cmd (ctx, "OPTION xauthority=%s", dft_xauthority);
  447. if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
  448. err = 0;
  449. else if (err)
  450. return err;
  451. dft_pinentry_user_data = getenv ("PINENTRY_USER_DATA");
  452. if (dft_pinentry_user_data)
  453. err = agent_simple_cmd (ctx, "OPTION pinentry_user_data=%s",
  454. dft_pinentry_user_data);
  455. if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
  456. err = 0;
  457. else if (err)
  458. return err;
  459. err = agent_simple_cmd (ctx, "OPTION allow-pinentry-notify");
  460. if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
  461. err = 0;
  462. else if (err)
  463. return err;
  464. err = assuan_transact (ctx, "GETINFO version",
  465. read_version_cb, NULL,
  466. NULL, NULL, NULL, NULL);
  467. if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION)
  468. err = 0;
  469. else if (err)
  470. return err;
  471. return err;
  472. }
  473. /* Try to connect to the agent via socket. Handle the server's
  474. initial greeting. */
  475. gpg_error_t
  476. scute_agent_initialize (void)
  477. {
  478. gpg_error_t err = 0;
  479. if (agent_ctx)
  480. {
  481. DEBUG (DBG_CRIT, "GPG Agent connection already established");
  482. return 0;
  483. }
  484. DEBUG (DBG_INFO, "Establishing connection to gpg-agent");
  485. err = agent_connect (&agent_ctx);
  486. if (err)
  487. return err;
  488. err = agent_configure (agent_ctx);
  489. if (err)
  490. scute_agent_finalize ();
  491. return err;
  492. }
  493. int
  494. scute_agent_get_agent_version (int *minor)
  495. {
  496. *minor = agent_version_minor;
  497. return agent_version_major;
  498. }
  499. /* Return a new malloced string by unescaping the string S. Escaping
  500. is percent escaping and '+'/space mapping. A binary nul will
  501. silently be replaced by a 0xFF. Function returns NULL to indicate
  502. an out of memory status. */
  503. static char *
  504. unescape_status_string (const unsigned char *src)
  505. {
  506. char *buffer;
  507. char *dst;
  508. buffer = malloc (strlen (src) + 1);
  509. if (!buffer)
  510. return NULL;
  511. dst = buffer;
  512. while (*src)
  513. {
  514. if (*src == '%' && src[1] && src[2])
  515. {
  516. src++;
  517. *dst = xtoi_2 (src);
  518. if (*dst == '\0')
  519. *dst = '\xff';
  520. dst++;
  521. src += 2;
  522. }
  523. else if (*src == '+')
  524. {
  525. *(dst++) = ' ';
  526. src++;
  527. }
  528. else
  529. *(dst++) = *(src++);
  530. }
  531. *dst = 0;
  532. return buffer;
  533. }
  534. /* Take a 20 byte hexencoded string and put it into the the provided
  535. 20 byte buffer FPR in binary format. Returns true if successful,
  536. and false otherwise. */
  537. static int
  538. unhexify_fpr (const char *hexstr, unsigned char *fpr)
  539. {
  540. const char *src;
  541. int cnt;
  542. /* Check for invalid or wrong length. */
  543. for (src = hexstr, cnt = 0; hexdigitp (src); src++, cnt++)
  544. ;
  545. if ((*src && !spacep (src)) || (cnt != 40))
  546. return 0;
  547. cnt /= 2;
  548. for (src = hexstr, cnt = 0; *src && !spacep (src); src += 2, cnt++)
  549. fpr[cnt] = xtoi_2 (src);
  550. return 1;
  551. }
  552. /* Take the serial number from LINE and return it verbatim in a newly
  553. allocated string. We make sure that only hex characters are
  554. returned. */
  555. static char *
  556. store_serialno (const char *line)
  557. {
  558. const char *src;
  559. char *ptr;
  560. for (src = line; hexdigitp (src); src++)
  561. ;
  562. ptr = malloc (src + 1 - line);
  563. if (ptr)
  564. {
  565. memcpy (ptr, line, src - line);
  566. ptr[src - line] = 0;
  567. }
  568. return ptr;
  569. }
  570. /* Release the card info structure INFO. */
  571. void
  572. scute_agent_release_card_info (struct agent_card_info_s *info)
  573. {
  574. if (!info)
  575. return;
  576. free (info->serialno);
  577. free (info->disp_name);
  578. free (info->disp_lang);
  579. free (info->pubkey_url);
  580. free (info->login_data);
  581. memset (info, 0, sizeof (*info));
  582. }
  583. /* FIXME: We are not returning out of memory errors. */
  584. static gpg_error_t
  585. learn_status_cb (void *opaque, const char *line)
  586. {
  587. struct agent_card_info_s *parm = opaque;
  588. const char *keyword = line;
  589. int keywordlen;
  590. int i;
  591. for (keywordlen = 0; *line && !spacep (line); line++, keywordlen++)
  592. ;
  593. while (spacep (line))
  594. line++;
  595. if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
  596. {
  597. if (parm->serialno)
  598. free (parm->serialno);
  599. parm->serialno = store_serialno (line);
  600. }
  601. else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen))
  602. {
  603. if (parm->disp_name)
  604. free (parm->disp_name);
  605. parm->disp_name = unescape_status_string (line);
  606. }
  607. else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen))
  608. {
  609. if (parm->disp_lang)
  610. free (parm->disp_lang);
  611. parm->disp_lang = unescape_status_string (line);
  612. }
  613. else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen))
  614. {
  615. parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0;
  616. }
  617. else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen))
  618. {
  619. if (parm->pubkey_url)
  620. free (parm->pubkey_url);
  621. parm->pubkey_url = unescape_status_string (line);
  622. }
  623. else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen))
  624. {
  625. if (parm->login_data)
  626. free (parm->login_data);
  627. parm->login_data = unescape_status_string (line);
  628. }
  629. else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen))
  630. {
  631. parm->sig_counter = strtoul (line, NULL, 0);
  632. }
  633. else if (keywordlen == 10 && !memcmp (keyword, "CHV-STATUS", keywordlen))
  634. {
  635. char *p, *buf;
  636. buf = p = unescape_status_string (line);
  637. if (buf)
  638. {
  639. while (spacep (p))
  640. p++;
  641. parm->chv1_cached = atoi (p);
  642. while (*p && !spacep (p))
  643. p++;
  644. while (spacep (p))
  645. p++;
  646. for (i = 0; *p && i < 3; i++)
  647. {
  648. parm->chvmaxlen[i] = atoi (p);
  649. while (*p && !spacep (p))
  650. p++;
  651. while (spacep (p))
  652. p++;
  653. }
  654. for (i=0; *p && i < 3; i++)
  655. {
  656. parm->chvretry[i] = atoi (p);
  657. while (*p && !spacep (p))
  658. p++;
  659. while (spacep (p))
  660. p++;
  661. }
  662. free (buf);
  663. }
  664. }
  665. else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
  666. {
  667. int no = atoi (line);
  668. while (*line && !spacep (line))
  669. line++;
  670. while (spacep (line))
  671. line++;
  672. if (no == 1)
  673. parm->fpr1valid = unhexify_fpr (line, parm->fpr1);
  674. else if (no == 2)
  675. parm->fpr2valid = unhexify_fpr (line, parm->fpr2);
  676. else if (no == 3)
  677. parm->fpr3valid = unhexify_fpr (line, parm->fpr3);
  678. }
  679. else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen))
  680. {
  681. int no = atoi (line);
  682. while (*line && !spacep (line))
  683. line++;
  684. while (spacep (line))
  685. line++;
  686. if (no == 1)
  687. parm->cafpr1valid = unhexify_fpr (line, parm->cafpr1);
  688. else if (no == 2)
  689. parm->cafpr2valid = unhexify_fpr (line, parm->cafpr2);
  690. else if (no == 3)
  691. parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3);
  692. }
  693. else if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen))
  694. {
  695. const char *grip = line;
  696. while (*line && !spacep (line))
  697. line++;
  698. if (line - grip == 40)
  699. {
  700. while (spacep (line))
  701. line++;
  702. if (!memcmp (line, "OPENPGP.", 8))
  703. {
  704. int no;
  705. line += 8;
  706. no = atoi (line);
  707. if (no == 1)
  708. {
  709. memcpy (parm->grip1, grip, 40);
  710. parm->grip1valid = 1;
  711. }
  712. else if (no == 2)
  713. {
  714. memcpy (parm->grip2, grip, 40);
  715. parm->grip2valid = 1;
  716. }
  717. else if (no == 3)
  718. {
  719. memcpy (parm->grip3, grip, 40);
  720. parm->grip3valid = 1;
  721. }
  722. }
  723. }
  724. }
  725. return 0;
  726. }
  727. /* Call the agent to learn about a smartcard. */
  728. gpg_error_t
  729. scute_agent_learn (struct agent_card_info_s *info)
  730. {
  731. gpg_error_t err;
  732. memset (info, 0, sizeof (*info));
  733. err = assuan_transact (agent_ctx, "LEARN --send",
  734. NULL, NULL, default_inq_cb,
  735. NULL, learn_status_cb, info);
  736. return err;
  737. }
  738. static gpg_error_t
  739. geteventcounter_status_cb (void *opaque, const char *line)
  740. {
  741. int *result = opaque;
  742. const char *keyword = line;
  743. int keywordlen;
  744. for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
  745. ;
  746. while (spacep (line))
  747. line++;
  748. if (keywordlen == 12 && !memcmp (keyword, "EVENTCOUNTER", keywordlen))
  749. {
  750. static int any_count;
  751. static unsigned int last_count;
  752. unsigned int count;
  753. if (sscanf (line, "%*u %*u %u ", &count) == 1)
  754. {
  755. if (any_count && last_count != count)
  756. *result = 1;
  757. any_count = 1;
  758. last_count = count;
  759. }
  760. }
  761. return 0;
  762. }
  763. static gpg_error_t
  764. read_status_cb (void *opaque, const void *buffer, size_t length)
  765. {
  766. char *flag = opaque;
  767. if (length == 0)
  768. *flag = 'r';
  769. else
  770. *flag = *((char *) buffer);
  771. return 0;
  772. }
  773. /* Check the agent status. This returns 0 if a token is present,
  774. GPG_ERR_CARD_REMOVED if no token is present, and an error code
  775. otherwise. */
  776. gpg_error_t
  777. scute_agent_check_status (void)
  778. {
  779. static char last_flag;
  780. gpg_error_t err;
  781. int any = 0;
  782. char flag = '-';
  783. /* First we look at the eventcounter to see if anything happened at
  784. all. This is a low overhead function which won't even clutter a
  785. gpg-agent log file. There is no need for error checking here. */
  786. if (last_flag)
  787. assuan_transact (agent_ctx, "GETEVENTCOUNTER",
  788. NULL, NULL,
  789. NULL, NULL,
  790. geteventcounter_status_cb, &any);
  791. if (any || !last_flag)
  792. {
  793. err = assuan_transact (agent_ctx, "SCD GETINFO status",
  794. read_status_cb, &flag,
  795. default_inq_cb, NULL,
  796. NULL, NULL);
  797. if (err)
  798. return err;
  799. last_flag = flag;
  800. }
  801. else
  802. flag = last_flag;
  803. if (flag == 'r')
  804. return gpg_error (GPG_ERR_CARD_REMOVED);
  805. return 0;
  806. }
  807. /* Enough space to hold a 2048 bit RSA signature in an S-expression. */
  808. #define MAX_SIGNATURE_LEN 350
  809. struct signature
  810. {
  811. unsigned char data[MAX_SIGNATURE_LEN];
  812. int len;
  813. };
  814. static gpg_error_t
  815. pksign_cb (void *opaque, const void *buffer, size_t length)
  816. {
  817. struct signature *sig = opaque;
  818. if (sig->len + length > MAX_SIGNATURE_LEN)
  819. {
  820. DEBUG (DBG_INFO, "maximum signature length exceeded");
  821. return gpg_error (GPG_ERR_BAD_DATA);
  822. }
  823. memcpy (&sig->data[sig->len], buffer, length);
  824. sig->len += length;
  825. return 0;
  826. }
  827. #define SIG_PREFIX "(7:sig-val(3:rsa(1:s128:"
  828. #define SIG_PREFIX_2 "(7:sig-val(3:rsa(1:s256:"
  829. #define SIG_PREFIX_LEN (sizeof (SIG_PREFIX) - 1)
  830. #define SIG_POSTFIX ")))"
  831. #define SIG_POSTFIX_LEN (sizeof (SIG_POSTFIX) - 1)
  832. #define SIG_LEN 128
  833. #define SIG_LEN_2 256
  834. /* Call the agent to learn about a smartcard. */
  835. gpg_error_t
  836. scute_agent_sign (char *grip, unsigned char *data, int len,
  837. unsigned char *sig_result, unsigned int *sig_len)
  838. {
  839. char cmd[150];
  840. gpg_error_t err;
  841. #define MAX_DATA_LEN 36
  842. unsigned char pretty_data[2 * MAX_DATA_LEN + 1];
  843. int i;
  844. struct signature sig;
  845. sig.len = 0;
  846. if (sig_len == NULL)
  847. return gpg_error (GPG_ERR_INV_ARG);
  848. if (sig_result == NULL)
  849. {
  850. /* FIXME: We return the largest supported size - is that correct? */
  851. *sig_len = SIG_LEN_2;
  852. return 0;
  853. }
  854. if (len > MAX_DATA_LEN)
  855. return gpg_error (GPG_ERR_INV_ARG);
  856. if (grip == NULL || sig_result == NULL || *sig_len < SIG_LEN)
  857. return gpg_error (GPG_ERR_INV_ARG);
  858. snprintf (cmd, sizeof (cmd), "SIGKEY %s", grip);
  859. err = assuan_transact (agent_ctx, cmd, NULL, NULL, default_inq_cb,
  860. NULL, NULL, NULL);
  861. if (err)
  862. return err;
  863. for (i = 0; i < len; i++)
  864. snprintf (&pretty_data[2 * i], 3, "%02X", data[i]);
  865. pretty_data[2 * len] = '\0';
  866. snprintf (cmd, sizeof (cmd), "SETHASH --hash=tls-md5sha1 %s", pretty_data);
  867. err = assuan_transact (agent_ctx, cmd, NULL, NULL, default_inq_cb,
  868. NULL, NULL, NULL);
  869. if (err)
  870. return err;
  871. err = assuan_transact (agent_ctx, "PKSIGN",
  872. pksign_cb, &sig, default_inq_cb, NULL, NULL, NULL);
  873. if (err)
  874. return err;
  875. /* FIXME: we need a real parser to cope with all kind of S-expressions. */
  876. if (sig.len == SIG_PREFIX_LEN + SIG_LEN_2 + SIG_POSTFIX_LEN)
  877. {
  878. if (memcmp (sig.data, SIG_PREFIX_2, SIG_PREFIX_LEN))
  879. return gpg_error (GPG_ERR_BAD_SIGNATURE);
  880. if (memcmp (sig.data + sig.len - SIG_POSTFIX_LEN,
  881. SIG_POSTFIX, SIG_POSTFIX_LEN))
  882. return gpg_error (GPG_ERR_BAD_SIGNATURE);
  883. memcpy (sig_result, sig.data + SIG_PREFIX_LEN, SIG_LEN_2);
  884. *sig_len = SIG_LEN_2;
  885. }
  886. else
  887. {
  888. if (sig.len != SIG_PREFIX_LEN + SIG_LEN + SIG_POSTFIX_LEN)
  889. return gpg_error (GPG_ERR_BAD_SIGNATURE);
  890. if (memcmp (sig.data, SIG_PREFIX, SIG_PREFIX_LEN))
  891. return gpg_error (GPG_ERR_BAD_SIGNATURE);
  892. if (memcmp (sig.data + sig.len - SIG_POSTFIX_LEN,
  893. SIG_POSTFIX, SIG_POSTFIX_LEN))
  894. return gpg_error (GPG_ERR_BAD_SIGNATURE);
  895. memcpy (sig_result, sig.data + SIG_PREFIX_LEN, SIG_LEN);
  896. *sig_len = SIG_LEN;
  897. }
  898. return 0;
  899. }
  900. /* Determine if FPR is trusted. */
  901. gpg_error_t
  902. scute_agent_is_trusted (char *fpr, bool *is_trusted)
  903. {
  904. gpg_error_t err;
  905. bool trusted = false;
  906. char cmd[150];
  907. snprintf (cmd, sizeof (cmd), "ISTRUSTED %s", fpr);
  908. err = assuan_transact (agent_ctx, cmd, NULL, NULL, default_inq_cb,
  909. NULL, NULL, NULL);
  910. if (err && gpg_err_code (err) != GPG_ERR_NOT_TRUSTED)
  911. return err;
  912. else if (!err)
  913. trusted = true;
  914. *is_trusted = trusted;
  915. return 0;
  916. }
  917. #define GET_CERT_INIT_SIZE 2048
  918. struct get_cert_s
  919. {
  920. unsigned char *cert_der;
  921. int cert_der_len;
  922. int cert_der_size;
  923. };
  924. gpg_error_t
  925. get_cert_data_cb (void *opaque, const void *data, size_t data_len)
  926. {
  927. struct get_cert_s *cert_s = opaque;
  928. gpg_error_t err;
  929. int needed_size;
  930. needed_size = cert_s->cert_der_len + data_len;
  931. if (needed_size > cert_s->cert_der_size)
  932. {
  933. unsigned char *new_cert_der;
  934. int new_cert_der_size = cert_s->cert_der_size;
  935. if (new_cert_der_size == 0)
  936. new_cert_der_size = GET_CERT_INIT_SIZE;
  937. while (new_cert_der_size < needed_size)
  938. new_cert_der_size *= 2;
  939. if (cert_s->cert_der == NULL)
  940. new_cert_der = malloc (new_cert_der_size);
  941. else
  942. new_cert_der = realloc (cert_s->cert_der, new_cert_der_size);
  943. if (new_cert_der == NULL)
  944. return gpg_error_from_syserror ();
  945. cert_s->cert_der = new_cert_der;
  946. cert_s->cert_der_size = new_cert_der_size;
  947. }
  948. memcpy (cert_s->cert_der + cert_s->cert_der_len, data, data_len);
  949. cert_s->cert_der_len += data_len;
  950. return 0;
  951. }
  952. /* Try to get certificate for key numer NO. */
  953. gpg_error_t
  954. scute_agent_get_cert (int no, struct cert *cert)
  955. {
  956. gpg_error_t err;
  957. char cmd[150];
  958. struct get_cert_s cert_s;
  959. cert_s.cert_der = NULL;
  960. cert_s.cert_der_len = 0;
  961. cert_s.cert_der_size = 0;
  962. snprintf (cmd, sizeof (cmd), "SCD READCERT OPENPGP.%i", no);
  963. err = assuan_transact (agent_ctx, cmd, get_cert_data_cb, &cert_s,
  964. NULL, NULL, NULL, NULL);
  965. /* Just to be safe... */
  966. if (!err && cert_s.cert_der_len <= 16)
  967. {
  968. DEBUG (DBG_INFO, "bad card certificate rejected");
  969. err = gpg_error (GPG_ERR_BAD_CERT);
  970. }
  971. if (err)
  972. {
  973. if (cert_s.cert_der)
  974. free (cert_s.cert_der);
  975. return err;
  976. }
  977. DEBUG (DBG_INFO, "got certificate from card with length %i",
  978. cert_s.cert_der_len);
  979. cert->cert_der = cert_s.cert_der;
  980. cert->cert_der_len = cert_s.cert_der_len;
  981. return 0;
  982. }
  983. void
  984. scute_agent_finalize (void)
  985. {
  986. if (!agent_ctx)
  987. {
  988. DEBUG (DBG_CRIT, "no GPG Agent connection established");
  989. return;
  990. }
  991. DEBUG (DBG_INFO, "releasing agent context");
  992. assuan_release (agent_ctx);
  993. agent_ctx = NULL;
  994. }