Piped commands now use absolute program paths (e.g. /bin/grep instead of just grep) to avoid potential attacks (issue 18)

git-svn-id: https://logkeys.googlecode.com/svn/trunk@41 c501e62c-e7d1-11de-a198-37193048d1ed
This commit is contained in:
kernc 2010-04-22 15:59:58 +00:00
parent c0e749c00c
commit 8359aa3598
9 changed files with 142 additions and 24 deletions

View File

@ -121,6 +121,7 @@ EXEEXT = @EXEEXT@
FOUND_DUMPKEYS = @FOUND_DUMPKEYS@
FOUND_GREP = @FOUND_GREP@
FOUND_PS = @FOUND_PS@
FOUND_WHICH = @FOUND_WHICH@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@

View File

@ -1,5 +1,14 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Holds path to dumpkeys executable */
#undef EXE_DUMPKEYS
/* Holds path to grep executable */
#undef EXE_GREP
/* Holds path to ps executable */
#undef EXE_PS
/* Define to 1 if you have the `atoi' function. */
#undef HAVE_ATOI
@ -114,6 +123,12 @@
/* Define to 1 if you have the `open' function. */
#undef HAVE_OPEN
/* Define to 1 if you have the `pclose' function. */
#undef HAVE_PCLOSE
/* Define to 1 if you have the `popen' function. */
#undef HAVE_POPEN
/* Define to 1 if you have the `read' function. */
#undef HAVE_READ

76
configure vendored
View File

@ -601,6 +601,7 @@ CXXCPP
FOUND_DUMPKEYS
FOUND_PS
FOUND_GREP
FOUND_WHICH
am__fastdepCXX_FALSE
am__fastdepCXX_TRUE
CXXDEPMODE
@ -2666,6 +2667,7 @@ ac_config_headers="$ac_config_headers config.h"
# Checks for programs.
ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@ -3378,7 +3380,50 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
# Checks for programs.
# More checks for programs.
# Extract the first word of "which", so it can be a program name with args.
set dummy which; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if test "${ac_cv_prog_FOUND_WHICH+set}" = set; then :
$as_echo_n "(cached) " >&6
else
if test -n "$FOUND_WHICH"; then
ac_cv_prog_FOUND_WHICH="$FOUND_WHICH" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
ac_cv_prog_FOUND_WHICH="yes"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
test -z "$ac_cv_prog_FOUND_WHICH" && ac_cv_prog_FOUND_WHICH="no"
fi
fi
FOUND_WHICH=$ac_cv_prog_FOUND_WHICH
if test -n "$FOUND_WHICH"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $FOUND_WHICH" >&5
$as_echo "$FOUND_WHICH" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test x"$FOUND_WHICH" = xno ; then
as_fn_error "Required program 'which' is missing." "$LINENO" 5
fi
# Extract the first word of "grep", so it can be a program name with args.
set dummy grep; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@ -3418,8 +3463,14 @@ fi
if test x"$FOUND_GREP" = xno ; then
as_fn_error "Required program grep is missing." "$LINENO" 5
as_fn_error "Required program 'grep' is missing." "$LINENO" 5
fi
cat >>confdefs.h <<_ACEOF
#define EXE_GREP "`which grep`"
_ACEOF
# Extract the first word of "ps", so it can be a program name with args.
set dummy ps; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@ -3459,8 +3510,14 @@ fi
if test x"$FOUND_PS" = xno ; then
as_fn_error "Required program ps is missing." "$LINENO" 5
as_fn_error "Required program 'ps' is missing." "$LINENO" 5
fi
cat >>confdefs.h <<_ACEOF
#define EXE_PS "`which ps`"
_ACEOF
# Extract the first word of "dumpkeys", so it can be a program name with args.
set dummy dumpkeys; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@ -3500,10 +3557,16 @@ fi
if test x"$FOUND_DUMPKEYS" = xno ; then
as_fn_error "Required program dumpkeys is missing." "$LINENO" 5
as_fn_error "Required program 'dumpkeys' is missing." "$LINENO" 5
fi
cat >>confdefs.h <<_ACEOF
#define EXE_DUMPKEYS "`which dumpkeys`"
_ACEOF
# Checks for files
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for /dev/input" >&5
$as_echo_n "checking for /dev/input... " >&6; }
if test "${ac_cv_file__dev_input+set}" = set; then :
@ -3551,6 +3614,7 @@ fi
# Checks for header files.
ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@ -3964,6 +4028,7 @@ done
# Checks for typedefs, structures, and compiler characteristics.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
if test "${ac_cv_header_stdbool_h+set}" = set; then :
@ -4140,6 +4205,7 @@ fi
# Checks for library functions.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for error_at_line" >&5
$as_echo_n "checking for error_at_line... " >&6; }
if test "${ac_cv_lib_error_at_line+set}" = set; then :
@ -4389,7 +4455,7 @@ $as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
fi
for ac_func in geteuid error error_at_line exit on_exit memset setlocale strerror fprintf getopt_long fopen sscanf fscanf getpid getuid getgid fclose remove kill strlen strcat strcpy strncat freopen feof fgets atoi sigaction fork setsid open close flock write umask setegid seteuid strftime localtime fflush read time fgetws wcslen swscanf wcscpy
for ac_func in geteuid error error_at_line exit on_exit memset setlocale strerror fprintf getopt_long fopen sscanf fscanf getpid getuid getgid fclose remove kill strlen strcat strcpy strncat freopen feof fgets atoi sigaction fork setsid open close flock write umask setegid seteuid strftime localtime fflush read time fgetws wcslen swscanf wcscpy popen pclose
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"

