~ubuntu-branches/ubuntu/raring/gnupg2/raring-proposed

« back to all changes in this revision

Viewing changes to agent/command-ssh.c

  • Committer: Package Import Robot
  • Author(s): Sebastien Bacher
  • Date: 2012-11-06 11:25:58 UTC
  • mfrom: (14.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20121106112558-kxptsug6ivixhx8m
Tags: 2.0.19-1ubuntu1
* Resynchronize on Debian, remaining changes:
  - Add udev rules to give gpg access to some smartcard readers;
    Debian #543217.
    . debian/gnupg2.dev: udev rules to set ACLs on SCM smartcard readers.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
 
35
35
#include "estream.h"
36
36
#include "i18n.h"
 
37
#include "../common/ssh-utils.h"
 
38
 
37
39
 
38
40
 
39
41
 
69
71
"# in the SSH protocol.  The ssh-add tool may add new entries to this\n"
70
72
"# file to enable them; you may also add them manually.  Comment\n"
71
73
"# lines, like this one, as well as empty lines are ignored.  Lines do\n"
72
 
"# have a certain length limit but this is not serious limitation as\n" 
 
74
"# have a certain length limit but this is not serious limitation as\n"
73
75
"# the format of the entries is fixed and checked by gpg-agent. A\n"
74
76
"# non-comment line starts with optional white spaces, followed by the\n"
75
77
"# keygrip of the key given as 40 hex digits, optionally followed by a\n"
193
195
 
194
196
 
195
197
/* Global variables.  */
196
 
   
 
198
 
197
199
 
198
200
/* Associating request types with the corresponding request
199
201
   handlers.  */
235
237
 
236
238
 
237
239
/*
238
 
   General utility functions. 
 
240
   General utility functions.
239
241
 */
240
242
 
241
243
/* A secure realloc, i.e. it makes sure to allocate secure memory if A
246
248
realloc_secure (void *a, size_t n)
247
249
{
248
250
  void *p;
249
 
  
 
251
 
250
252
  if (a)
251
253
    p = gcry_realloc (a, n);
252
254
  else
276
278
 
277
279
 
278
280
 
279
 
/* 
280
 
   Primitive I/O functions.  
 
281
/*
 
282
   Primitive I/O functions.
281
283
 */
282
284
 
283
285
 
467
469
  err = stream_read_string (stream, 0, &buffer, NULL);
468
470
  if (err)
469
471
    goto out;
470
 
  
 
472
 
471
473
  *string = (char *) buffer;
472
474
 
473
475
 out:
504
506
                             (const unsigned char *) string, strlen (string));
505
507
 
506
508
  return err;
507
 
}                         
 
509
}
508
510
 
509
511
/* Read an MPI from STREAM, store it in MPINT.  Depending on SECURE
510
512
   use secure memory.  */
615
617
 
616
618
  buffer_new = NULL;
617
619
  err = 0;
618
 
  
 
620
 
619
621
  stream = es_fopen (filename, "r");
620
622
  if (! stream)
621
623
    {
681
683
    {
682
684
      /* Fixme: "x" is a GNU extension.  We might want to use the es_
683
685
         functions here.  */
684
 
      fp = fopen (fname, "wx");  
 
686
      fp = fopen (fname, "wx");
685
687
      if (!fp)
686
688
        {
687
689
          err = gpg_error (gpg_err_code_from_errno (errno));
701
703
      xfree (fname);
702
704
      return err;
703
705
    }
704
 
  
705
 
  *r_fp = fp;  
 
706
 
 
707
  *r_fp = fp;
706
708
 
707
709
  return 0;
708
710
}
711
713
/* Search the file at stream FP from the beginning until a matching
712
714
   HEXGRIP is found; return success in this case and store true at
713
715
   DISABLED if the found key has been disabled.  If R_TTL is not NULL
714
 
   a specified TTL for that key is stored there. */
 
716
   a specified TTL for that key is stored there.  If R_CONFIRM is not
 
717
   NULL it is set to 1 if the key has the confirm flag set. */
715
718
static gpg_error_t
716
 
search_control_file (FILE *fp, const char *hexgrip, 
717
 
                     int *r_disabled, int *r_ttl)
 
719
search_control_file (FILE *fp, const char *hexgrip,
 
720
                     int *r_disabled, int *r_ttl, int *r_confirm)
718
721
{
719
 
  int c, i;
 
722
  int c, i, n;
720
723
  char *p, *pend, line[256];
721
724
  long ttl;
 
725
  int lnr = 0;
 
726
  const char fname[] = "sshcontrol";
722
727
 
723
728
  assert (strlen (hexgrip) == 40 );
724
729
 
725
 
  rewind (fp);
 
730
  if (r_confirm)
 
731
    *r_confirm = 0;
 
732
 
 
733
  fseek (fp, 0, SEEK_SET);
 
734
  clearerr (fp);
726
735
  *r_disabled = 0;
727
736
 next_line:
728
737
  do
733
742
            return gpg_error (GPG_ERR_EOF);
734
743
          return gpg_error (gpg_err_code_from_errno (errno));
735
744
        }
736
 
      
 
745
      lnr++;
 
746
 
737
747
      if (!*line || line[strlen(line)-1] != '\n')
738
748
        {
739
749
          /* Eat until end of line */
742
752
          return gpg_error (*line? GPG_ERR_LINE_TOO_LONG
743
753
                                 : GPG_ERR_INCOMPLETE_LINE);
744
754
        }
745
 
      
 
755
 
746
756
      /* Allow for empty lines and spaces */
747
757
      for (p=line; spacep (p); p++)
748
758
        ;
749
759
    }
750
760
  while (!*p || *p == '\n' || *p == '#');
751
 
  
 
761
 
752
762
  *r_disabled = 0;
753
763
  if (*p == '!')
754
764
    {
762
772
      goto next_line;
763
773
  if (i != 40 || !(spacep (p) || *p == '\n'))
764
774
    {
765
 
      log_error ("invalid formatted line in ssh control file\n");
 
775
      log_error ("invalid formatted line in `%s', line %d\n", fname, lnr);
766
776
      return gpg_error (GPG_ERR_BAD_DATA);
767
777
    }
768
778
 
770
780
  p = pend;
771
781
  if (!(spacep (p) || *p == '\n') || ttl < -1)
772
782
    {
773
 
      log_error ("invalid TTL value in ssh control file; assuming 0\n");
 
783
      log_error ("invalid TTL value in `%s', line %d; assuming 0\n",
 
784
                 fname, lnr);
774
785
      ttl = 0;
775
786
    }
776
787
  if (r_ttl)
777
788
    *r_ttl = ttl;
778
789
 
779
 
  /* Here is the place to parse flags if we need them.  */  
 
790
  /* Now check for key-value pairs of the form NAME[=VALUE]. */
 
791
  while (*p)
 
792
    {
 
793
      for (; spacep (p) && *p != '\n'; p++)
 
794
        ;
 
795
      if (!*p || *p == '\n')
 
796
        break;
 
797
      n = strcspn (p, "= \t\n");
 
798
      if (p[n] == '=')
 
799
        {
 
800
          log_error ("assigning a value to a flag is not yet supported; "
 
801
                     "in `%s', line %d; flag ignored\n", fname, lnr);
 
802
          p++;
 
803
        }
 
804
      else if (n == 7 && !memcmp (p, "confirm", 7))
 
805
        {
 
806
          if (r_confirm)
 
807
            *r_confirm = 1;
 
808
        }
 
809
      else
 
810
        log_error ("invalid flag `%.*s' in `%s', line %d; ignored\n",
 
811
                   n, p, fname, lnr);
 
812
      p += n;
 
813
    }
780
814
 
781
815
  return 0; /* Okay:  found it.  */
782
816
}
785
819
 
