Print this page
5857 add -o option to lofiadm
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Andy Stormont <astormont@racktopsystems.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/lofiadm/main.c
          +++ new/usr/src/cmd/lofiadm/main.c
↓ open down ↓ 17 lines elided ↑ open up ↑
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   * Copyright 2012 Joyent, Inc.  All rights reserved.
  25   25   *
  26   26   * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  27   27   * Copyright (c) 2014 Gary Mills
       28 + * Copyright (c) 2016 Andrey Sokolov
  28   29   */
  29   30  
  30   31  /*
  31   32   * lofiadm - administer lofi(7d). Very simple, add and remove file<->device
  32   33   * associations, and display status. All the ioctls are private between
  33   34   * lofi and lofiadm, and so are very simple - device information is
  34   35   * communicated via a minor number.
  35   36   */
  36   37  
  37   38  #include <sys/types.h>
↓ open down ↓ 108 lines elided ↑ open up ↑
 146  147  
 147  148  #define COMPRESS_ALGORITHM      "gzip"
 148  149  #define COMPRESS_THRESHOLD      2048
 149  150  #define SEGSIZE                 131072
 150  151  #define BLOCK_SIZE              512
 151  152  #define KILOBYTE                1024
 152  153  #define MEGABYTE                (KILOBYTE * KILOBYTE)
 153  154  #define GIGABYTE                (KILOBYTE * MEGABYTE)
 154  155  #define LIBZ                    "libz.so.1"
 155  156  
      157 +const char lofi_crypto_magic[6] = LOFI_CRYPTO_MAGIC;
      158 +
 156  159  static void
 157  160  usage(const char *pname)
 158  161  {
 159  162          (void) fprintf(stderr, gettext(USAGE), pname, pname, pname,
 160  163              pname, pname, pname, pname, pname, pname, pname);
 161  164          exit(E_USAGE);
 162  165  }
 163  166  
 164  167  static int
 165  168  gzip_compress(void *src, size_t srclen, void *dst, size_t *dstlen, int level)
↓ open down ↓ 42 lines elided ↑ open up ↑
 208  211          SzAlloc,
 209  212          SzFree
 210  213  };
 211  214  
 212  215  #define LZMA_UNCOMPRESSED_SIZE  8
 213  216  #define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + LZMA_UNCOMPRESSED_SIZE)
 214  217  
 215  218  /*ARGSUSED*/
 216  219  static int
 217  220  lzma_compress(void *src, size_t srclen, void *dst,
 218      -        size_t *dstlen, int level)
      221 +    size_t *dstlen, int level)
 219  222  {
 220  223          CLzmaEncProps props;
 221  224          size_t outsize2;
 222  225          size_t outsizeprocessed;
 223  226          size_t outpropssize = LZMA_PROPS_SIZE;
 224  227          uint64_t t = 0;
 225  228          SRes res;
 226  229          Byte *dstp;
 227  230          int i;
 228  231  
↓ open down ↓ 599 lines elided ↑ open up ↑
 828  831           */
 829  832          if (ti->name == NULL && ti->mfr == NULL && ti->serno == NULL)
 830  833                  ti->name = strdup(pkcs11_default_token());
 831  834          return (ti);
 832  835  }
 833  836  
 834  837  /*
 835  838   * PBE the passphrase into a raw key
 836  839   */
 837  840  static void
 838      -getkeyfromuser(mech_alias_t *cipher, char **raw_key, size_t *raw_key_sz)
      841 +getkeyfromuser(mech_alias_t *cipher, char **raw_key, size_t *raw_key_sz,
      842 +    boolean_t with_confirmation)
 839  843  {
 840  844          CK_SESSION_HANDLE sess;
 841  845          CK_RV   rv;
 842  846          char    *pass = NULL;
 843  847          size_t  passlen = 0;
 844  848          void    *salt = NULL;   /* don't use NULL, see note on salt below */
 845  849          size_t  saltlen = 0;
 846  850          CK_KEY_TYPE ktype;
 847  851          void    *kvalue;
 848  852          size_t  klen;
↓ open down ↓ 10 lines elided ↑ open up ↑
 859  863  
 860  864          /*
 861  865           * use the passphrase to generate a PBE PKCS#5 secret key and
 862  866           * retrieve the raw key data to eventually pass it to the kernel;
 863  867           */
 864  868          rv = C_OpenSession(cipher->slot, CKF_SERIAL_SESSION, NULL, NULL, &sess);
 865  869          if (rv != CKR_OK)
 866  870                  goto cleanup;
 867  871  
 868  872          /* get user passphrase with 8 byte minimum */
 869      -        if (pkcs11_get_pass(NULL, &pass, &passlen, MIN_PASSLEN, B_TRUE) < 0) {
      873 +        if (pkcs11_get_pass(NULL, &pass, &passlen, MIN_PASSLEN,
      874 +            with_confirmation) < 0) {
 870  875                  die(gettext("passphrases do not match\n"));
 871  876          }
 872  877  
 873  878          /*
 874  879           * salt should not be NULL, or else pkcs11_PasswdToKey() will
 875  880           * complain about CKR_MECHANISM_PARAM_INVALID; the following is
 876  881           * to make up for not having a salt until a proper one is used
 877  882           */
 878  883          salt = pass;
 879  884          saltlen = passlen;
↓ open down ↓ 872 lines elided ↑ open up ↑
1752 1757                  die(gettext("size of %s is not a multiple of %d\n"),
1753 1758                      filename, DEV_BSIZE);
1754 1759          }
1755 1760          (void) close(fd);
1756 1761  
1757 1762          if (name_to_minor(filename) != 0) {
1758 1763                  die(gettext("cannot use %s on itself\n"), LOFI_DRIVER_NAME);
1759 1764          }
1760 1765  }
1761 1766  
     1767 +static boolean_t
     1768 +check_file_is_encrypted(const char *filename)
     1769 +{
     1770 +        int     fd;
     1771 +        char    buf[sizeof (lofi_crypto_magic)];
     1772 +        int     got;
     1773 +        int     rest = sizeof (lofi_crypto_magic);
     1774 +
     1775 +        fd = open64(filename, O_RDONLY);
     1776 +        if (fd == -1)
     1777 +                die(gettext("failed to open: %s"), filename);
     1778 +
     1779 +        if (lseek(fd, CRYOFF, SEEK_SET) != CRYOFF)
     1780 +                die(gettext("failed to seek to offset 0x%lx in file %s"),
     1781 +                    CRYOFF, filename);
     1782 +
     1783 +        do {
     1784 +                got = read(fd, buf + sizeof (lofi_crypto_magic) - rest, rest);
     1785 +                if ((got == 0) || ((got == -1) && (errno != EINTR)))
     1786 +                        die(gettext("failed to read crypto header"
     1787 +                            " at offset 0x%lx in file %s"), CRYOFF, filename);
     1788 +
     1789 +                if (got > 0)
     1790 +                        rest -= got;
     1791 +        } while (rest > 0);
     1792 +
     1793 +        while (close(fd) == -1) {
     1794 +                if (errno != EINTR)
     1795 +                        die(gettext("failed to close file %s"), filename);
     1796 +        }
     1797 +
     1798 +        return (strncmp(buf, lofi_crypto_magic,
     1799 +            sizeof (lofi_crypto_magic)) == 0);
     1800 +}
     1801 +
