2020-11-09 05:23:58 +01:00
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2016-12-16 12:57:44 +01:00
2018-01-11 00:39:12 +01:00
# include <errno.h>
2016-12-16 12:57:44 +01:00
# include <stdio.h>
# include <sys/stat.h>
2018-01-11 00:39:12 +01:00
# include "alloc-util.h"
2020-08-28 21:26:33 +02:00
# include "cryptsetup-util.h"
2020-06-04 18:41:28 +02:00
# include "fileio.h"
2016-12-16 12:57:44 +01:00
# include "hexdecoct.h"
2018-01-11 00:39:12 +01:00
# include "log.h"
2018-11-22 20:21:08 +01:00
# include "main-func.h"
2020-06-04 18:41:28 +02:00
# include "path-util.h"
2018-11-20 15:42:57 +01:00
# include "pretty-print.h"
2016-12-16 12:57:44 +01:00
# include "string-util.h"
2018-08-09 10:32:31 +02:00
# include "terminal-util.h"
2016-12-16 12:57:44 +01:00
static char * arg_root_hash = NULL ;
static char * arg_data_what = NULL ;
static char * arg_hash_what = NULL ;
2018-11-22 20:21:08 +01:00
STATIC_DESTRUCTOR_REGISTER ( arg_root_hash , freep ) ;
STATIC_DESTRUCTOR_REGISTER ( arg_data_what , freep ) ;
STATIC_DESTRUCTOR_REGISTER ( arg_hash_what , freep ) ;
2016-12-16 12:57:44 +01:00
static int help ( void ) {
2018-08-09 10:32:31 +02:00
_cleanup_free_ char * link = NULL ;
int r ;
r = terminal_urlify_man ( " systemd-veritysetup@.service " , " 8 " , & link ) ;
if ( r < 0 )
return log_oom ( ) ;
2020-06-04 18:41:28 +02:00
printf ( " %s attach VOLUME DATADEVICE HASHDEVICE ROOTHASH [ROOTHASHSIG] \n "
2016-12-16 12:57:44 +01:00
" %s detach VOLUME \n \n "
2018-08-09 10:32:31 +02:00
" Attaches or detaches an integrity protected block device. \n "
" \n See the %s for details. \n "
, program_invocation_short_name
, program_invocation_short_name
, link
) ;
2016-12-16 12:57:44 +01:00
return 0 ;
}
2018-11-22 20:21:08 +01:00
static int run ( int argc , char * argv [ ] ) {
2017-11-02 09:16:47 +01:00
_cleanup_ ( crypt_freep ) struct crypt_device * cd = NULL ;
2016-12-16 12:57:44 +01:00
int r ;
2018-11-22 20:21:08 +01:00
if ( argc < = 1 )
return help ( ) ;
2016-12-16 12:57:44 +01:00
2018-11-22 20:21:08 +01:00
if ( argc < 3 )
return log_error_errno ( SYNTHETIC_ERRNO ( EINVAL ) , " This program requires at least two arguments. " ) ;
2016-12-16 12:57:44 +01:00
2018-11-20 11:18:22 +01:00
log_setup_service ( ) ;
2016-12-16 12:57:44 +01:00
umask ( 0022 ) ;
if ( streq ( argv [ 1 ] , " attach " ) ) {
_cleanup_free_ void * m = NULL ;
crypt_status_info status ;
size_t l ;
2018-11-22 20:21:08 +01:00
if ( argc < 6 )
return log_error_errno ( SYNTHETIC_ERRNO ( EINVAL ) , " attach requires at least two arguments. " ) ;
2016-12-16 12:57:44 +01:00
r = unhexmem ( argv [ 5 ] , strlen ( argv [ 5 ] ) , & m , & l ) ;
2018-11-22 20:21:08 +01:00
if ( r < 0 )
return log_error_errno ( r , " Failed to parse root hash: %m " ) ;
2016-12-16 12:57:44 +01:00
r = crypt_init ( & cd , argv [ 4 ] ) ;
2018-11-22 20:21:08 +01:00
if ( r < 0 )
return log_error_errno ( r , " Failed to open verity device %s: %m " , argv [ 4 ] ) ;
2016-12-16 12:57:44 +01:00
2020-08-10 12:45:07 +02:00
cryptsetup_enable_logging ( cd ) ;
2016-12-16 12:57:44 +01:00
status = crypt_status ( cd , argv [ 2 ] ) ;
2017-09-29 00:37:23 +02:00
if ( IN_SET ( status , CRYPT_ACTIVE , CRYPT_BUSY ) ) {
2016-12-16 12:57:44 +01:00
log_info ( " Volume %s already active. " , argv [ 2 ] ) ;
2018-11-22 20:21:08 +01:00
return 0 ;
2016-12-16 12:57:44 +01:00
}
r = crypt_load ( cd , CRYPT_VERITY , NULL ) ;
2018-11-22 20:21:08 +01:00
if ( r < 0 )
return log_error_errno ( r , " Failed to load verity superblock: %m " ) ;
2016-12-16 12:57:44 +01:00
r = crypt_set_data_device ( cd , argv [ 3 ] ) ;
2018-11-22 20:21:08 +01:00
if ( r < 0 )
return log_error_errno ( r , " Failed to configure data device: %m " ) ;
2016-12-16 12:57:44 +01:00
2020-06-04 18:41:28 +02:00
if ( argc > 6 ) {
# if HAVE_CRYPT_ACTIVATE_BY_SIGNED_KEY
_cleanup_free_ char * hash_sig = NULL ;
size_t hash_sig_size ;
char * value ;
if ( ( value = startswith ( argv [ 6 ] , " base64: " ) ) ) {
r = unbase64mem ( value , strlen ( value ) , ( void * ) & hash_sig , & hash_sig_size ) ;
if ( r < 0 )
return log_error_errno ( r , " Failed to parse root hash signature '%s': %m " , argv [ 6 ] ) ;
} else {
2020-11-04 20:25:06 +01:00
r = read_full_file_full (
AT_FDCWD , argv [ 6 ] , UINT64_MAX , SIZE_MAX ,
READ_FULL_FILE_CONNECT_SOCKET ,
NULL ,
& hash_sig , & hash_sig_size ) ;
2020-06-04 18:41:28 +02:00
if ( r < 0 )
return log_error_errno ( r , " Failed to read root hash signature: %m " ) ;
}
r = crypt_activate_by_signed_key ( cd , argv [ 2 ] , m , l , hash_sig , hash_sig_size , CRYPT_ACTIVATE_READONLY ) ;
# else
return log_error_errno ( SYNTHETIC_ERRNO ( EOPNOTSUPP ) , " activation of verity device with signature %s requested, but not supported by cryptsetup due to missing crypt_activate_by_signed_key() " , argv [ 6 ] ) ;
# endif
} else
r = crypt_activate_by_volume_key ( cd , argv [ 2 ] , m , l , CRYPT_ACTIVATE_READONLY ) ;
2018-11-22 20:21:08 +01:00
if ( r < 0 )
return log_error_errno ( r , " Failed to set up verity device: %m " ) ;
2016-12-16 12:57:44 +01:00
} else if ( streq ( argv [ 1 ] , " detach " ) ) {
r = crypt_init_by_name ( & cd , argv [ 2 ] ) ;
if ( r = = - ENODEV ) {
log_info ( " Volume %s already inactive. " , argv [ 2 ] ) ;
2018-11-22 20:21:08 +01:00
return 0 ;
2016-12-16 12:57:44 +01:00
}
2018-11-22 20:21:08 +01:00
if ( r < 0 )
return log_error_errno ( r , " crypt_init_by_name() failed : % m " ) ;
2016-12-16 12:57:44 +01:00
2020-08-10 12:45:07 +02:00
cryptsetup_enable_logging ( cd ) ;
2016-12-16 12:57:44 +01:00
r = crypt_deactivate ( cd , argv [ 2 ] ) ;
2018-11-22 20:21:08 +01:00
if ( r < 0 )
return log_error_errno ( r , " Failed to deactivate: %m " ) ;
2016-12-16 12:57:44 +01:00
2018-11-22 20:21:08 +01:00
} else
return log_error_errno ( SYNTHETIC_ERRNO ( EINVAL ) , " Unknown verb %s. " , argv [ 1 ] ) ;
2016-12-16 12:57:44 +01:00
2018-11-22 20:21:08 +01:00
return 0 ;
2016-12-16 12:57:44 +01:00
}
2018-11-22 20:21:08 +01:00
DEFINE_MAIN_FUNCTION ( run ) ;