786
820
/* Add an entry to the control file to mark the key with the keygrip
787
821
   HEXGRIP as usable for SSH; i.e. it will be returned when ssh asks
788
 
   for it.  This function is in general used to add a key received
789
 
   through the ssh-add function.  We can assume that the user wants to
790
 
   allow ssh using this key. */
 
822
   for it.  FMTFPR is the fingerprint string.  This function is in
 
823
   general used to add a key received through the ssh-add function.
 
824
   We can assume that the user wants to allow ssh using this key. */
791
825
static gpg_error_t
792
 
add_control_entry (ctrl_t ctrl, const char *hexgrip, int ttl)
 
826
add_control_entry (ctrl_t ctrl, const char *hexgrip, const char *fmtfpr,
 
827
                   int ttl, int confirm)
793
828
{
794
829
  gpg_error_t err;
795
830
  FILE *fp;
801
836
  if (err)
802
837
    return err;
803
838
 
804
 
  err = search_control_file (fp, hexgrip, &disabled, NULL);
 
839
  err = search_control_file (fp, hexgrip, &disabled, NULL, NULL);
805
840
  if (err && gpg_err_code(err) == GPG_ERR_EOF)
806
841
    {
807
842
      struct tm *tp;
810
845
      /* Not yet in the file - add it. Because the file has been
811
846
         opened in append mode, we simply need to write to it.  */
812
847
      tp = localtime (&atime);
813
 
      fprintf (fp, "# Key added on %04d-%02d-%02d %02d:%02d:%02d\n%s %d\n",
 
848
      fprintf (fp, ("# Key added on: %04d-%02d-%02d %02d:%02d:%02d\n"
 
849
                    "# Fingerprint:  %s\n"
 
850
                    "%s %d%s\n"),
814
851
               1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
815
852
               tp->tm_hour, tp->tm_min, tp->tm_sec,
816
 
               hexgrip, ttl);
817
 
               
 
853
               fmtfpr, hexgrip, ttl, confirm? " confirm":"");
 
854
 
818
855
    }
819
856
  fclose (fp);
820
857
  return 0;
834
871
  if (open_control_file (&fp, 0))
835
872
    return 0; /* Error: Use the global default TTL.  */
836
873
 
837
 
  if (search_control_file (fp, hexgrip, &disabled, &ttl)
 
874
  if (search_control_file (fp, hexgrip, &disabled, &ttl, NULL)
838
875
      || disabled)
839
876
    ttl = 0;  /* Use the global default if not found or disabled.  */
840
877
 
841
 
  fclose (fp); 
 
878
  fclose (fp);
842
879
 
843
880
  return ttl;
844
881
}
845
882
 
846
883
 
 
884
/* Scan the sshcontrol file and return the confirm flag.  */
 
885
static int
 
886
confirm_flag_from_sshcontrol (const char *hexgrip)
 
887
{
 
888
  FILE *fp;
 
889
  int disabled, confirm;
 
890
 
 
891
  if (!hexgrip || strlen (hexgrip) != 40)
 
892
    return 1;  /* Wrong input: Better ask for confirmation.  */
 
893
 
 
894
  if (open_control_file (&fp, 0))
 
895
    return 1; /* Error: Better ask for confirmation.  */
 
896
 
 
897
  if (search_control_file (fp, hexgrip, &disabled, NULL, &confirm)
 
898
      || disabled)
 
899
    confirm = 0;  /* If not found or disabled, there is no reason to
 
900
                     ask for confirmation.  */
 
901
 
 
902
  fclose (fp);
 
903
 
 
904
  return confirm;
 
905
}
 
906
 
 
907
 
847
908
 
848
909
 
849
910
 
850
911
/*
851
912
 
852
 
  MPI lists. 
 
913
  MPI lists.
853
914
 
854
915
 */
855
916
 
875
936
ssh_receive_mpint_list (estream_t stream, int secret,
876
937
                        ssh_key_type_spec_t key_spec, gcry_mpi_t **mpi_list)
877
938
{
878
 
  unsigned int elems_public_n;
879
939
  const char *elems_public;
880
940
  unsigned int elems_n;
881
941
  const char *elems;
886
946
 
887
947
  mpis = NULL;
888
948
  err = 0;
889
 
  
 
949
 
890
950
  if (secret)
891
951
    elems = key_spec.elems_key_secret;
892
952
  else
894
954
  elems_n = strlen (elems);
895
955
 
896
956
  elems_public = key_spec.elems_key_public;
897
 
  elems_public_n = strlen (elems_public);
898
957
 
899
958
  mpis = xtrycalloc (elems_n + 1, sizeof *mpis );
900
959
  if (!mpis)
1008
1067
          err = gpg_error (GPG_ERR_INTERNAL); /* FIXME?  */
1009
1068
          break;
1010
1069
        }
1011
 
      
 
1070
 
1012
1071
      memset (buffer + (i * SSH_DSA_SIGNATURE_PADDING), 0,
1013
1072
              SSH_DSA_SIGNATURE_PADDING - data_n);
1014
1073
      memcpy (buffer + (i * SSH_DSA_SIGNATURE_PADDING)
1029
1088
  return err;
1030
1089
}
1031
1090
 
1032
 
/* 
1033
 
   S-Expressions. 
 
1091
/*
 
1092
   S-Expressions.
1034
1093
 */
1035
1094
 
1036
1095
 
1252
1311
  gcry_sexp_release (value_list);
1253
1312
  gcry_sexp_release (value_pair);
1254
1313
  gcry_sexp_release (comment_list);
1255
 
  
 
1314
 
1256
1315
  if (err)
1257
1316
    {
1258
1317
      xfree (comment_new);
1262
1321
  return err;
1263
1322
}
1264
1323
 
1265
 
/* Extract the car from SEXP, and create a newly created C-string 
 
1324
/* Extract the car from SEXP, and create a newly created C-string
1266
1325
   which is to be stored in IDENTIFIER.  */
1267
1326
static gpg_error_t
1268
1327
sexp_extract_identifier (gcry_sexp_t sexp, char **identifier)
1275
1334
 
1276
1335
  identifier_new = NULL;
1277
1336
  err = 0;
1278
 
  
 
1337
 
1279
1338
  sublist = gcry_sexp_nth (sexp, 1);
1280
1339
  if (! sublist)
1281
1340
    {
1329
1388
    if ((ssh_name && (! strcmp (ssh_name, ssh_key_types[i].ssh_identifier)))
1330
1389
        || (name && (! strcmp (name, ssh_key_types[i].identifier))))
1331
1390
      break;
1332
 
  
 
1391
 
1333
1392
  if (i == DIM (ssh_key_types))
1334
1393
    err = gpg_error (GPG_ERR_NOT_FOUND);
1335
1394
  else
1351
1410
                 int read_comment, ssh_key_type_spec_t *key_spec)
1352
1411
{
1353
1412
  gpg_error_t err;
1354
 
  char *key_type;
1355
 
  char *comment;
1356
 
  gcry_sexp_t key;
 
1413
  char *key_type = NULL;
 
1414
  char *comment = NULL;
 
1415
  gcry_sexp_t key = NULL;
1357
1416
  ssh_key_type_spec_t spec;
1358
 
  gcry_mpi_t *mpi_list;
 
1417
  gcry_mpi_t *mpi_list = NULL;
1359
1418
  const char *elems;
1360
1419
 
1361
 
  mpi_list = NULL;
1362
 
  key_type = NULL;
1363
 
  comment = "";
1364
 
  key = NULL;
1365
 
        
 
1420
 
1366
1421
  err = stream_read_cstring (stream, &key_type);
1367
1422
  if (err)
1368
1423
    goto out;
1394
1449
        goto out;
1395
1450
    }
1396
1451
 
1397
 
  err = sexp_key_construct (&key, spec, secret, mpi_list, comment);
 
1452
  err = sexp_key_construct (&key, spec, secret, mpi_list, comment? comment:"");
1398
1453
  if (err)
1399
1454
    goto out;
1400
1455
 
1401
1456
  if (key_spec)
1402
1457
    *key_spec = spec;
1403
1458
  *key_new = key;
1404
 
  
 
1459
 
1405
1460
 out:
1406
1461
 
1407
1462
  mpint_list_free (mpi_list);
1408
1463
  xfree (key_type);
1409
 
  if (read_comment)
1410
 
    xfree (comment);
 
1464
  xfree (comment);
1411
1465
 
1412
1466
  return err;
1413
1467
}
1454
1508
      err = gpg_error_from_syserror ();
