~ubuntu-branches/ubuntu/karmic/gnupg2/karmic-security

« back to all changes in this revision

Viewing changes to agent/command.c

  • Committer: Bazaar Package Importer
  • Author(s): Soren Hansen
  • Date: 2009-08-04 12:27:49 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20090804122749-q0j52zp6xmzvyall
Tags: 2.0.12-0ubuntu1
* New upstream release.
* Add 01-scd-pw2.patch, 03-opgp-writekey.patch, and 06-opgp-sign3072.patch
  from https://bugs.g10code.com/gnupg/issue1094 to make OpenPGP 2.0
  smartcards work.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* command.c - gpg-agent command handler
2
2
 * Copyright (C) 2001, 2002, 2003, 2004, 2005,
3
 
 *               2006, 2008  Free Software Foundation, Inc.
 
3
 *               2006, 2008, 2009  Free Software Foundation, Inc.
4
4
 *
5
5
 * This file is part of GnuPG.
6
6
 *
30
30
#include <ctype.h>
31
31
#include <unistd.h>
32
32
#include <assert.h>
 
33
#include <sys/types.h>
 
34
#include <sys/stat.h>
 
35
#include <dirent.h>
33
36
 
34
37
#include <assuan.h>
35
38
 
 
39
#include "i18n.h"
36
40
#include "agent.h"
37
41
 
38
42
/* maximum allowed size of the inquired ciphertext */
101
105
} eventcounter;
102
106
 
103
107
 
 
108
 
 
109
/*  Local prototypes.  */
 
110
static int command_has_option (const char *cmd, const char *cmdopt);
 
111
 
104
112
 
105
113
 
106
114
 
178
186
          && (!s[n] || spacep (s+n) || s[n] == '='));
179
187
}
180
188
 
 
189
/* Return a pointer to the argument of the option with NAME.  If such
 
190
   an option is not given, it returns NULL. */
 
191
static char *
 
192
option_value (const char *line, const char *name)
 
193
{
 
194
  char *s;
 
195
  int n = strlen (name);
 
196
 
 
197
  s = strstr (line, name);
 
198
  if (s && (s == line || spacep (s-1))
 
199
      && s[n] && (spacep (s+n) || s[n] == '='))
 
200
    {
 
201
      s += n + 1;
 
202
      s += strspn (s, " ");
 
203
      if (*s && !spacep(s))
 
204
        return s;
 
205
    }
 
206
  return NULL;
 
207
}
 
208
 
181
209
 
182
210
/* Skip over options.  It is assumed that leading spaces have been
183
211
   removed (this is the case for lines passed to a handler from
208
236
}
209
237
 
210
238
 
211
 
/* Do the percent and plus/space unescaping in place and return the
212
 
   length of the valid buffer. */
213
 
static size_t
214
 
percent_plus_unescape (char *string)
215
 
{
216
 
  unsigned char *p = (unsigned char *)string;
217
 
  size_t n = 0;
218
 
 
219
 
  while (*string)
220
 
    {
221
 
      if (*string == '%' && string[1] && string[2])
222
 
        { 
223
 
          string++;
224
 
          *p++ = xtoi_2 (string);
225
 
          n++;
226
 
          string+= 2;
227
 
        }
228
 
      else if (*string == '+')
229
 
        {
230
 
          *p++ = ' ';
231
 
          n++;
232
 
          string++;
233
 
        }
234
 
      else
235
 
        {
236
 
          *p++ = *string++;
237
 
          n++;
238
 
        }
239
 
    }
240
 
 
241
 
  return n;
242
 
}
243
 
 
244
 
 
245
 
 
246
 
 
247
239
/* Parse a hex string.  Return an Assuan error code or 0 on success and the
248
240
   length of the parsed string in LEN. */
249
241
static int
308
300
          *p++ = ' ';
309
301
          n++;
310
302
        }
311
 
      for ( ; *text && n < DIM (buf)-2; n++)
312
 
        *p++ = *text++;
 
303
      for ( ; *text && n < DIM (buf)-3; n++, text++)
 
304
        {
 
305
          if (*text == '\n')
 
306
            {
 
307
              *p++ = '\\';
 
308
              *p++ = 'n';
 
309
            }
 
310
          else if (*text == '\r')
 
311
            {
 
312
              *p++ = '\\';
 
313
              *p++ = 'r';
 
314
            }
 
315
          else
 
316
            *p++ = *text;
 
317
        }
313
318
    }
314
319
  *p = 0;
315
320
  err = assuan_write_status (ctx, keyword, buf);
420
425
  for (p=line; i < 40; p++, i++)
421
426
    fpr[i] = *p >= 'a'? (*p & 0xdf): *p;
422
427
  fpr[i] = 0;
423
 
  rc = agent_istrusted (ctrl, fpr);
 
428
  rc = agent_istrusted (ctrl, fpr, NULL);
424
429
  if (!rc || gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
425
430
    return rc;
426
431
  else if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF )
596
601
    {
597
602
      if (has_option (line, "--hash=sha1"))
598
603
        algo = GCRY_MD_SHA1;
 
604
      else if (has_option (line, "--hash=sha224"))
 
605
        algo = GCRY_MD_SHA224;
599
606
      else if (has_option (line, "--hash=sha256"))
600
607
        algo = GCRY_MD_SHA256;
 
608
      else if (has_option (line, "--hash=sha384"))
 
609
        algo = GCRY_MD_SHA384;
 
610
      else if (has_option (line, "--hash=sha512"))
 
611
        algo = GCRY_MD_SHA512;
601
612
      else if (has_option (line, "--hash=rmd160"))
602
613
        algo = GCRY_MD_RMD160;
603
614
      else if (has_option (line, "--hash=md5"))
630
641
  n /= 2;
631
642
  if (algo == MD_USER_TLS_MD5SHA1 && n == 36)
632
643
    ;
633
 
  else if (n != 16 && n != 20 && n != 24 && n != 32)
 
644
  else if (n != 16 && n != 20 && n != 24 
 
645
           && n != 28 && n != 32 && n != 48 && n != 64)
634
646
    return set_error (GPG_ERR_ASS_PARAMETER, "unsupported length of hash");
635
647
 
636
648
  if (n > MAX_DIGEST_LEN)
806
818
}
807
819
 
808
820
 
809
 
 
 
821
 
 
822
/* KEYINFO [--list] <keygrip>
 
823
 
 
824
   Return information about the key specified by the KEYGRIP.  If the
 
825
   key is not available GPG_ERR_NOT_FOUND is returned.  If the option
 
826
   --list is given the keygrip is ignored and information about all
 
827
   available keys are returned.  The information is returned as a
 
828
   status line with this format:
 
829
 
 
830
     KEYINFO <keygrip> <type> <serialno> <idstr>
 
831
 
 
832
   KEYGRIP is the keygrip.
 
833
 
 
834
   TYPE is describes the type of the key:
 
835
       'D' - Regular key stored on disk,
 
836
       'T' - Key is stored on a smartcard (token).
 
837
       '-' - Unknown type.
 
838
 
 
839
   SERIALNO is an ASCII string with the serial number of the
 
840
            smartcard.  If the serial number is not known a single
 
841
            dash '-' is used instead.
 
842
 
 
843
   IDSTR is the IDSTR used to distinguish keys on a smartcard.  If it
 
844
         is not known a dash is used instead.
 
845
 
 
846
   More information may be added in the future.
 
847
*/
 
848
static gpg_error_t
 
849
do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip)
 
850
{
 
851
  gpg_error_t err;
 
852
  char hexgrip[40+1];
 
853
  int keytype;
 
854
  unsigned char *shadow_info = NULL;
 
855
  char *serialno = NULL;
 
856
  char *idstr = NULL;
 
857
  const char *keytypestr;
 
858
 
 
859
  err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info);
 
860
  if (err)
 
861
    goto leave;
 
862
 
 
863
  /* Reformat the grip so that we use uppercase as good style. */
 
864
  bin2hex (grip, 20, hexgrip);
 
865
      
 
866
  if (keytype == PRIVATE_KEY_CLEAR 
 
867
      || keytype == PRIVATE_KEY_PROTECTED)
 
868
    keytypestr = "D";
 
869
  else if (keytype == PRIVATE_KEY_SHADOWED)
 
870
    keytypestr = "T";
 
871
  else 
 
872
    keytypestr = "-";
 
873
      
 
874
  if (shadow_info)
 
875
    {
 
876
      err = parse_shadow_info (shadow_info, &serialno, &idstr);
 
877
      if (err)
 
878
        goto leave;
 
879
    }
 
880
      
 
881
  err = agent_write_status (ctrl, "KEYINFO",
 
882
                            hexgrip,
 
883
                            keytypestr,
 
884
                            serialno? serialno : "-",
 
885
                            idstr? idstr : "-",
 
886
                            NULL);
 
887
 leave:
 
888
  xfree (shadow_info);
 
889
  xfree (serialno);
 
890
  xfree (idstr);
 
891
  return err;
 
892
}
 
893
 
 
894
 
 
895
static int
 
896
cmd_keyinfo (assuan_context_t ctx, char *line)
 
897
{
 
898
  ctrl_t ctrl = assuan_get_pointer (ctx);
 
899
  int err;
 
900
  unsigned char grip[20];
 
901
  DIR *dir = NULL;
 
902
  int list_mode;
 
903
 
 
904
  list_mode = has_option (line, "--list");
 
905
  line = skip_options (line);
 
906
 
 
907
  if (list_mode)
 
908
    {
 
909
      char *dirname;
 
910
      struct dirent *dir_entry;
 
911
      char hexgrip[41];
 
912
      
 
913
      dirname = make_filename_try (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, NULL);
 
914
      if (!dirname)
 
915
        {
 
916
          err = gpg_error_from_syserror ();
 
917
          goto leave;
 
918
        }
 
919
      dir = opendir (dirname);
 
920
      if (!dir)
 
921
        {
 
922
          err = gpg_error_from_syserror ();
 
923
          xfree (dirname);
 
924
          goto leave;
 
925
        }
 
926
      xfree (dirname);
 
927
 
 
928
      while ( (dir_entry = readdir (dir)) )
 
929
        {
 
930
          if (strlen (dir_entry->d_name) != 44
 
931
              || strcmp (dir_entry->d_name + 40, ".key"))
 
932
            continue;
 
933
          strncpy (hexgrip, dir_entry->d_name, 40);
 
934
          hexgrip[40] = 0;
 
935
 
 
936
          if ( hex2bin (hexgrip, grip, 20) < 0 )
 
937
            continue; /* Bad hex string.  */
 
938
 
 
939
          err = do_one_keyinfo (ctrl, grip);
 
940
          if (err)
 
941
            goto leave;
 
942
        }
 
943
      err = 0;
 
944
    }
 
945
  else
 
946
    {
 
947
      err = parse_keygrip (ctx, line, grip);
 
948
      if (err)
 
949
        goto leave;
 
950
      err = do_one_keyinfo (ctrl, grip);
 
951
    }
 
952
      
 
953
 leave:
 
954
  if (dir)
 
955
    closedir (dir);
 
956
  if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND)
 
957
    log_error ("command keyinfo failed: %s\n", gpg_strerror (err));
 
958
  return err;
 
959
}
810
960
 
811
961
 
812
962
 
836
986
}
837
987
 
838
988
 
839
 
/* GET_PASSPHRASE [--data] [--check] [--no-ask] <cache_id>
 
989
/* GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]] 
 
990
                  [--qualitybar] <cache_id>
840
991
                  [<error_message> <prompt> <description>]
841
992
 
842
993
   This function is usually used to ask for a passphrase to be used
857
1008
   If the option "--no-ask" is used and the passphrase is not in the
858
1009
   cache the user will not be asked to enter a passphrase but the error
859
1010
   code GPG_ERR_NO_DATA is returned.  
 
1011
 
 
1012
   If the option "--qualitybar" is used a visual indication of the
 
1013
   entered passphrase quality is shown.  (Unless no minimum passphrase
 
1014
   length has been configured.)
860
1015
*/
861
1016
 
862
1017
static int
867
1022
  const char *pw;
868
1023
  char *response;
