2010-09-17 03:26:29 +04:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd .
Copyright 2010 Lennart Poettering
systemd is free software ; you can redistribute it and / or modify it
2012-04-12 02:20:58 +04:00
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation ; either version 2.1 of the License , or
2010-09-17 03:26:29 +04:00
( at your option ) any later version .
systemd is distributed in the hope that it will be useful , but
WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
2012-04-12 02:20:58 +04:00
Lesser General Public License for more details .
2010-09-17 03:26:29 +04:00
2012-04-12 02:20:58 +04:00
You should have received a copy of the GNU Lesser General Public License
2010-09-17 03:26:29 +04:00
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
# include <sys/socket.h>
# include <sys/poll.h>
# include <sys/types.h>
# include <assert.h>
# include <string.h>
# include <errno.h>
# include <unistd.h>
# include <fcntl.h>
# include <sys/un.h>
# include <sys/stat.h>
# include <sys/signalfd.h>
# include <getopt.h>
2010-09-17 04:10:08 +04:00
# include <termios.h>
# include <limits.h>
2010-10-07 04:34:17 +04:00
# include <stddef.h>
2010-09-17 03:26:29 +04:00
# include "log.h"
# include "macro.h"
# include "util.h"
2011-02-23 03:12:07 +03:00
# include "strv.h"
2010-11-12 02:39:17 +03:00
# include "ask-password-api.h"
2011-04-14 04:30:43 +04:00
# include "def.h"
2010-09-17 03:26:29 +04:00
static const char * arg_icon = NULL ;
2014-03-25 14:05:23 +04:00
static const char * arg_id = NULL ;
2010-09-17 03:26:29 +04:00
static const char * arg_message = NULL ;
2010-09-17 04:10:08 +04:00
static bool arg_use_tty = true ;
2011-04-14 04:30:43 +04:00
static usec_t arg_timeout = DEFAULT_TIMEOUT_USEC ;
2011-02-23 03:12:07 +03:00
static bool arg_accept_cached = false ;
static bool arg_multiple = false ;
2010-09-17 03:26:29 +04:00
static int help ( void ) {
printf ( " %s [OPTIONS...] MESSAGE \n \n "
2010-09-17 04:13:12 +04:00
" Query the user for a system passphrase, via the TTY or an UI agent. \n \n "
2011-02-23 03:12:07 +03:00
" -h --help Show this help \n "
" --icon=NAME Icon name \n "
" --timeout=SEC Timeout in sec \n "
" --no-tty Ask question via agent even on TTY \n "
" --accept-cached Accept cached passwords \n "
2014-03-25 14:05:23 +04:00
" --multiple List multiple passwords if available \n "
" --id=ID Query identifier (e.g. cryptsetup:/dev/sda5) \n " ,
2010-09-17 03:26:29 +04:00
program_invocation_short_name ) ;
return 0 ;
}
static int parse_argv ( int argc , char * argv [ ] ) {
enum {
ARG_ICON = 0x100 ,
2010-09-17 04:10:08 +04:00
ARG_TIMEOUT ,
2011-02-23 03:12:07 +03:00
ARG_NO_TTY ,
ARG_ACCEPT_CACHED ,
2014-03-25 14:05:23 +04:00
ARG_MULTIPLE ,
ARG_ID
2010-09-17 03:26:29 +04:00
} ;
static const struct option options [ ] = {
2011-02-23 03:12:07 +03:00
{ " help " , no_argument , NULL , ' h ' } ,
{ " icon " , required_argument , NULL , ARG_ICON } ,
{ " timeout " , required_argument , NULL , ARG_TIMEOUT } ,
{ " 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 14:05:23 +04:00
{ " id " , required_argument , NULL , ARG_ID } ,
2013-11-06 21:28:39 +04:00
{ }
2010-09-17 03:26:29 +04:00
} ;
int c ;
assert ( argc > = 0 ) ;
assert ( argv ) ;
while ( ( c = getopt_long ( argc , argv , " h " , options , NULL ) ) > = 0 ) {
switch ( c ) {
case ' h ' :
2013-11-06 21:28:39 +04:00
return help ( ) ;
2010-09-17 03:26:29 +04:00
case ARG_ICON :
arg_icon = optarg ;
break ;
case ARG_TIMEOUT :
2013-04-02 22:38:16 +04:00
if ( parse_sec ( optarg , & arg_timeout ) < 0 ) {
2010-09-17 03:26:29 +04:00
log_error ( " Failed to parse --timeout parameter %s " , optarg ) ;
return - EINVAL ;
}
break ;
2010-09-17 04:10:08 +04:00
case ARG_NO_TTY :
arg_use_tty = false ;
break ;
2011-02-23 03:12:07 +03:00
case ARG_ACCEPT_CACHED :
arg_accept_cached = true ;
break ;
case ARG_MULTIPLE :
arg_multiple = true ;
break ;
2014-03-25 14:05:23 +04:00
case ARG_ID :
arg_id = optarg ;
break ;
2010-09-17 03:26:29 +04:00
case ' ? ' :
return - EINVAL ;
default :
2013-11-06 21:28:39 +04:00
assert_not_reached ( " Unhandled option " ) ;
2010-09-17 03:26:29 +04:00
}
}
if ( optind ! = argc - 1 ) {
help ( ) ;
return - EINVAL ;
}
arg_message = argv [ optind ] ;
2010-09-17 04:10:08 +04:00
return 1 ;
2010-09-17 03:26:29 +04:00
}
2010-09-17 04:10:08 +04:00
int main ( int argc , char * argv [ ] ) {
int r ;
2011-04-13 23:42:46 +04:00
usec_t timeout ;
2010-09-17 04:10:08 +04:00
log_parse_environment ( ) ;
log_open ( ) ;
if ( ( r = parse_argv ( argc , argv ) ) < = 0 )
goto finish ;
2011-04-13 23:42:46 +04:00
if ( arg_timeout > 0 )
timeout = now ( CLOCK_MONOTONIC ) + arg_timeout ;
else
timeout = 0 ;
2011-02-23 03:12:07 +03:00
if ( arg_use_tty & & isatty ( STDIN_FILENO ) ) {
char * password = NULL ;
2011-04-13 23:42:46 +04:00
if ( ( r = ask_password_tty ( arg_message , timeout , NULL , & password ) ) > = 0 ) {
2011-02-23 03:12:07 +03:00
puts ( password ) ;
free ( password ) ;
}
} else {
char * * l ;
2014-03-25 14:05:23 +04:00
if ( ( r = ask_password_agent ( arg_message , arg_icon , arg_id , timeout , arg_accept_cached , & l ) ) > = 0 ) {
2011-02-23 03:12:07 +03:00
char * * p ;
STRV_FOREACH ( p , l ) {
puts ( * p ) ;
2010-10-25 22:35:17 +04:00
2011-02-23 03:12:07 +03:00
if ( ! arg_multiple )
break ;
}
strv_free ( l ) ;
}
2010-11-12 02:39:17 +03:00
}
2010-09-17 04:10:08 +04:00
finish :
2010-11-12 02:39:17 +03:00
2010-09-17 04:10:08 +04:00
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS ;
}