1455
1509
      goto out;
1456
1510
    }
1457
 
  
 
1511
 
1458
1512
  err = es_fseek (stream, 0, SEEK_SET);
1459
1513
  if (err)
1460
1514
    goto out;
1482
1536
 
1483
1537
  return err;
1484
1538
}
1485
 
                              
 
1539
 
1486
1540
 
1487
1541
/* Write the public key KEY_PUBLIC to STREAM in SSH key format.  If
1488
1542
   OVERRIDE_COMMENT is not NULL, it will be used instead of the
1520
1574
                                 spec.ssh_identifier, mpi_list);
1521
1575
  if (err)
1522
1576
    goto out;
1523
 
  
 
1577
 
1524
1578
  err = stream_write_string (stream, blob, blob_n);
1525
1579
  if (err)
1526
1580
    goto out;
1527
1581
 
1528
1582
  err = stream_write_cstring (stream,
1529
1583
                              override_comment? override_comment : comment);
1530
 
  
 
1584
 
1531
1585
 out:
1532
1586
 
1533
1587
  mpint_list_free (mpi_list);
1550
1604
  gpg_error_t err;
1551
1605
 
1552
1606
  err = 0;
1553
 
  
 
1607
 
1554
1608
  blob_stream = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+");
1555
1609
  if (! blob_stream)
1556
1610
    {
1590
1644
  return 0;
1591
1645
}
1592
1646
 
 
1647
 
1593
1648
/* Converts the secret key KEY_SECRET into a public key, storing it in
1594
1649
   KEY_PUBLIC.  SPEC is the according key specification.  Returns zero
1595
1650
   on success or an error code.  */
