2017-11-18 17:09:20 +01:00
/* SPDX-License-Identifier: LGPL-2.1+ */
2010-09-17 01:26:29 +02:00
# include <errno.h>
# include <getopt.h>
2010-10-07 02:34:17 +02:00
# include <stddef.h>
2015-10-06 16:27:24 +02:00
# include <unistd.h>
2010-09-17 01:26:29 +02:00
2015-10-06 16:27:24 +02:00
# include "ask-password-api.h"
# include "def.h"
2010-09-17 01:26:29 +02:00
# include "log.h"
# include "macro.h"
2018-11-20 15:14:16 +09:00
# include "main-func.h"
2011-02-23 01:12:07 +01:00
# include "strv.h"
2018-08-09 10:32:31 +02:00
# include "terminal-util.h"
2010-09-17 01:26:29 +02:00
static const char * arg_icon = NULL ;
2014-03-25 11:05:23 +01:00
static const char * arg_id = NULL ;
2015-10-07 11:26:10 +02:00
static const char * arg_keyname = NULL ;
static char * arg_message = NULL ;
2011-04-14 02:30:43 +02:00
static usec_t arg_timeout = DEFAULT_TIMEOUT_USEC ;
2011-02-23 01:12:07 +01:00
static bool arg_multiple = false ;
2016-02-29 21:04:02 +01:00
static bool arg_no_output = false ;
2015-10-07 11:26:10 +02:00
static AskPasswordFlags arg_flags = ASK_PASSWORD_PUSH_CACHE ;
2010-09-17 01:26:29 +02:00
2018-11-20 15:14:16 +09:00
STATIC_DESTRUCTOR_REGISTER ( arg_message , freep ) ;
2018-08-09 10:32:31 +02:00
static int help ( void ) {
_cleanup_free_ char * link = NULL ;
int r ;
r = terminal_urlify_man ( " systemd-ask-password " , " 1 " , & link ) ;
if ( r < 0 )
return log_oom ( ) ;
2010-09-17 01:26:29 +02:00
printf ( " %s [OPTIONS...] MESSAGE \n \n "
2010-09-17 02:13:12 +02:00
" Query the user for a system passphrase, via the TTY or an UI agent. \n \n "
2015-10-07 11:26:10 +02:00
" -h --help Show this help \n "
" --icon=NAME Icon name \n "
" --id=ID Query identifier (e.g. \" cryptsetup:/dev/sda5 \" ) \n "
" --keyname=NAME Kernel key name for caching passwords (e.g. \" cryptsetup \" ) \n "
" --timeout=SEC Timeout in seconds \n "
" --echo Do not mask input (useful for usernames) \n "
" --no-tty Ask question via agent even on TTY \n "
" --accept-cached Accept cached passwords \n "
" --multiple List multiple passwords if available \n "
2016-02-29 21:04:02 +01:00
" --no-output Do not print password to standard output \n "
2018-08-09 10:32:31 +02:00
" \n See the %s for details. \n "
, program_invocation_short_name
, link
) ;
return 0 ;
2010-09-17 01:26:29 +02:00
}
static int parse_argv ( int argc , char * argv [ ] ) {
enum {
ARG_ICON = 0x100 ,
2010-09-17 02:10:08 +02:00
ARG_TIMEOUT ,
2014-10-03 15:53:45 +02:00
ARG_ECHO ,
2011-02-23 01:12:07 +01:00
ARG_NO_TTY ,
ARG_ACCEPT_CACHED ,
2014-03-25 11:05:23 +01:00
ARG_MULTIPLE ,
2015-10-07 11:26:10 +02:00
ARG_ID ,
ARG_KEYNAME ,
2016-02-29 21:04:02 +01:00
ARG_NO_OUTPUT ,
2018-08-09 10:32:31 +02:00
ARG_VERSION ,
2010-09-17 01:26:29 +02:00
} ;
static const struct option options [ ] = {
2011-02-23 01:12:07 +01:00
{ " help " , no_argument , NULL , ' h ' } ,
2018-08-09 10:32:31 +02:00
{ " version " , no_argument , NULL , ARG_VERSION } ,
2011-02-23 01:12:07 +01:00
{ " icon " , required_argument , NULL , ARG_ICON } ,
{ " timeout " , required_argument , NULL , ARG_TIMEOUT } ,
2014-10-03 15:53:45 +02:00
{ " echo " , no_argument , NULL , ARG_ECHO } ,
2011-02-23 01:12:07 +01:00
{ " no-tty " , no_argument , NULL , ARG_NO_TTY } ,
{ " accept-cached " , no_argument , NULL , ARG_ACCEPT_CACHED } ,
{ " multiple " , no_argument , NULL , ARG_MULTIPLE } ,
2014-03-25 11:05:23 +01:00
{ " id " , required_argument , NULL , ARG_ID } ,
2015-10-07 11:26:10 +02:00
{ " keyname " , required_argument , NULL , ARG_KEYNAME } ,
2016-02-29 21:04:02 +01:00
{ " no-output " , no_argument , NULL , ARG_NO_OUTPUT } ,
2013-11-06 18:28:39 +01:00
{ }
2010-09-17 01:26:29 +02:00
} ;
int c ;
assert ( argc > = 0 ) ;
assert ( argv ) ;
2014-08-02 11:12:21 -04:00
while ( ( c = getopt_long ( argc , argv , " h " , options , NULL ) ) > = 0 )
2010-09-17 01:26:29 +02:00
switch ( c ) {
case ' h ' :
2018-08-09 10:32:31 +02:00
return help ( ) ;
case ARG_VERSION :
return version ( ) ;
2010-09-17 01:26:29 +02:00
case ARG_ICON :
arg_icon = optarg ;
break ;
case ARG_TIMEOUT :
2013-04-02 20:38:16 +02:00
if ( parse_sec ( optarg , & arg_timeout ) < 0 ) {
2010-09-17 01:26:29 +02:00
log_error ( " Failed to parse --timeout parameter %s " , optarg ) ;
return - EINVAL ;
}
break ;
2014-10-03 15:53:45 +02:00
case ARG_ECHO :
2015-10-07 11:26:10 +02:00
arg_flags | = ASK_PASSWORD_ECHO ;
2014-10-03 15:53:45 +02:00
break ;
2010-09-17 02:10:08 +02:00
case ARG_NO_TTY :
2015-10-07 11:26:10 +02:00
arg_flags | = ASK_PASSWORD_NO_TTY ;
2010-09-17 02:10:08 +02:00
break ;
2011-02-23 01:12:07 +01:00
case ARG_ACCEPT_CACHED :
2015-10-07 11:26:10 +02:00
arg_flags | = ASK_PASSWORD_ACCEPT_CACHED ;
2011-02-23 01:12:07 +01:00
break ;
case ARG_MULTIPLE :
arg_multiple = true ;
break ;
2014-03-25 11:05:23 +01:00
case ARG_ID :
arg_id = optarg ;
break ;
2015-10-07 11:26:10 +02:00
case ARG_KEYNAME :
arg_keyname = optarg ;
break ;
2016-02-29 21:04:02 +01:00
case ARG_NO_OUTPUT :
arg_no_output = true ;
break ;
2010-09-17 01:26:29 +02:00
case ' ? ' :
return - EINVAL ;
default :
2013-11-06 18:28:39 +01:00
assert_not_reached ( " Unhandled option " ) ;
2010-09-17 01:26:29 +02:00
}
2015-10-07 11:26:10 +02:00
if ( argc > optind ) {
arg_message = strv_join ( argv + optind , " " ) ;
if ( ! arg_message )
return log_oom ( ) ;
2010-09-17 01:26:29 +02:00
}
2010-09-17 02:10:08 +02:00
return 1 ;
2010-09-17 01:26:29 +02:00
}
2018-11-20 15:14:16 +09:00
static int run ( int argc , char * argv [ ] ) {
2015-10-15 10:02:35 -04:00
_cleanup_strv_free_erase_ char * * l = NULL ;
2011-04-13 21:42:46 +02:00
usec_t timeout ;
2015-10-07 11:26:10 +02:00
char * * p ;
int r ;
2010-09-17 02:10:08 +02:00
log_parse_environment ( ) ;
log_open ( ) ;
2014-08-02 11:12:21 -04:00
r = parse_argv ( argc , argv ) ;
if ( r < = 0 )
2018-11-20 15:14:16 +09:00
return r ;
2010-09-17 02:10:08 +02:00
2011-04-13 21:42:46 +02:00
if ( arg_timeout > 0 )
timeout = now ( CLOCK_MONOTONIC ) + arg_timeout ;
else
timeout = 0 ;
2015-10-07 11:26:10 +02:00
r = ask_password_auto ( arg_message , arg_icon , arg_id , arg_keyname , timeout , arg_flags , & l ) ;
2018-11-20 15:14:16 +09:00
if ( r < 0 )
return log_error_errno ( r , " Failed to query password: %m " ) ;
2011-02-23 01:12:07 +01:00
2015-10-07 11:26:10 +02:00
STRV_FOREACH ( p , l ) {
2016-02-29 21:04:02 +01:00
if ( ! arg_no_output )
puts ( * p ) ;
2010-10-25 20:35:17 +02:00
2015-10-07 11:26:10 +02:00
if ( ! arg_multiple )
break ;
2010-11-12 00:39:17 +01:00
}
2010-09-17 02:10:08 +02:00
2018-11-20 15:14:16 +09:00
return 0 ;
2010-09-17 02:10:08 +02:00
}
2018-11-20 15:14:16 +09:00
DEFINE_MAIN_FUNCTION ( run ) ;