View File

@ -8,26 +8,39 @@ AM_INIT_AUTOMAKE([-Wall foreign])
AC_CONFIG_HEADERS([config.h])
# Checks for programs.
AC_PROG_CXX
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_LANG([C++])
# Checks for programs.
AC_CHECK_PROG([FOUND_GREP], [grep], [yes], [no])
if test x"$FOUND_GREP" = xno ; then
AC_MSG_ERROR([Required program grep is missing.])
fi
AC_CHECK_PROG([FOUND_PS], [ps], [yes], [no])
if test x"$FOUND_PS" = xno ; then
AC_MSG_ERROR([Required program ps is missing.])
fi
AC_CHECK_PROG([FOUND_DUMPKEYS], [dumpkeys], [yes], [no])
if test x"$FOUND_DUMPKEYS" = xno ; then
AC_MSG_ERROR([Required program dumpkeys is missing.])
# More checks for programs.
AC_CHECK_PROG([FOUND_WHICH], [which], [yes], [no])
if test x"$FOUND_WHICH" = xno ; then
AC_MSG_ERROR([Required program 'which' is missing.])
fi
AC_CHECK_PROG([FOUND_GREP], [grep], [yes], [no])
if test x"$FOUND_GREP" = xno ; then
AC_MSG_ERROR([Required program 'grep' is missing.])
fi
AC_DEFINE_UNQUOTED([EXE_GREP], ["`which grep`"], [Holds path to grep executable])
AC_CHECK_PROG([FOUND_PS], [ps], [yes], [no])
if test x"$FOUND_PS" = xno ; then
AC_MSG_ERROR([Required program 'ps' is missing.])
fi
AC_DEFINE_UNQUOTED([EXE_PS], ["`which ps`"], [Holds path to ps executable])
AC_CHECK_PROG([FOUND_DUMPKEYS], [dumpkeys], [yes], [no])
if test x"$FOUND_DUMPKEYS" = xno ; then
AC_MSG_ERROR([Required program 'dumpkeys' is missing.])
fi
AC_DEFINE_UNQUOTED([EXE_DUMPKEYS], ["`which dumpkeys`"], [Holds path to dumpkeys executable])
# Checks for files
AC_CHECK_FILE(
[/dev/input],
[],
@ -40,6 +53,7 @@ AC_CHECK_FILE(
)
# Checks for header files.
AC_CHECK_HEADERS(
[cstdio cerrno cwchar cstring cassert sstream cstdlib csignal error.h unistd.h getopt.h sys/file.h sys/stat.h linux/input.h],
[],
@ -47,16 +61,18 @@ AC_CHECK_HEADERS(
)
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
AC_C_INLINE
AC_TYPE_PID_T
AC_TYPE_SIZE_T
# Checks for library functions.
AC_FUNC_ERROR_AT_LINE
AC_FUNC_FORK
AC_CHECK_FUNCS(
[geteuid error error_at_line exit on_exit memset setlocale strerror fprintf getopt_long fopen sscanf fscanf getpid getuid getgid fclose remove kill strlen strcat strcpy strncat freopen feof fgets atoi sigaction fork setsid open close flock write umask setegid seteuid strftime localtime fflush read time fgetws wcslen swscanf wcscpy],
[geteuid error error_at_line exit on_exit memset setlocale strerror fprintf getopt_long fopen sscanf fscanf getpid getuid getgid fclose remove kill strlen strcat strcpy strncat freopen feof fgets atoi sigaction fork setsid open close flock write umask setegid seteuid strftime localtime fflush read time fgetws wcslen swscanf wcscpy popen pclose],
[],
[AC_MSG_ERROR([Expected function is missing!])]
)

View File

@ -91,6 +91,7 @@ EXEEXT = @EXEEXT@
FOUND_DUMPKEYS = @FOUND_DUMPKEYS@
FOUND_GREP = @FOUND_GREP@
FOUND_PS = @FOUND_PS@
FOUND_WHICH = @FOUND_WHICH@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@

View File

@ -90,6 +90,7 @@ EXEEXT = @EXEEXT@
FOUND_DUMPKEYS = @FOUND_DUMPKEYS@
FOUND_GREP = @FOUND_GREP@
FOUND_PS = @FOUND_PS@
FOUND_WHICH = @FOUND_WHICH@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@

View File

@ -84,6 +84,7 @@ EXEEXT = @EXEEXT@
FOUND_DUMPKEYS = @FOUND_DUMPKEYS@
FOUND_GREP = @FOUND_GREP@
FOUND_PS = @FOUND_PS@
FOUND_WHICH = @FOUND_WHICH@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@

View File

@ -10,7 +10,7 @@ namespace logkeys {
wchar_t char_keys[49] = L"1234567890-=qwertyuiop[]asdfghjkl;'`\\zxcvbnm,./<";
wchar_t shift_keys[49] = L"!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:\"~|ZXCVBNM<>?>";
wchar_t altgr_keys[49] = {0}; // old, US don't use AltGr key: L"\0@\0$\0\0{[]}\\\0qwertyuiop\0~asdfghjkl\0\0\0\0zxcvbnm\0\0\0|"; // \0 on no symbol; as obtained by `loadkeys us`
// TODO: add altgr_shift_keys[]
// TODO: add altgr_shift_keys[] (http://en.wikipedia.org/wiki/AltGr_key#US_international)
wchar_t func_keys[][8] = {
L"<Esc>", L"<BckSp>", L"<Tab>", L"<Enter>", L"<LCtrl>", L"<LShft>", L"<RShft>", L"<KP*>", L"<LAlt>", L" L", L"<CpsLk>", L"<F1>", L"<F2>", L"<F3>", L"<F4>", L"<F5>",

View File

@ -30,6 +30,23 @@
# define PACKAGE_VERSION "0.1.0" // if PACKAGE_VERSION wasn't defined in <config.h>
#endif
// following EXE_* macros should be defined in config.h; if not, default
#ifndef EXE_PS
# define EXE_PS "/bin/ps"
#endif
#ifndef EXE_GREP
# define EXE_GREP "/bin/grep"
#endif
#ifndef EXE_DUMPKEYS
# define EXE_DUMPKEYS "/usr/bin/dumpkeys"
#endif
#define COMMAND_STR_DUMPKEYS ( EXE_DUMPKEYS " -n | " EXE_GREP " '^\\([[:space:]]shift[[:space:]]\\)*\\([[:space:]]altgr[[:space:]]\\)*keycode'" )
#define COMMAND_STR_DEVICES ( EXE_GREP " Name /proc/bus/input/devices | " EXE_GREP " -nE '[Kk]eyboard|kbd'" )
#define COMMAND_STR_GET_PID ( (std::string(EXE_PS " ax | " EXE_GREP " '") + program_invocation_name + "' | " EXE_GREP " -v grep").c_str() )
#define INPUT_EVENT_PATH "/dev/input/"
#define DEFAULT_LOG_FILE "/var/log/logkeys.log"
#define PID_FILE "/var/run/logkeys.pid"
@ -146,8 +163,7 @@ void kill_existing_process()
}
if (!via_file) { // if reading PID from temp_file failed, try ps-grep pipe
const char *pipe_cmd = (std::string("ps ax | grep '") + program_invocation_name + "' | grep -v grep").c_str();
via_pipe &= (sscanf(execute(pipe_cmd).c_str(), "%d", &pid) == 1);
via_pipe &= (sscanf(execute(COMMAND_STR_GET_PID).c_str(), "%d", &pid) == 1);
via_pipe &= (pid != getpid());
}
@ -178,7 +194,7 @@ void determine_system_keymap()
// get keymap from dumpkeys
// if one knows of a better, more portable way to get wchar_t-s from symbolic keysym-s from `dumpkeys` or `xmodmap` or another, PLEASE LET ME KNOW! kthx
std::stringstream ss, dump(execute("dumpkeys -n | grep '^\\([[:space:]]shift[[:space:]]\\)*\\([[:space:]]altgr[[:space:]]\\)*keycode'")); // see example output after i.e. `loadkeys slovene`
std::stringstream ss, dump(execute(COMMAND_STR_DUMPKEYS)); // see example output after i.e. `loadkeys slovene`
std::string line;
unsigned int i = 0; // keycode
@ -335,7 +351,7 @@ void export_keymap_to_file()
void determine_input_device()
{
// extract input number from /proc/bus/input/devices (I don't know how to do it better. If you have an idea, please let me know.)
std::string output = execute("grep Name /proc/bus/input/devices | grep -nE '[Kk]eyboard|kbd'");
std::string output = execute(COMMAND_STR_DEVICES);
std::stringstream input_dev_index;
input_dev_index << INPUT_EVENT_PATH;
@ -604,4 +620,5 @@ int main(int argc, char **argv)
int main(int argc, char** argv) {
logkeys::main(argc, argv);
}
}