1714
1769
      /* (Shadow)-key is not available in our key storage.  */
1715
1770
      unsigned char *shadow_info;
1716
1771
      unsigned char *tmp;
1717
 
      
 
1772
 
1718
1773
      shadow_info = make_shadow_info (serialno, authkeyid);
1719
1774
      if (!shadow_info)
1720
1775
        {
1849
1904
      goto out;
1850
1905
    }
1851
1906
  key_directory_n = strlen (key_directory);
1852
 
  
 
1907
 
1853
1908
  key_path = xtrymalloc (key_directory_n + 46);
1854
1909
  if (! key_path)
1855
1910
    {
1881
1936
      xfree (cardsn);
1882
1937
      if (err)
1883
1938
        goto out;
1884
 
      
 
1939
 
1885
1940
      key_counter++;
1886
1941
    }
1887
1942
 
1911
1966
          hexgrip[40] = 0;
1912
1967
          if ( strlen (hexgrip) != 40 )
1913
1968
            continue;
1914
 
          if (search_control_file (ctrl_fp, hexgrip, &disabled, NULL)
 
1969
          if (search_control_file (ctrl_fp, hexgrip, &disabled, NULL, NULL)
1915
1970
              || disabled)
1916
1971
            continue;
1917
1972
 
1921
1976
          err = file_to_buffer (key_path, &buffer, &buffer_n);
1922
1977
          if (err)
1923
1978
            goto out;
1924
 
              
 
1979
 
1925
1980
          err = gcry_sexp_sscan (&key_secret, NULL, (char*)buffer, buffer_n);
1926
1981
          if (err)
1927
1982
            goto out;
1946
2001
 
1947
2002
          gcry_sexp_release (key_secret);
1948
2003
          key_secret = NULL;
1949
 
              
 
2004
 
1950
2005
          err = ssh_send_key_public (key_blobs, key_public, NULL);
1951
2006
          if (err)
1952
2007
            goto out;
1957
2012
          key_counter++;
1958
2013
        }