1762 1802  static uint32_t
1763 1803  convert_to_num(const char *str)
1764 1804  {
1765 1805          int len;
1766 1806          uint32_t segsize, mult = 1;
1767 1807  
1768 1808          len = strlen(str);
1769 1809          if (len && isalpha(str[len - 1])) {
1770 1810                  switch (str[len - 1]) {
1771 1811                  case 'k':
↓ open down ↓ 53 lines elided ↑ open up ↑
1825 1865          token_spec_t *token = NULL;
1826 1866          char    *rkey = NULL;
1827 1867          size_t  rksz = 0;
1828 1868          char realfilename[MAXPATHLEN];
1829 1869  
1830 1870          pname = getpname(argv[0]);
1831 1871  
1832 1872          (void) setlocale(LC_ALL, "");
1833 1873          (void) textdomain(TEXT_DOMAIN);
1834 1874  
1835      -        while ((c = getopt(argc, argv, "a:c:Cd:efk:o:rs:T:U")) != EOF) {
     1875 +        while ((c = getopt(argc, argv, "a:c:Cd:efk:rs:T:U")) != EOF) {
1836 1876                  switch (c) {
1837 1877                  case 'a':
1838 1878                          addflag = B_TRUE;
1839 1879                          if ((filename = realpath(optarg, realfilename)) == NULL)
1840 1880                                  die("%s", optarg);
1841 1881                          if (((argc - optind) > 0) && (*argv[optind] != '-')) {
1842 1882                                  /* optional device */
1843 1883                                  devicename = argv[optind];
1844 1884                                  optind++;
1845 1885                          }
↓ open down ↓ 168 lines elided ↑ open up ↑
2014 2054                          cipher = DEFAULT_CIPHER;
2015 2055  
2016 2056                  if (!kernel_cipher_check(cipher))
2017 2057                          die(gettext(
2018 2058                              "use \"cryptoadm list -m\" to find available "
2019 2059                              "mechanisms\n"));
2020 2060  
2021 2061                  init_crypto(token, cipher, &sess);
2022 2062  
2023 2063                  if (cipher_only) {
2024      -                        getkeyfromuser(cipher, &rkey, &rksz);
     2064 +                        getkeyfromuser(cipher, &rkey, &rksz,
     2065 +                            !check_file_is_encrypted(filename));
2025 2066                  } else if (token != NULL) {
2026 2067                          getkeyfromtoken(sess, token, keyfile, cipher,
2027 2068                              &rkey, &rksz);
2028 2069                  } else {
2029 2070                          /* this also handles ephemeral keys */
2030 2071                          getkeyfromfile(keyfile, cipher, &rkey, &rksz);
2031 2072                  }
2032 2073  
2033 2074                  end_crypto(sess);
2034 2075          }
↓ open down ↓ 23 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX