| @ -1,37 +0,0 @@ | |||
| #!/bin/bash -l | |||
| IDENT="`date --date="today" "+%Y-%m-%d_%H-%M-%S"`.`whoami`.$$" | |||
| # This is a file transfer, no audit shell neccessary | |||
| if (echo "$@"|egrep -q "^-c.*scp.*$");then | |||
| logger -t auditshell.filetransfer.${IDENT} <<< "/bin/sh $@" | |||
| exec /bin/sh "$@" | |||
| # Remote command execution | |||
| elif (echo "$@"|egrep -q "^-c.*$");then | |||
| logger -t auditshell.remotecommand.${IDENT} <<< "/bin/bash $@" | |||
| exec /bin/bash "$@" | |||
| fi | |||
| TYPESCRIPT="auditshell.typescript.${IDENT}" | |||
| TIMING="auditshell.timing.${IDENT}" | |||
| export SHELL=/bin/bash | |||
| cat <<EOF | |||
| _ _ _ ____ ___ _____ ____ _ _ _____ _ _ | |||
| / \ | | | | _ \_ _|_ _/ ___|| | | | ____| | | | | |||
| / _ \| | | | | | | | | | \___ \| |_| | _| | | | | | |||
| / ___ \ |_| | |_| | | | | ___) | _ | |___| |___| |___ | |||
| /_/ \_\___/|____/___| |_| |____/|_| |_|_____|_____|_____| | |||
| NOTE: This shell session will be recorded | |||
| AUDIT KEY: $IDENT | |||
| EOF | |||
| /usr/local/bin/script -d -e -f -q -t 5 \ | |||
| 5> >(base64|logger -t $TYPESCRIPT) \ | |||
| 2> >(base64|logger -t $TIMING) | |||
| echo "Finish" | |||
| @ -1,57 +0,0 @@ | |||
| #!/usr/bin/env perl | |||
| use strict; | |||
| use warnings; | |||
| use FileHandle; | |||
| my $file = shift(); | |||
| my $dir = shift(); | |||
| if ( (!defined $file) || (!defined $file) ){ | |||
| print "auditshell_create_sessionfiles <logfile> <dir>\n"; | |||
| exit(1); | |||
| } | |||
| chdir($dir); | |||
| unless(chdir($dir)) | |||
| { | |||
| die "Error: Can't change directory!: $!"; | |||
| } | |||
| open( INFILE, "<$file" ) || die "input-file '$file' could not be opened"; | |||
| my $fdcache = {}; | |||
| while (my $zeile = <INFILE>) { | |||
| if ($zeile =~m /auditshell\.(typescript|timing)\.(.*?): (.*)$/){ | |||
| chomp($zeile); | |||
| my $type = $1; | |||
| my $ident = $2; | |||
| my $line = $3; | |||
| if ( !exists $fdcache->{$ident}){ | |||
| $fdcache->{$ident} = {}; | |||
| print "Create $ident.typescript.base64\n"; | |||
| $fdcache->{$ident}->{typescript} = FileHandle->new("> $ident.typescript.base64"); | |||
| print "Create $ident.timing.base64\n"; | |||
| $fdcache->{$ident}->{timing} = FileHandle->new("> $ident.timing.base64"); | |||
| } | |||
| my $fd = $fdcache->{$ident}->{$type}; | |||
| print $fd $line."\n"; | |||
| } | |||
| } | |||
| close(INFILE); | |||
| foreach my $ident(keys %{$fdcache}){ | |||
| close $fdcache->{$ident}->{typescript}; | |||
| close $fdcache->{$ident}->{timing}; | |||
| system("base64 -d $ident.typescript.base64 |gzip -c > $ident.typescript.gz"); | |||
| system("base64 -d $ident.timing.base64 |gzip -c > $ident.timing.gz"); | |||
| unlink("$ident.timing.base64"); | |||
| unlink("$ident.typescript.base64"); | |||
| print "removed $ident.typescript.base64, created $ident.typescript.gz\n"; | |||
| print "removed $ident.timing.base64, created $ident.timing.gz\n"; | |||
| } | |||
| @ -1,131 +0,0 @@ | |||
| diff --git a/term-utils/script.1 b/term-utils/script.1 | |||
| index 5c366b129..33789a927 100644 | |||
| --- a/term-utils/script.1 | |||
| +++ b/term-utils/script.1 | |||
| @@ -86,14 +86,21 @@ or symbolic link. The command will follow a symbolic link. | |||
| Be quiet (do not write start and done messages to either standard output | |||
| or the typescript file). | |||
| .TP | |||
| -\fB\-t\fR, \fB\-\-timing\fR[=\fIfile\fR] | |||
| -Output timing data to standard error, or to | |||
| +\fB\-t\fR, \fB\-\-timing\fR[=\fIfile|descriptor\fR] | |||
| +Output timing data to standard error, or to a | |||
| .I file | |||
| +or | |||
| +.I descriptor | |||
| when given. This data contains two fields, separated by a space. The first | |||
| field indicates how much time elapsed since the previous output. The second | |||
| field indicates how many characters were output this time. This information | |||
| can be used to replay typescripts with realistic typing and output delays. | |||
| .TP | |||
| +\fB\-d\fR, \fB\-\-descriptor\fR | |||
| +Use this option in combination with | |||
| +.I --timing | |||
| +for using the given resource as a file descriptor number as destination for timing data | |||
| +.TP | |||
| \fB\-V\fR, \fB\-\-version\fR | |||
| Display version information and exit. | |||
| .TP | |||
| diff --git a/term-utils/script.c b/term-utils/script.c | |||
| index d1ef07203..4b56b671d 100644 | |||
| --- a/term-utils/script.c | |||
| +++ b/term-utils/script.c | |||
| @@ -116,7 +116,8 @@ struct script_control { | |||
| #endif | |||
| unsigned int | |||
| append:1, /* append output */ | |||
| - rc_wanted:1, /* return child exit value */ | |||
| + tsdesc:1, /* output typescript to file descriptor */ | |||
| + rc_wanted:1, /* return child exit value */ | |||
| flush:1, /* flush after each write */ | |||
| quiet:1, /* suppress most output */ | |||
| timing:1, /* include timing file */ | |||
| @@ -169,6 +170,7 @@ static void __attribute__((__noreturn__)) usage(FILE *out) | |||
| " --force use output file even when it is a link\n" | |||
| " -q, --quiet be quiet\n" | |||
| " -t, --timing[=<file>] output timing data to stderr (or to FILE)\n" | |||
| + " -d, --descriptor[=<n>] output timing data to a defined descriptor number\n" | |||
| " -V, --version output version information and exit\n" | |||
| " -h, --help display this help and exit\n\n"), out); | |||
| @@ -195,8 +197,14 @@ static void __attribute__((__noreturn__)) done(struct script_control *ctl) | |||
| if (ctl->isterm) | |||
| tcsetattr(STDIN_FILENO, TCSADRAIN, &ctl->attrs); | |||
| - if (!ctl->quiet && ctl->typescriptfp) | |||
| - printf(_("Script done, file is %s\n"), ctl->fname); | |||
| + if (!ctl->quiet && ctl->typescriptfp) { | |||
| + if (ctl->tsdesc == 1) { | |||
| + printf(_("Script done, file descriptor number is %s\n"), ctl->fname); | |||
| + }else{ | |||
| + printf(_("Script done, file is %s\n"), ctl->fname); | |||
| + } | |||
| + } | |||
| + | |||
| #ifdef HAVE_LIBUTEMPTER | |||
| if (ctl->master >= 0) | |||
| utempter_remove_record(ctl->master); | |||
| @@ -407,6 +415,7 @@ static void do_io(struct script_control *ctl) | |||
| int ret, ignore_stdin = 0, eof = 0; | |||
| time_t tvec = script_time((time_t *)NULL); | |||
| char buf[128]; | |||
| + int fdnum_typescript = 0; | |||
| enum { | |||
| POLLFD_SIGNAL = 0, | |||
| POLLFD_MASTER, | |||
| @@ -420,7 +429,18 @@ static void do_io(struct script_control *ctl) | |||
| }; | |||
| - if ((ctl->typescriptfp = | |||
| + | |||
| + if (ctl->tsdesc == 1){ | |||
| + fdnum_typescript = atoi(ctl->fname); | |||
| + if (fdnum_typescript == 0){ | |||
| + warn(_("file descriptor is not a number")); | |||
| + fail(ctl); | |||
| + } | |||
| + if ((ctl->typescriptfp = fdopen (fdnum_typescript, "w")) == NULL) { | |||
| + warn(_("cannot open fd %s"), ctl->fname); | |||
| + fail(ctl); | |||
| + } | |||
| + }else if ((ctl->typescriptfp = | |||
| fopen(ctl->fname, ctl->append ? "a" UL_CLOEXECSTR : "w" UL_CLOEXECSTR)) == NULL) { | |||
| warn(_("cannot open %s"), ctl->fname); | |||
| fail(ctl); | |||
| @@ -678,6 +698,7 @@ int main(int argc, char **argv) | |||
| {"force", no_argument, NULL, FORCE_OPTION,}, | |||
| {"quiet", no_argument, NULL, 'q'}, | |||
| {"timing", optional_argument, NULL, 't'}, | |||
| + {"descriptor", no_argument, NULL, 'd' }, | |||
| {"version", no_argument, NULL, 'V'}, | |||
| {"help", no_argument, NULL, 'h'}, | |||
| {NULL, 0, NULL, 0} | |||
| @@ -698,8 +719,10 @@ int main(int argc, char **argv) | |||
| script_init_debug(); | |||
| - while ((ch = getopt_long(argc, argv, "ac:efqt::Vh", longopts, NULL)) != -1) | |||
| + while ((ch = getopt_long(argc, argv, "dac:efqt::Vh", longopts, NULL)) != -1) | |||
| switch (ch) { | |||
| + case 'd': | |||
| + ctl.tsdesc = 1; | |||
| case 'a': | |||
| ctl.append = 1; | |||
| break; | |||
| @@ -748,8 +771,13 @@ int main(int argc, char **argv) | |||
| ctl.shell = _PATH_BSHELL; | |||
| getmaster(&ctl); | |||
| - if (!ctl.quiet) | |||
| - printf(_("Script started, file is %s\n"), ctl.fname); | |||
| + if (!ctl.quiet) { | |||
| + if (ctl.tsdesc == 1) { | |||
| + printf(_("Script started, file descriptor number is %s\n"), ctl.fname); | |||
| + }else{ | |||
| + printf(_("Script started, file is %s\n"), ctl.fname); | |||
| + } | |||
| + } | |||
| fixtty(&ctl); | |||
| #ifdef HAVE_LIBUTEMPTER | |||
| @ -1,126 +0,0 @@ | |||
| diff --git a/term-utils/script.1 b/term-utils/script.1 | |||
| index 1e430d8..1808a37 100644 | |||
| --- a/term-utils/script.1 | |||
| +++ b/term-utils/script.1 | |||
| @@ -84,14 +84,21 @@ or symbolic link. The command will follow a symbolic link. | |||
| \fB\-q\fR, \fB\-\-quiet\fR | |||
| Be quiet. | |||
| .TP | |||
| -\fB\-t\fR, \fB\-\-timing\fR[=\fIfile\fR] | |||
| -Output timing data to standard error, or to | |||
| +\fB\-t\fR, \fB\-\-timing\fR[=\fIfile|descriptor\fR] | |||
| +Output timing data to standard error, or to a | |||
| .I file | |||
| +or | |||
| +.I descriptor | |||
| when given. This data contains two fields, separated by a space. The first | |||
| field indicates how much time elapsed since the previous output. The second | |||
| field indicates how many characters were output this time. This information | |||
| can be used to replay typescripts with realistic typing and output delays. | |||
| .TP | |||
| +\fB\-d\fR, \fB\-\-descriptor\fR | |||
| +Use this option in combination with | |||
| +.I --timing | |||
| +for using the given resource as a file descriptor number as destination for timing data | |||
| +.TP | |||
| \fB\-V\fR, \fB\-\-version\fR | |||
| Output version information and exit. | |||
| .TP | |||
| diff --git a/term-utils/script.c b/term-utils/script.c | |||
| index 242b815..778fbbe 100644 | |||
| --- a/term-utils/script.c | |||
| +++ b/term-utils/script.c | |||
| @@ -101,12 +101,14 @@ int l; | |||
| char line[] = "/dev/ptyXX"; | |||
| #endif | |||
| int aflg = 0; | |||
| +int dflg = 0; | |||
| char *cflg = NULL; | |||
| int eflg = 0; | |||
| int fflg = 0; | |||
| int qflg = 0; | |||
| int tflg = 0; | |||
| int forceflg = 0; | |||
| +int fdnum_typescript = 0; | |||
| int die; | |||
| int resized; | |||
| @@ -171,6 +173,7 @@ main(int argc, char **argv) { | |||
| { "force", no_argument, NULL, FORCE_OPTION, }, | |||
| { "quiet", no_argument, NULL, 'q' }, | |||
| { "timing", optional_argument, NULL, 't' }, | |||
| + { "descriptor", no_argument, NULL, 'd' }, | |||
| { "version", no_argument, NULL, 'V' }, | |||
| { "help", no_argument, NULL, 'h' }, | |||
| { NULL, 0, NULL, 0 } | |||
| @@ -182,8 +185,10 @@ main(int argc, char **argv) { | |||
| textdomain(PACKAGE); | |||
| atexit(close_stdout); | |||
| - while ((ch = getopt_long(argc, argv, "ac:efqt::Vh", longopts, NULL)) != -1) | |||
| + while ((ch = getopt_long(argc, argv, "dac:efqt::Vh", longopts, NULL)) != -1) | |||
| switch(ch) { | |||
| + case 'd': | |||
| + dflg = 1; | |||
| case 'a': | |||
| aflg = 1; | |||
| break; | |||
| @@ -229,7 +234,22 @@ main(int argc, char **argv) { | |||
| fname = DEFAULT_OUTPUT; | |||
| die_if_link(fname); | |||
| } | |||
| - if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) { | |||
| + | |||
| + | |||
| + if (dflg == 1){ | |||
| + | |||
| + fdnum_typescript = atoi(fname); | |||
| + | |||
| + if (fdnum_typescript == 0){ | |||
| + warn(_("file descriptor is not a number")); | |||
| + fail(); | |||
| + } | |||
| + | |||
| + if ((fscript = fdopen (fdnum_typescript, "w")) == NULL) { | |||
| + warn(_("cannot open fd %s"), fname); | |||
| + fail(); | |||
| + } | |||
| + }else if((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) { | |||
| warn(_("cannot open %s"), fname); | |||
| fail(); | |||
| } | |||
| @@ -239,8 +259,15 @@ main(int argc, char **argv) { | |||
| shell = _PATH_BSHELL; | |||
| getmaster(); | |||
| - if (!qflg) | |||
| + | |||
| + if (!qflg) { | |||
| + if (dflg == 1){ | |||
| + printf(_("Script started, file descriptor number is %s\n"), fname); | |||
| + }else{ | |||
| printf(_("Script started, file is %s\n"), fname); | |||
| + } | |||
| + } | |||
| + | |||
| fixtty(); | |||
| #ifdef HAVE_LIBUTEMPTER | |||
| @@ -495,8 +520,16 @@ done(void) { | |||
| master = -1; | |||
| } else { | |||
| tcsetattr(STDIN_FILENO, TCSADRAIN, &tt); | |||
| - if (!qflg) | |||
| + | |||
| + if (!qflg) { | |||
| + if (dflg == 1){ | |||
| + printf(_("Script done, file descriptor number is %s\n"), fname); | |||
| + }else{ | |||
| printf(_("Script done, file is %s\n"), fname); | |||
| + } | |||
| + } | |||
| + | |||
| + | |||
| #ifdef HAVE_LIBUTEMPTER | |||
| if (master >= 0) | |||
| utempter_remove_record(master); | |||