1959
2014
    }
1960
 
  
 
2015
 
1961
2016
  ret = es_fseek (key_blobs, 0, SEEK_SET);
1962
2017
  if (ret)
1963
2018
    {
2046
2101
  const char *elems;
2047
2102
  size_t elems_n;
2048
2103
  gcry_mpi_t *mpis = NULL;
 
2104
  char hexgrip[40+1];
2049
2105
 
2050
2106
  *sig = NULL;
2051
2107
  *sig_n = 0;
2052
2108
 
 
2109
  /* Quick check to see whether we have a valid keygrip and convert it
 
2110
     to hex.  */
 
2111
  if (!ctrl->have_keygrip)
 
2112
    {
 
2113
      err = gpg_error (GPG_ERR_NO_SECKEY);
 
2114
      goto out;
 
2115
    }
 
2116
  bin2hex (ctrl->keygrip, 20, hexgrip);
 
2117
 
 
2118
  /* Ask for confirmation if needed.  */
 
2119
  if (confirm_flag_from_sshcontrol (hexgrip))
 
2120
    {
 
2121
      gcry_sexp_t key;
 
2122
      char *fpr, *prompt;
 
2123
      char *comment = NULL;
 
2124
 
 
2125
      err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &key);
 
2126
      if (err)
 
2127
        goto out;
 
2128
      err = ssh_get_fingerprint_string (key, &fpr);
 
2129
      if (!err)
 
2130
        {
 
2131
          gcry_sexp_t tmpsxp = gcry_sexp_find_token (key, "comment", 0);
 
2132
          if (tmpsxp)
 
2133
            comment = gcry_sexp_nth_string (tmpsxp, 1);
 
2134
          gcry_sexp_release (tmpsxp);
 
2135
        }
 
2136
      gcry_sexp_release (key);
 
2137
      if (err)
 
2138
        goto out;
 
2139
      prompt = xtryasprintf (_("An ssh process requested the use of key%%0A"
 
2140
                               "  %s%%0A"
 
2141
                               "  (%s)%%0A"
 
2142
                               "Do you want to allow this?"),
 
2143
                             fpr, comment? comment:"");
 
2144
      xfree (fpr);
 
2145
      gcry_free (comment);
 
2146
      err = agent_get_confirmation (ctrl, prompt, _("Allow"), _("Deny"), 0);
 
2147
      xfree (prompt);
 
2148
      if (err)
 
2149
        goto out;
 
2150
    }
 
2151
 
 
2152
  /* Create signature.  */
2053
2153
  ctrl->use_auth_call = 1;
2054
2154
  err = agent_pksign_do (ctrl,
2055
2155
                         _("Please enter the passphrase "
2056
 
                           "for the ssh key%0A  %c"), &signature_sexp,
 
2156
                           "for the ssh key%%0A  %F%%0A  (%c)"),
 
2157
                         &signature_sexp,
2057
2158
                         CACHE_MODE_SSH, ttl_from_sshcontrol);
2058
2159
  ctrl->use_auth_call = 0;
2059
2160
  if (err)
2151
2252
    {
2152
2253
      err = gpg_error_from_syserror ();
2153
2254
      goto out;
2154
 
    }    
 
2255
    }
2155
2256
 
2156
2257
  err = stream_read_data (stream, sig_blob, sig_blob_n);
2157
2258
  if (err)
2158
2259
    goto out;
2159
 
  
 
2260
 
2160
2261
  *sig = sig_blob;
2161
2262
  *sig_n = sig_blob_n;
2162
 
  
 
2263
 
2163
2264
 out:
2164
2265
 
2165
2266
  if (err)
2201
2302
  key = NULL;
2202
2303
 
2203
2304
  /* Receive key.  */
2204
 
  
 
2305
 
2205
2306
  err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2206
2307
  if (err)
2207
2308
    goto out;
2246
2347
  memcpy (ctrl->keygrip, key_grip, 20);
2247
2348
 
2248
2349
  err = data_sign (ctrl, spec.signature_encoder, &sig, &sig_n);
2249
 
  
 
2350
 
2250
2351
 out:
2251
2352
 
2252
2353
  /* Done.  */
2266
2367
      if (ret_err)
2267
2368
        goto leave;
2268
2369
    }
2269
 
  
 
2370
 
2270
2371
 leave:
2271
2372
 
2272
2373
  gcry_sexp_release (key);
2295
2396
      err = gpg_error (GPG_ERR_INV_SEXP);
2296
2397
      goto out;
2297
2398
    }
2298
 
  
 
2399
 
2299
2400
  data = gcry_sexp_nth_data (comment_list, 1, &data_n);
2300
2401
  if (! data)
2301
2402
    {
2339
2440
      err = gpg_error_from_syserror ();
2340
2441
      goto out;
2341
2442
    }
2342
 
  
 
2443
 
2343
2444
  gcry_sexp_sprint (key, GCRYSEXP_FMT_CANON, buffer_new, buffer_new_n);
2344
2445
  /* FIXME: guarantee?  */
2345
2446
 
2372
2473
   our key storage, don't do anything.  When entering a new key also
2373
2474
   add an entry to the sshcontrol file.  */
2374
2475
static gpg_error_t
2375
 
ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl)
 
2476
ssh_identity_register (ctrl_t ctrl, gcry_sexp_t key, int ttl, int confirm)
2376
2477
{
2377
2478
  gpg_error_t err;
2378
2479
  unsigned char key_grip_raw[20];
2382
2483
  char *description = NULL;
2383
2484
  const char *description2 = _("Please re-enter this passphrase");
2384
2485
  char *comment = NULL;
 
2486
  char *key_fpr = NULL;
2385
2487
  const char *initial_errtext = NULL;
2386
2488
  unsigned int i;
2387
2489
  struct pin_entry_info_s *pi = NULL, *pi2;
2395
2497
  if ( !agent_key_available (key_grip_raw) )
2396
2498
    goto out; /* Yes, key is available.  */
2397
2499
 
2398
 
  
 
2500
  err = ssh_get_fingerprint_string (key, &key_fpr);
 
2501
  if (err)
 
2502
    goto out;
 
2503
 
2399
2504
  err = ssh_key_extract_comment (key, &comment);
2400
2505
  if (err)
2401
2506
    goto out;
2404
2509
                 _("Please enter a passphrase to protect"
2405
2510
                   " the received secret key%%0A"
2406
2511
                   "   %s%%0A"
 
2512
                   "   %s%%0A"
2407
2513
                   "within gpg-agent's key storage"),
2408
 
                 comment ? comment : "?") < 0)
 
2514
                 key_fpr, comment ? comment : "") < 0)
2409
2515
    {
2410
2516
      err = gpg_error_from_syserror ();
2411
2517
      goto out;
2462
2568
    goto out;
2463
2569
 
2464
2570
  /* And add an entry to the sshcontrol file.  */
2465
 
  err = add_control_entry (ctrl, key_grip, ttl);
 
2571
  err = add_control_entry (ctrl, key_grip, key_fpr, ttl, confirm);
2466
2572
 
2467
2573
 
2468
2574
 out:
2471
2577
  xfree (pi);
2472
2578
  xfree (buffer);
2473
2579
  xfree (comment);
2474
 
  xfree (description); 
 
2580
  xfree (key_fpr);
 
2581
  xfree (description);
2475
2582
 
2476
2583
  return err;
2477
2584
}
2510
2617
  unsigned char b;
