~ubuntu-branches/ubuntu/jaunty/gnupg2/jaunty-security

« back to all changes in this revision

Viewing changes to agent/command-ssh.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-10-04 10:25:53 UTC
  • mfrom: (5.1.15 intrepid)
  • Revision ID: james.westby@ubuntu.com-20081004102553-fv62pp8dsitxli47
Tags: 2.0.9-3.1
* Non-maintainer upload.
* agent/gpg-agent.c: Deinit the threading library before exec'ing
  the command to run in --daemon mode. And because that still doesn't
  restore the sigprocmask, do that manually. Closes: #499569

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* command-ssh.c - gpg-agent's ssh-agent emulation layer
2
 
 * Copyright (C) 2004, 2005 Free Software Foundation, Inc.
 
2
 * Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
3
3
 *
4
4
 * This file is part of GnuPG.
5
5
 *
6
6
 * GnuPG is free software; you can redistribute it and/or modify
7
7
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * the Free Software Foundation; either version 3 of the License, or
9
9
 * (at your option) any later version.
10
10
 *
11
11
 * GnuPG is distributed in the hope that it will be useful,
14
14
 * GNU General Public License for more details.
15
15
 *
16
16
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19
 
 * 02111-1307, USA
 
17
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20
18
 */
21
19
 
22
20
/* Only v2 of the ssh-agent protocol is implemented.  */
268
266
  s = xtrymalloc (data_n + 1);
269
267
  if (s)
270
268
    {
271
 
      strncpy (s, data, data_n);
 
269
      memcpy (s, data, data_n);
272
270
      s[data_n] = 0;
273
271
    }
274
272
 
294
292
  if (ret == EOF)
295
293
    {
296
294
      if (es_ferror (stream))
297
 
        err = gpg_error_from_errno (errno);
 
295
        err = gpg_error_from_syserror ();
298
296
      else
299
297
        err = gpg_error (GPG_ERR_EOF);
300
298
      *b = 0;
317
315
 
318
316
  ret = es_fputc (b, stream);
319
317
  if (ret == EOF)
320
 
    err = gpg_error_from_errno (errno);
 
318
    err = gpg_error_from_syserror ();
321
319
  else
322
320
    err = 0;
323
321
 
335
333
 
336
334
  ret = es_read (stream, buffer, sizeof (buffer), &bytes_read);
337
335
  if (ret)
338
 
    err = gpg_error_from_errno (errno);
 
336
    err = gpg_error_from_syserror ();
339
337
  else
340
338
    {
341
339
      if (bytes_read != sizeof (buffer))
368
366
 
369
367
  ret = es_write (stream, buffer, sizeof (buffer), NULL);
370
368
  if (ret)
371
 
    err = gpg_error_from_errno (errno);
 
369
    err = gpg_error_from_syserror ();
372
370
  else
373
371
    err = 0;
374
372
 
385
383
 
386
384
  ret = es_read (stream, buffer, size, &bytes_read);
387
385
  if (ret)
388
 
    err = gpg_error_from_errno (errno);
 
386
    err = gpg_error_from_syserror ();
389
387
  else
390
388
    {
391
389
      if (bytes_read != size)
406
404
 
407
405
  ret = es_write (stream, buffer, size, NULL);
408
406
  if (ret)
409
 
    err = gpg_error_from_errno (errno);
 
407
    err = gpg_error_from_syserror ();
410
408
  else
411
409
    err = 0;
412
410
 
421
419
                    unsigned char **string, u32 *string_size)
422
420
{
423
421
  gpg_error_t err;
424
 
  unsigned char *buffer;
425
 
  u32 length;
426
 
 
427
 
  buffer = NULL;
 
422
  unsigned char *buffer = NULL;
 
423
  u32 length = 0;
428
424
 
429
425
  /* Read string length.  */
430
426
  err = stream_read_uint32 (stream, &length);
438
434
    buffer = xtrymalloc (length + 1);
439
435
  if (! buffer)
440
436
    {
441
 
      err = gpg_error_from_errno (errno);
 
437
      err = gpg_error_from_syserror ();
442
438
      goto out;
443
439
    }
444
440
 
526
522
  if (err)
527
523
    goto out;
528
524
 
 
525
  /* To avoid excessive use of secure memory we check that an MPI is
 
526
     not too large. */
 
527
  if (mpi_data_size > 520)
 
528
    {
 
529
      log_error (_("ssh keys greater than %d bits are not supported\n"), 4096);
 
530
      err = GPG_ERR_TOO_LARGE;
 
531
      goto out;
 
532
    }
 
533
 
529
534
  err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_STD, mpi_data, mpi_data_size, NULL);
530
535
  if (err)
531
536
    goto out;
578
583
      if (ret || (! bytes_read))
579
584
        {
580
585
          if (ret)
581
 
            err = gpg_error_from_errno (errno);
 
586
            err = gpg_error_from_syserror ();
582
587
          break;
583
588
        }
584
589
      ret = es_write (dst, buffer, bytes_read, NULL);
585
590
      if (ret)
586
591
        {
587
 
          err = gpg_error_from_errno (errno);
 
592
          err = gpg_error_from_syserror ();
588
593
          break;
589
594
        }
590
595
    }
614
619
  stream = es_fopen (filename, "r");
615
620
  if (! stream)
616
621
    {
617
 
      err = gpg_error_from_errno (errno);
 
622
      err = gpg_error_from_syserror ();
618
623
      goto out;
619
624
    }
620
625
 
621
626
  ret = fstat (es_fileno (stream), &statbuf);
622
627
  if (ret)
623
628
    {
624
 
      err = gpg_error_from_errno (errno);
 
629
      err = gpg_error_from_syserror ();
625
630
      goto out;
626
631
    }
627
632
 
628
633
  buffer_new = xtrymalloc (statbuf.st_size);
629
634
  if (! buffer_new)
630
635
    {
631
 
      err = gpg_error_from_errno (errno);
 
636
      err = gpg_error_from_syserror ();
632
637
      goto out;
633
638
    }
634
639
 
787
792
      struct tm *tp;
788
793
      time_t atime = time (NULL);
789
794
 
790
 
      /* Not yet in the file - add it. Becuase the file has been
 
795
      /* Not yet in the file - add it. Because the file has been
791
796
         opened in append mode, we simply need to write to it.  */
792
797
      tp = localtime (&atime);
793
798
      fprintf (fp, "# Key added on %04d-%02d-%02d %02d:%02d:%02d\n%s %d\n",
853
858
  elems_public = key_spec.elems_key_public;
854
859
  elems_public_n = strlen (elems_public);
855
860
 
856
 
  mpis = xtrymalloc (sizeof (*mpis) * (elems_n + 1));
857
 
  if (! mpis)
 
861
  mpis = xtrycalloc (elems_n + 1, sizeof *mpis );
 
862
  if (!mpis)
858
863
    {
859
 
      err = gpg_error_from_errno (errno);
 
864
      err = gpg_error_from_syserror ();
860
865
      goto out;
861
866
    }
862
 
  
863
 
  memset (mpis, 0, sizeof (*mpis) * (elems_n + 1));
864
867
 
865
868
  elem_is_secret = 0;
866
869
  for (i = 0; i < elems_n; i++)
1033
1036
  sexp_template = xtrymalloc (sexp_template_n);
1034
1037
  if (! sexp_template)
1035
1038
    {
1036
 
      err = gpg_error_from_errno (errno);
 
1039
      err = gpg_error_from_syserror ();
1037
1040
      goto out;
1038
1041
    }
1039
1042
 
1041
1044
  arg_list = xtrymalloc (sizeof (*arg_list) * (2 + elems_n + 1));
1042
1045
  if (! arg_list)
1043
1046
    {
1044
 
      err = gpg_error_from_errno (errno);
 
1047
      err = gpg_error_from_syserror ();
1045
1048
      goto out;
1046
1049
    }
1047
1050
 
1143
1146
    }
1144
1147
 
1145
1148
  elems_n = strlen (elems);
1146
 
  mpis_new = xtrymalloc (sizeof (*mpis_new) * (elems_n + 1));
1147
 
  if (! mpis_new)
 
1149
  mpis_new = xtrycalloc (elems_n + 1, sizeof *mpis_new );
 
1150
  if (!mpis_new)
1148
1151
    {
1149
 
      err = gpg_error_from_errno (errno);
 
1152
      err = gpg_error_from_syserror ();
1150
1153
      goto out;
1151
1154
    }
1152
 
  memset (mpis_new, 0, sizeof (*mpis_new) * (elems_n + 1));
1153
1155
 
1154
1156
  value_list = gcry_sexp_find_token (sexp, key_spec.identifier, 0);
1155
1157
  if (! value_list)
1198
1200
  comment_new = make_cstring (data, data_n);
1199
1201
  if (! comment_new)
1200
1202
    {
1201
 
      err = gpg_error_from_errno (errno);
 
1203
      err = gpg_error_from_syserror ();
1202
1204
      goto out;
1203
1205
    }
1204
1206
 
1395
1397
  stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1396
1398
  if (! stream)
1397
1399
    {
1398
 
      err = gpg_error_from_errno (errno);
 
1400
      err = gpg_error_from_syserror ();
1399
1401
      goto out;
1400
1402
    }
1401
1403
 
1411
1413
  blob_size_new = es_ftell (stream);
1412
1414
  if (blob_size_new == -1)
1413
1415
    {
1414
 
      err = gpg_error_from_errno (errno);
 
1416
      err = gpg_error_from_syserror ();
1415
1417
      goto out;
1416
1418
    }
1417
1419
  
1422
1424
  blob_new = xtrymalloc (blob_size_new);
1423
1425
  if (! blob_new)
1424
1426
    {
1425
 
      err = gpg_error_from_errno (errno);
 
1427
      err = gpg_error_from_syserror ();
1426
1428
      goto out;
1427
1429
    }
1428
1430
 
1514
1516
  blob_stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1515
1517
  if (! blob_stream)
1516
1518
    {
1517
 
      err = gpg_error_from_errno (errno);
 
1519
      err = gpg_error_from_syserror ();
1518
1520
      goto out;
1519
1521
    }
1520
1522
 
1678
1680
      shadow_info = make_shadow_info (serialno, authkeyid);
1679
1681
      if (!shadow_info)
1680
1682
        {
1681
 
          err = gpg_error_from_errno (errno);
 
1683
          err = gpg_error_from_syserror ();
1682
1684
          xfree (pkbuf);
1683
1685
          gcry_sexp_release (s_pk);
1684
1686
          xfree (serialno);
1728
1730
        *cardsn = xtryasprintf ("cardno:%s", serialno);
1729
1731
      if (!*cardsn)
1730
1732
        {
1731
 
          err = gpg_error_from_errno (errno);
 
1733
          err = gpg_error_from_syserror ();
1732
1734
          xfree (pkbuf);
1733
1735
          gcry_sexp_release (s_pk);
1734
1736
          xfree (serialno);
1795
1797
  key_blobs = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1796
1798
  if (! key_blobs)
1797
1799
    {
1798
 
      err = gpg_error_from_errno (errno);
 
1800
      err = gpg_error_from_syserror ();
1799
1801
      goto out;
1800
1802
    }
1801
1803
 
1919
1921
  ret = es_fseek (key_blobs, 0, SEEK_SET);
1920
1922
  if (ret)
1921
1923
    {
1922
 
      err = gpg_error_from_errno (errno);
 
1924
      err = gpg_error_from_syserror ();
1923
1925
      goto out;
1924
1926
    }
1925
1927
 
2026
2028
  stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2027
2029
  if (! stream)
2028
2030
    {
2029
 
      err = gpg_error_from_errno (errno);
 
2031
      err = gpg_error_from_syserror ();
2030
2032
      goto out;
2031
2033
    }
2032
2034
 
2040
2042
  identifier = make_cstring (identifier_raw, identifier_n);
2041
2043
  if (! identifier)
2042
2044
    {
2043
 
      err = gpg_error_from_errno (errno);
 
2045
      err = gpg_error_from_syserror ();
2044
2046
      goto out;
2045
2047
    }
2046
2048
 
2055
2057
  elems = spec.elems_signature;
2056
2058
  elems_n = strlen (elems);
2057
2059
 
2058
 
  mpis = xtrymalloc (sizeof (*mpis) * (elems_n + 1));
2059
 
  if (! mpis)
 
2060
  mpis = xtrycalloc (elems_n + 1, sizeof *mpis);
 
2061
  if (!mpis)
2060
2062
    {
2061
 
      err = gpg_error_from_errno (errno);
 
2063
      err = gpg_error_from_syserror ();
2062
2064
      goto out;
2063
2065
    }
2064
 
  memset (mpis, 0, sizeof (*mpis) * (elems_n + 1));
2065
2066
 
2066
2067
  for (i = 0; i < elems_n; i++)
2067
2068
    {
2093
2094
  sig_blob_n = es_ftell (stream);
2094
2095
  if (sig_blob_n == -1)
2095
2096
    {
2096
 
      err = gpg_error_from_errno (errno);
 
2097
      err = gpg_error_from_syserror ();
2097
2098
      goto out;
2098
2099
    }
2099
2100
 
2100
2101
  sig_blob = xtrymalloc (sig_blob_n);
2101
2102
  if (! sig_blob)
2102
2103
    {
2103
 
      err = gpg_error_from_errno (errno);
 
2104
      err = gpg_error_from_syserror ();
2104
2105
      goto out;
2105
2106
    }
2106
2107
 
2107
2108
  ret = es_fseek (stream, 0, SEEK_SET);
2108
2109
  if (ret)
2109
2110
    {
2110
 
      err = gpg_error_from_errno (errno);
 
2111
      err = gpg_error_from_syserror ();
2111
2112
      goto out;
2112
2113
    }    
2113
2114
 
2264
2265
  comment_new = make_cstring (data, data_n);
2265
2266
  if (! comment_new)
2266
2267
    {
2267
 
      err = gpg_error_from_errno (errno);
 
2268
      err = gpg_error_from_syserror ();
2268
2269
      goto out;
2269
2270
    }
2270
2271
 
2294
2295
  buffer_new = xtrymalloc_secure (buffer_new_n);
2295
2296
  if (! buffer_new)
2296
2297
    {
2297
 
      err = gpg_error_from_errno (errno);
 
2298
      err = gpg_error_from_syserror ();
2298
2299
      goto out;
2299
2300
    }
2300
2301
  
2312
2313
 
2313
2314
 
2314
2315
 
 
2316
/* Callback function to compare the first entered PIN with the one
 
2317
   currently being entered. */
 
2318
static int
 
2319
reenter_compare_cb (struct pin_entry_info_s *pi)
 
2320
{
 
2321
  const char *pin1 = pi->check_cb_arg;
 
2322
 
 
2323
  if (!strcmp (pin1, pi->pin))
 
2324
    return 0; /* okay */
 
2325
  return -1;
 
2326
}
 
2327
 
2315
2328
/* Store the ssh KEY into our local key storage and protect it after
2316
2329
   asking for a passphrase.  Cache that passphrase.  TTL is the
2317
2330
   maximum caching time for that key.  If the key already exists in
2321
2334
ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
2322
2335
{
2323
2336
  gpg_error_t err;
2324
 
  unsigned char key_grip_raw[21];
 
2337
  unsigned char key_grip_raw[20];
2325
2338
  char key_grip[41];
2326
2339
  unsigned char *buffer = NULL;
2327
 
  unsigned int buffer_n;
 
2340
  size_t buffer_n;
2328
2341
  char *description = NULL;
 
2342
  const char *description2 = _("Please re-enter this passphrase");
2329
2343
  char *comment = NULL;
 
2344
  const char *initial_errtext = NULL;
2330
2345
  unsigned int i;
2331
 
  struct pin_entry_info_s *pi = NULL;
 
2346
  struct pin_entry_info_s *pi = NULL, *pi2;
2332
2347
 
2333
2348
  err = ssh_key_grip (key, key_grip_raw);
2334
2349
  if (err)
2335
2350
    goto out;
2336
2351
 
2337
 
  key_grip_raw[sizeof (key_grip_raw) - 1] = 0; /* FIXME:  Why?? */
2338
 
 
2339
2352
  /* Check whether the key is already in our key storage.  Don't do
2340
2353
     anything then.  */
2341
2354
  if ( !agent_key_available (key_grip_raw) )
2353
2366
                   "within gpg-agent's key storage"),
2354
2367
                 comment ? comment : "?") < 0)
2355
2368
    {
2356
 
      err = gpg_error_from_errno (errno);
 
2369
      err = gpg_error_from_syserror ();
2357
2370
      goto out;
2358
2371
    }
2359
2372
 
2360
2373
 
2361
 
  pi = gcry_calloc_secure (1, sizeof (*pi) + 100 + 1);
 
2374
  pi = gcry_calloc_secure (2, sizeof (*pi) + 100 + 1);
2362
2375
  if (!pi)
2363
2376
    {
2364
 
      err = gpg_error_from_errno (errno);
 
2377
      err = gpg_error_from_syserror ();
2365
2378
      goto out;
2366
2379
    }
 
2380
  pi2 = pi + (sizeof *pi + 100 + 1);
2367
2381
  pi->max_length = 100;
2368
2382
  pi->max_tries = 1;
2369
 
  err = agent_askpin (ctrl, description, NULL, NULL, pi);
 
2383
  pi2->max_length = 100;
 
2384
  pi2->max_tries = 1;
 
2385
  pi2->check_cb = reenter_compare_cb;
 
2386
  pi2->check_cb_arg = pi->pin;
 
2387
 
 
2388
 next_try:
 
2389
  err = agent_askpin (ctrl, description, NULL, initial_errtext, pi);
 
2390
  initial_errtext = NULL;
2370
2391
  if (err)
2371
2392
    goto out;
2372
2393
 
 
2394
  /* Unless the passphrase is empty, ask to confirm it.  */
 
2395
  if (pi->pin && *pi->pin)
 
2396
    {
 
2397
      err = agent_askpin (ctrl, description2, NULL, NULL, pi2);
 
2398
      if (err == -1)
 
2399
        { /* The re-entered one did not match and the user did not
 
2400
             hit cancel. */
 
2401
          initial_errtext = _("does not match - try again");
 
2402
          goto next_try;
 
2403
        }
 
2404
    }
 
2405
 
2373
2406
  err = ssh_key_to_protected_buffer (key, pi->pin, &buffer, &buffer_n);
2374
2407
  if (err)
2375
2408
    goto out;
2643
2676
      break;
2644
2677
  if (i == DIM (request_specs))
2645
2678
    {
2646
 
      log_info ("ssh request %u is not supported\n", type);
 
2679
      if (opt.verbose)
 
2680
        log_info ("ssh request %u is not supported\n", type);
2647
2681
      spec = NULL;
2648
2682
    }
2649
2683
  else
2679
2713
     secret key material.  The response does not have to be stored in
2680
2714
     secure memory, since we never give out secret keys. 
2681
2715
 
2682
 
     FIXME: This is a pretty good DoS.  We only have a limited amount
2683
 
     of secure memory, we can't throw in everything we get from a
2684
 
     client -wk */
2685
 
      
 
2716
     Note: we only have little secure memory, but there is NO
 
2717
     possibility of DoS here; only trusted clients are allowed to
 
2718
     connect to the agent.  What could happen is that the agent
 
2719
     returns out-of-secure-memory errors on requests in case the
 
2720
     agent's owner floods his own agent with many large messages.
 
2721
     -moritz */
 
2722
 
2686
2723
  /* Retrieve request.  */
2687
2724
  err = stream_read_string (stream_sock, 1, &request_data, &request_data_size);
2688
2725
  if (err)
2714
2751
    request = es_mopen (NULL, 0, 0, 1, gcry_realloc, gcry_free, "r+");
2715
2752
  if (! request)
2716
2753
    {
2717
 
      err = gpg_error_from_errno (errno);
 
2754
      err = gpg_error_from_syserror ();
2718
2755
      goto out;
2719
2756
    }
2720
2757
  ret = es_setvbuf (request, NULL, _IONBF, 0);
2721
2758
  if (ret)
2722
2759
    {
2723
 
      err = gpg_error_from_errno (errno);
 
2760
      err = gpg_error_from_syserror ();
2724
2761
      goto out;
2725
2762
    }
2726
2763
  err = stream_write_data (request, request_data + 1, request_data_size - 1);
2731
2768
  response = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
2732
2769
  if (! response)
2733
2770
    {
2734
 
      err = gpg_error_from_errno (errno);
 
2771
      err = gpg_error_from_syserror ();
2735
2772
      goto out;
2736
2773
    }
2737
2774
 
2815
2852
 
2816
2853
/* Start serving client on SOCK_CLIENT.  */
2817
2854
void
2818
 
start_command_handler_ssh (int sock_client)
 
2855
start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client)
2819
2856
{
2820
 
  struct server_control_s ctrl;
2821
2857
  estream_t stream_sock;
2822
2858
  gpg_error_t err;
2823
2859
  int ret;
2824
2860
 
2825
 
  /* Setup control structure.  */
2826
 
 
2827
 
  memset (&ctrl, 0, sizeof (ctrl));
2828
 
  agent_init_default_ctrl (&ctrl);
2829
 
  ctrl.connection_fd = sock_client;
2830
 
 
2831
2861
  /* Because the ssh protocol does not send us information about the
2832
2862
     the current TTY setting, we resort here to use those from startup
2833
2863
     or those explictly set.  */
2834
 
  if (!ctrl.display && opt.startup_display)
2835
 
    ctrl.display = strdup (opt.startup_display);
2836
 
  if (!ctrl.ttyname && opt.startup_ttyname)
2837
 
    ctrl.ttyname = strdup (opt.startup_ttyname);
2838
 
  if (!ctrl.ttytype && opt.startup_ttytype)
2839
 
    ctrl.ttytype = strdup (opt.startup_ttytype);
2840
 
  if (!ctrl.lc_ctype && opt.startup_lc_ctype)
2841
 
    ctrl.lc_ctype = strdup (opt.startup_lc_ctype);
2842
 
  if (!ctrl.lc_messages && opt.startup_lc_messages)
2843
 
    ctrl.lc_messages = strdup (opt.startup_lc_messages);
 
2864
  if (!ctrl->display && opt.startup_display)
 
2865
    ctrl->display = strdup (opt.startup_display);
 
2866
  if (!ctrl->ttyname && opt.startup_ttyname)
 
2867
    ctrl->ttyname = strdup (opt.startup_ttyname);
 
2868
  if (!ctrl->ttytype && opt.startup_ttytype)
 
2869
    ctrl->ttytype = strdup (opt.startup_ttytype);
 
2870
  if (!ctrl->lc_ctype && opt.startup_lc_ctype)
 
2871
    ctrl->lc_ctype = strdup (opt.startup_lc_ctype);
 
2872
  if (!ctrl->lc_messages && opt.startup_lc_messages)
 
2873
    ctrl->lc_messages = strdup (opt.startup_lc_messages);
 
2874
  if (!ctrl->xauthority && opt.startup_xauthority)
 
2875
    ctrl->xauthority = strdup (opt.startup_xauthority);
 
2876
  if (!ctrl->pinentry_user_data && opt.startup_pinentry_user_data)
 
2877
    ctrl->pinentry_user_data = strdup (opt.startup_pinentry_user_data);
2844
2878
 
2845
2879
 
2846
2880
  /* Create stream from socket.  */
2847
 
  stream_sock = es_fdopen (sock_client, "r+");
 
2881
  stream_sock = es_fdopen (FD2INT(sock_client), "r+");
2848
2882
  if (!stream_sock)
2849
2883
    {
2850
 
      err = gpg_error_from_errno (errno);
 
2884
      err = gpg_error_from_syserror ();
2851
2885
      log_error (_("failed to create stream from socket: %s\n"),
2852
2886
                 gpg_strerror (err));
2853
2887
      goto out;
2857
2891
  ret = es_setvbuf (stream_sock, NULL, _IONBF, 0);
2858
2892
  if (ret)
2859
2893
    {
2860
 
      err = gpg_error_from_errno (errno);
2861
 
      log_error (_("failed to disable buffering "
2862
 
                   "on socket stream: %s\n"), gpg_strerror (err));
 
2894
      err = gpg_error_from_syserror ();
 
2895
      log_error ("failed to disable buffering "
 
2896
                 "on socket stream: %s\n", gpg_strerror (err));
2863
2897
      goto out;
2864
2898
    }
2865
2899
 
2866
2900
  /* Main processing loop. */
2867
 
  while ( !ssh_request_process (&ctrl, stream_sock) )
2868
 
    ;
 
2901
  while ( !ssh_request_process (ctrl, stream_sock) )
 
2902
    {
 
2903
      /* Check wether we have reached EOF before trying to read
 
2904
         another request.  */
 
2905
      int c;
 
2906
 
 
2907
      c = es_fgetc (stream_sock);
 
2908
      if (c == EOF)
 
2909
        break;
 
2910
      es_ungetc (c, stream_sock);
 
2911
    }
2869
2912
 
2870
2913
  /* Reset the SCD in case it has been used. */
2871
 
  agent_reset_scd (&ctrl);
 
2914
  agent_reset_scd (ctrl);
2872
2915
 
2873
2916
 
2874
2917
 out:
2875
2918
  if (stream_sock)
2876
2919
    es_fclose (stream_sock);
2877
 
 
2878
 
  free (ctrl.display);
2879
 
  free (ctrl.ttyname);
2880
 
  free (ctrl.ttytype);
2881
 
  free (ctrl.lc_ctype);
2882
 
  free (ctrl.lc_messages);
2883
2920
}