1313#include "ask-password-api.h"
1414#include "crypt-util.h"
1515#include "cryptsetup-pkcs11.h"
16+ #include "cryptsetup-util.h"
1617#include "device-util.h"
1718#include "escape.h"
1819#include "fileio.h"
2122#include "hexdecoct.h"
2223#include "log.h"
2324#include "main-func.h"
25+ #include "memory-util.h"
2426#include "mount-util.h"
2527#include "nulstr-util.h"
2628#include "parse-util.h"
@@ -458,6 +460,8 @@ static int attach_tcrypt(
458460 struct crypt_device * cd ,
459461 const char * name ,
460462 const char * key_file ,
463+ const void * key_data ,
464+ size_t key_data_size ,
461465 char * * passwords ,
462466 uint32_t flags ) {
463467
@@ -471,7 +475,7 @@ static int attach_tcrypt(
471475
472476 assert (cd );
473477 assert (name );
474- assert (key_file || ( passwords && passwords [ 0 ] ));
478+ assert (key_file || key_data || ! strv_isempty ( passwords ));
475479
476480 if (arg_pkcs11_uri )
477481 /* Ask for a regular password */
@@ -487,23 +491,36 @@ static int attach_tcrypt(
487491 if (arg_tcrypt_veracrypt )
488492 params .flags |= CRYPT_TCRYPT_VERA_MODES ;
489493
490- if (key_file ) {
491- r = read_one_line_file (key_file , & passphrase );
492- if (r < 0 ) {
493- log_error_errno (r , "Failed to read password file '%s': %m" , key_file );
494- return - EAGAIN ; /* log with the actual error, but return EAGAIN */
495- }
494+ if (key_data ) {
495+ params .passphrase = key_data ;
496+ params .passphrase_size = key_data_size ;
497+ } else {
498+ if (key_file ) {
499+ r = read_one_line_file (key_file , & passphrase );
500+ if (r < 0 ) {
501+ log_error_errno (r , "Failed to read password file '%s': %m" , key_file );
502+ return - EAGAIN ; /* log with the actual error, but return EAGAIN */
503+ }
496504
497- params .passphrase = passphrase ;
498- } else
499- params .passphrase = passwords [0 ];
500- params .passphrase_size = strlen (params .passphrase );
505+ params .passphrase = passphrase ;
506+ } else
507+ params .passphrase = passwords [0 ];
508+
509+ params .passphrase_size = strlen (params .passphrase );
510+ }
501511
502512 r = crypt_load (cd , CRYPT_TCRYPT , & params );
503513 if (r < 0 ) {
504- if (key_file && r == - EPERM ) {
505- log_error_errno (r , "Failed to activate using password file '%s'. (Key data not correct?)" , key_file );
506- return - EAGAIN ; /* log the actual error, but return EAGAIN */
514+ if (r == - EPERM ) {
515+ if (key_data ) {
516+ log_error_errno (r , "Failed to activate using discovered key. (Key not correct?)" );
517+ return - EAGAIN ; /* log the actual error, but return EAGAIN */
518+ }
519+
520+ if (key_file ) {
521+ log_error_errno (r , "Failed to activate using password file '%s'. (Key data not correct?)" , key_file );
522+ return - EAGAIN ; /* log the actual error, but return EAGAIN */
523+ }
507524 }
508525
509526 return log_error_errno (r , "Failed to load tcrypt superblock on device %s: %m" , crypt_get_device_name (cd ));
@@ -520,6 +537,8 @@ static int attach_luks_or_plain(
520537 struct crypt_device * cd ,
521538 const char * name ,
522539 const char * key_file ,
540+ const void * key_data ,
541+ size_t key_data_size ,
523542 char * * passwords ,
524543 uint32_t flags ,
525544 usec_t until ) {
@@ -589,7 +608,7 @@ static int attach_luks_or_plain(
589608 _cleanup_free_ char * friendly = NULL ;
590609 size_t decrypted_key_size = 0 ;
591610
592- if (!key_file )
611+ if (!key_file && ! key_data )
593612 return log_error_errno (SYNTHETIC_ERRNO (EINVAL ), "PKCS#11 mode selected but no key file specified, refusing." );
594613
595614 friendly = friendly_disk_name (crypt_get_device_name (cd ), name );
@@ -602,8 +621,8 @@ static int attach_luks_or_plain(
602621 r = decrypt_pkcs11_key (
603622 friendly ,
604623 arg_pkcs11_uri ,
605- key_file ,
606- arg_keyfile_size , arg_keyfile_offset ,
624+ key_file , arg_keyfile_size , arg_keyfile_offset ,
625+ key_data , key_data_size ,
607626 until ,
608627 & decrypted_key , & decrypted_key_size );
609628 if (r >= 0 )
@@ -686,6 +705,18 @@ static int attach_luks_or_plain(
686705 if (r < 0 )
687706 return log_error_errno (r , "Failed to activate with PKCS#11 acquired key: %m" );
688707
708+ } else if (key_data ) {
709+ if (pass_volume_key )
710+ r = crypt_activate_by_volume_key (cd , name , key_data , key_data_size , flags );
711+ else
712+ r = crypt_activate_by_passphrase (cd , name , arg_key_slot , key_data , key_data_size , flags );
713+ if (r == - EPERM ) {
714+ log_error_errno (r , "Failed to activate. (Key incorrect?)" );
715+ return - EAGAIN ; /* Log actual error, but return EAGAIN */
716+ }
717+ if (r < 0 )
718+ return log_error_errno (r , "Failed to activate: %m" );
719+
689720 } else if (key_file ) {
690721 r = crypt_activate_by_keyfile_device_offset (cd , name , arg_key_slot , key_file , arg_keyfile_size , arg_keyfile_offset , flags );
691722 if (r == - EPERM ) {
@@ -805,12 +836,17 @@ static int run(int argc, char *argv[]) {
805836 crypt_status_info status ;
806837 _cleanup_ (remove_and_erasep ) const char * destroy_key_file = NULL ;
807838 const char * key_file = NULL ;
839+ _cleanup_ (erase_and_freep ) void * key_data = NULL ;
840+ size_t key_data_size = 0 ;
808841
809842 /* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [PASSWORD] [OPTIONS] */
810843
811844 if (argc < 4 )
812845 return log_error_errno (SYNTHETIC_ERRNO (EINVAL ), "attach requires at least two arguments." );
813846
847+ if (!filename_is_valid (argv [2 ]))
848+ return log_error_errno (SYNTHETIC_ERRNO (EINVAL ), "Volume name '%s' is not valid." , argv [2 ]);
849+
814850 if (argc >= 5 && !STR_IN_SET (argv [4 ], "" , "-" , "none" )) {
815851 if (path_is_absolute (argv [4 ]))
816852 key_file = argv [4 ];
@@ -827,7 +863,22 @@ static int run(int argc, char *argv[]) {
827863 /* A delicious drop of snake oil */
828864 (void ) mlockall (MCL_FUTURE );
829865
830- if (key_file && arg_keyfile_erase )
866+ if (!key_file ) {
867+ const char * fn ;
868+
869+ /* If a key file is not explicitly specified, search for a key in a well defined
870+ * search path, and load it. */
871+
872+ fn = strjoina (argv [2 ], ".key" );
873+ r = load_key_file (fn ,
874+ STRV_MAKE ("/etc/cryptsetup-keys.d" , "/run/cryptsetup-keys.d" ),
875+ 0 , 0 , /* Note we leave arg_keyfile_offset/arg_keyfile_size as something that only applies to arg_keyfile! */
876+ & key_data , & key_data_size );
877+ if (r < 0 )
878+ return r ;
879+ if (r > 0 )
880+ log_debug ("Automatically discovered key for volume '%s'." , argv [2 ]);
881+ } else if (arg_keyfile_erase )
831882 destroy_key_file = key_file ; /* let's get this baby erased when we leave */
832883
833884 if (arg_header ) {
@@ -876,7 +927,7 @@ static int run(int argc, char *argv[]) {
876927 }
877928
878929 /* Tokens are available in LUKS2 only, but it is ok to call (and fail) with LUKS1. */
879- if (!key_file ) {
930+ if (!key_file && ! key_data ) {
880931 r = crypt_activate_by_token (cd , argv [2 ], CRYPT_ANY_TOKEN , NULL , flags );
881932 if (r >= 0 ) {
882933 log_debug ("Volume %s activated with LUKS token id %i." , argv [2 ], r );
@@ -890,7 +941,7 @@ static int run(int argc, char *argv[]) {
890941 for (tries = 0 ; arg_tries == 0 || tries < arg_tries ; tries ++ ) {
891942 _cleanup_strv_free_erase_ char * * passwords = NULL ;
892943
893- if (!key_file && !arg_pkcs11_uri ) {
944+ if (!key_file && !key_data && ! arg_pkcs11_uri ) {
894945 r = get_password (argv [2 ], argv [3 ], until , tries == 0 && !arg_verify , & passwords );
895946 if (r == - EAGAIN )
896947 continue ;
@@ -899,16 +950,18 @@ static int run(int argc, char *argv[]) {
899950 }
900951
901952 if (streq_ptr (arg_type , CRYPT_TCRYPT ))
902- r = attach_tcrypt (cd , argv [2 ], key_file , passwords , flags );
953+ r = attach_tcrypt (cd , argv [2 ], key_file , key_data , key_data_size , passwords , flags );
903954 else
904- r = attach_luks_or_plain (cd , argv [2 ], key_file , passwords , flags , until );
955+ r = attach_luks_or_plain (cd , argv [2 ], key_file , key_data , key_data_size , passwords , flags , until );
905956 if (r >= 0 )
906957 break ;
907958 if (r != - EAGAIN )
908959 return r ;
909960
910961 /* Passphrase not correct? Let's try again! */
911962 key_file = NULL ;
963+ key_data = erase_and_free (key_data );
964+ key_data_size = 0 ;
912965 arg_pkcs11_uri = NULL ;
913966 }
914967
@@ -917,6 +970,9 @@ static int run(int argc, char *argv[]) {
917970
918971 } else if (streq (argv [1 ], "detach" )) {
919972
973+ if (!filename_is_valid (argv [2 ]))
974+ return log_error_errno (SYNTHETIC_ERRNO (EINVAL ), "Volume name '%s' is not valid." , argv [2 ]);
975+
920976 r = crypt_init_by_name (& cd , argv [2 ]);
921977 if (r == - ENODEV ) {
922978 log_info ("Volume %s already inactive." , argv [2 ]);
0 commit comments