2511
2618
  int confirm;
2512
2619
  int ttl;
2513
 
  
 
2620
 
2514
2621
  confirm = 0;
2515
2622
  key = NULL;
2516
2623
  ttl = 0;
2555
2662
  if (err)
2556
2663
    goto out;
2557
2664
 
2558
 
  /* FIXME: are constraints used correctly?  */
2559
 
 
2560
 
  err = ssh_identity_register (ctrl, key, ttl);
 
2665
  err = ssh_identity_register (ctrl, key, ttl, confirm);
2561
2666
 
2562
2667
 out:
2563
2668
 
2588
2693
 
2589
2694
  key_blob = NULL;
2590
2695
  key = NULL;
2591
 
  
 
2696
 
2592
2697
  err = stream_read_string (request, 0, &key_blob, &key_blob_size);
2593
2698
  if (err)
2594
2699
    goto out;
2596
2701
  err = ssh_read_key_public_from_blob (key_blob, key_blob_size, &key, NULL);
2597
2702
  if (err)
2598
2703
    goto out;
2599
 
  
 
2704
 
2600
2705
  err = ssh_identity_drop (key);
2601
2706
 
2602
2707
 out:
2622
2727
 
2623
2728
  /* FIXME: shall we remove _all_ cache entries or only those
2624
2729
     registered through the ssh emulation?  */
2625
 
  
 
2730
 
2626
2731
  return err;
2627
2732
}
2628
2733
 
2636
2741
 
2637
2742
  (void)ctrl;
2638
2743
  (void)request;
2639
 
  
 
2744
 
2640
2745
  err = ssh_identities_remove_all ();
2641
2746
 
2642
2747
  if (! err)
2681
2786
 
2682
2787
  (void)ctrl;
2683
2788
  (void)request;
2684
 
  
 
2789
 
2685
2790
  err = ssh_lock ();
2686
2791
 
2687
2792
  if (! err)
2698
2803
{
2699
2804
  gpg_error_t ret_err;
2700
2805
  gpg_error_t err;
2701
 
  
 
2806
 
2702
2807
  (void)ctrl;
2703
2808
  (void)request;
2704
2809
 
2763
2868
  /* Create memory streams for request/response data.  The entire
2764
2869
     request will be stored in secure memory, since it might contain
2765
2870
     secret key material.  The response does not have to be stored in
2766
 
     secure memory, since we never give out secret keys. 
 
2871
     secure memory, since we never give out secret keys.
2767
2872
 
2768
2873
     Note: we only have little secure memory, but there is NO
2769
2874
     possibility of DoS here; only trusted clients are allowed to
2914
3019
     the current TTY setting, we resort here to use those from startup
2915
3020
     or those explictly set.  */
2916
3021
  {
2917
 
    static const char *names[] = 
 
3022
    static const char *names[] =
2918
3023
      {"GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL};
2919
3024
    int idx;
2920
3025
    const char *value;
2923
3028
      if (!session_env_getenv (ctrl->session_env, names[idx])
2924
3029
          && (value = session_env_getenv (opt.startup_env, names[idx])))
2925
3030
        err = session_env_setenv (ctrl->session_env, names[idx], value);
2926
 
    
 
3031
 
2927
3032
    if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype)
2928
3033
      if (!(ctrl->lc_ctype = xtrystrdup (opt.startup_lc_ctype)))
2929
3034
        err = gpg_error_from_syserror ();
2934
3039
 
2935
3040
    if (err)
2936
3041
      {
2937
 
        log_error ("error setting default session environment: %s\n", 
 
3042
        log_error ("error setting default session environment: %s\n",
2938
3043
                   gpg_strerror (err));
2939
3044
        goto out;
2940
3045
      }