869
1024
  char *cacheid = NULL, *desc = NULL, *prompt = NULL, *errtext = NULL;
 
1025
  const char *desc2 = _("Please re-enter this passphrase");
870
1026
  char *p;
871
1027
  void *cache_marker;
872
 
  int opt_data, opt_check, opt_no_ask;
 
1028
  int opt_data, opt_check, opt_no_ask, opt_qualbar;
 
1029
  int opt_repeat = 0;
 
1030
  char *repeat_errtext = NULL;
873
1031
 
874
1032
  opt_data = has_option (line, "--data");
875
1033
  opt_check = has_option (line, "--check");
876
1034
  opt_no_ask = has_option (line, "--no-ask");
 
1035
  if (has_option_name (line, "--repeat"))
 
1036
    {
 
1037
      p = option_value (line, "--repeat");
 
1038
      if (p)
 
1039
        opt_repeat = atoi (p);
 
1040
      else
 
1041
        opt_repeat = 1;
 
1042
    }
 
1043
  opt_qualbar = has_option (line, "--qualitybar");
877
1044
  line = skip_options (line);
878
1045
 
879
1046
  cacheid = line;
940
1107
      if (desc)
941
1108
        plus_to_blank (desc);
942
1109
 
943
 
      response = NULL;
944
 
      do
945
 
        {
946
 
          xfree (response);
947
 
          rc = agent_get_passphrase (ctrl, &response, desc, prompt, errtext);
948
 
        }
949
 
      while (!rc
950
 
             && opt_check
951
 
             && check_passphrase_constraints (ctrl, response, 0));
952
 
 
 
1110
    next_try:
 
1111
      rc = agent_get_passphrase (ctrl, &response, desc, prompt, 
 
1112
                                 repeat_errtext? repeat_errtext:errtext, 
 
1113
                                 opt_qualbar);
 
1114
      xfree (repeat_errtext);
 
1115
      repeat_errtext = NULL;
953
1116
      if (!rc)
954
1117
        {
955
 
          if (cacheid)
956
 
            agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
957
 
          rc = send_back_passphrase (ctx, opt_data, response);
 
1118
          int i;
 
1119
 
 
1120
          if (opt_check && check_passphrase_constraints (ctrl, response, 0))
 
1121
            {
 
1122
              xfree (response);
 
1123
              goto next_try;
 
1124
            }
 
1125
          for (i = 0; i < opt_repeat; i++)
 
1126
            {
 
1127
              char *response2;
 
1128
 
 
1129
              rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
 
1130
                                         errtext, 0);
 
1131
              if (rc)
 
1132
                break;
 
1133
              if (strcmp (response2, response))
 
1134
                {
 
1135
                  xfree (response2);
 
1136
                  xfree (response);
 
1137
                  repeat_errtext = try_percent_escape 
 
1138
                    (_("does not match - try again"), NULL);
 
1139
                  if (!repeat_errtext)
 
1140
                    {
 
1141
                      rc = gpg_error_from_syserror ();
 
1142
                      break;
 
1143
                    }
 
1144
                  goto next_try;
 
1145
                }
 
1146
              xfree (response2);
 
1147
            }
 
1148
          if (!rc)
 
1149
            {
 
1150
              if (cacheid)
 
1151
                agent_put_cache (cacheid, CACHE_MODE_USER, response, 0);
 
1152
              rc = send_back_passphrase (ctx, opt_data, response);
 
1153
            }
958
1154
          xfree (response);
959
1155
        }
960
1156
    }
1033
1229
  if (desc)
1034
1230
    plus_to_blank (desc);
1035
1231
 
1036
 
  rc = agent_get_confirmation (ctrl, desc, NULL, NULL);
 
1232
  rc = agent_get_confirmation (ctrl, desc, NULL, NULL, 0);
1037
1233
  if (rc)
1038
1234
    log_error ("command get_confirmation failed: %s\n", gpg_strerror (rc));
1039
1235
  return rc;
1061
1257
 
1062
1258
/* PASSWD <hexstring_with_keygrip>
1063
1259
  
1064
 
   Change the passphrase/PID for the key identified by keygrip in LINE. */
 
1260
   Change the passphrase/PIN for the key identified by keygrip in LINE. */
1065
1261
static int
1066
1262
cmd_passwd (assuan_context_t ctx, char *line)
1067
1263
{
1077
1273
 
1078
1274
  ctrl->in_passwd++;
1079
1275
  rc = agent_key_from_file (ctrl, ctrl->server_local->keydesc,
1080
 
                            grip, &shadow_info, CACHE_MODE_IGNORE, &s_skey);
 
1276
                            grip, &shadow_info, CACHE_MODE_IGNORE, NULL, 
 
1277
                            &s_skey);
1081
1278
  if (rc)
1082
1279
    ;
1083
1280
  else if (!s_skey)
1270
1467
          p = strchr (value, ' ');
1271
1468
          if (p)
1272
1469
            *p = 0;
1273
 
          valuelen = percent_plus_unescape (value);
 
1470
          valuelen = percent_plus_unescape_inplace (value, 0);
1274
1471
        }
1275
1472
    }
1276
1473
  if (!key || !*key)
1397
1594
     socket_name - Return the name of the socket.
1398
1595
     ssh_socket_name - Return the name of the ssh socket.
1399
1596
     scd_running - Return OK if the SCdaemon is already running.
 
1597
 
 
1598
     cmd_has_option CMD OPT
 
1599
                 - Returns OK if the command CMD implements the option OPT.
1400
1600
 */
1401
1601
static int
1402
1602
cmd_getinfo (assuan_context_t ctx, char *line)
1437
1637
    {
1438
1638
      rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
1439
1639
    }
 
1640
  else if (!strncmp (line, "cmd_has_option", 14)
 
1641
           && (line[14] == ' ' || line[14] == '\t' || !line[14]))
 
1642
    {
 
1643
      char *cmd, *cmdopt;
 
1644
      line += 14;
 
1645
      while (*line == ' ' || *line == '\t')
 
1646
        line++;
 
1647
      if (!*line)
 
1648
        rc = gpg_error (GPG_ERR_MISSING_VALUE);
 
1649
      else
 
1650
        {
 
1651
          cmd = line;
 
1652
          while (*line && (*line != ' ' && *line != '\t'))
 
1653
            line++;
 
1654
          if (!*line)
 
1655
            rc = gpg_error (GPG_ERR_MISSING_VALUE);
 
1656
          else
 
1657
            {
 
1658
              *line++ = 0;
 
1659
              while (*line == ' ' || *line == '\t')
 
1660
                line++;
 
1661
              if (!*line)
 
1662
                rc = gpg_error (GPG_ERR_MISSING_VALUE);
 
1663
              else
 
1664
                {
 
1665
                  cmdopt = line;
 
1666
                  if (!command_has_option (cmd, cmdopt))
 
1667
                    rc = gpg_error (GPG_ERR_GENERAL);
 
1668
                }
 
1669
            }
 
1670
        }
 
1671
    }
1440
1672
  else
1441
1673
    rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
1442
1674
  return rc;
1563
1795
}
1564
1796
 
1565
1797
 
 
1798
/* Return true if the commznd CMD implements the option OPT.  */
 
1799
static int
 
1800
command_has_option (const char *cmd, const char *cmdopt)
 
1801
{
 
1802
  if (!strcmp (cmd, "GET_PASSPHRASE"))
 
1803
    {
 
1804
      if (!strcmp (cmdopt, "repeat"))
 
1805
          return 1;
 
1806
    }
 
1807
      
 
1808
  return 0;
 
1809
}
 
1810
 
 
1811
 
1566
1812
/* Tell the assuan library about our commands */
1567
1813
static int
1568
1814
register_commands (assuan_context_t ctx)
1574
1820
    { "GETEVENTCOUNTER",cmd_geteventcounter },
1575
1821
    { "ISTRUSTED",      cmd_istrusted },
1576
1822
    { "HAVEKEY",        cmd_havekey },
 
1823
    { "KEYINFO",        cmd_keyinfo },
1577
1824
    { "SIGKEY",         cmd_sigkey },
1578
1825
    { "SETKEY",         cmd_sigkey },
1579
1826
    { "SETKEYDESC",     cmd_setkeydesc },