Is there a way to have rlwrap automatically delete history files? - linux

I am using rlwrap to give command history to sqlplus/rman/etc on a linux server. I can see the command history files such as .sqlplus_history being generated and because these are plain text files that could possible contain passwords, e.g. if a user enters 'connect username/password' inside of sqlplus, there is a security risk to keeping them indefinitely.
Is there an easier way then some kind of cron job that would remove the logs at regular intervals?
I was hoping for some kind of keywords that would trigger the removal of the log such as if the 'exit' or 'quit' commands are read the user leaves sqlplus and the .sqlplus_history log is removed. Is anything like this possible?

rlwrap has many options to keep command lines out of the history list (and hence out of the history file), although not exactly in the way you describe (which I would not find as useful anyway)
rlwrap --forget-matching connect sqlplus will not remember any input lines that contain the string connect
Specifying a negative history size, like rlwrap --histsize -3000 will treat the history file as read-only (the password will still be visible in the history, but it will not be written to a file)
Entering a line with CTRL+O will keep this particular line out of the history list. (This action can be re-bound to another key, see the manpage)
For a really fancy password censor, one could write a filter censor_passwords like this:
#!/usr/bin/env perl
use lib ($ENV{RLWRAP_FILTERDIR} or ".");
use RlwrapFilter;
use strict;
my $filter = new RlwrapFilter;
$filter -> help_text("This filter removes the password from SQL 'identified by' clauses\n");
$filter -> history_handler(sub { s/(identified\s+by\s+)(\S+)/$1 xXxXxXxX/ig; $_});
$filter -> run;
.. and then use it like rlwrap -z censor_passwords sqlplus.
Any input containing IDENTIFIED BY yd6e7#te6 will then be remembered as IDENTIFIED BY xXxXxXxX

Related

tmux pin to avoid scrolling

Often when I run a command that writes to stdout, and that command fails, I have to scroll up (using uncomfortable key-bindings) looking for the place where I pressed Enter, to see what the first error was (out of hundreds others, across many screens of text). This is both annoying and time-consuming. I wish there was a feature which allowed me to pin my current terminal to the place where I am now, then start the command, see only the first lines of the output (as many as fits below my cursor) and let the rest of the output be written but not displayed. In other words I would like a feature to allow me automatically scroll up to the place where I gave the command, to see the first lines of the output (where usually the origin of the failure is displayed).
I searched for it but I didn't find it. Do you know if such feature exists? Or have an idea how to implement it with some tricks or workarounds?
If you have a unique shell prompt you could bind a key to jump between shell prompts, for example something like this will make C-b S jump to the previous shell prompt then S subsequent ones:
bind S copy-mode \; send -X search-backward 'nicholas#myhost:'
bind -Tcopy-mode S send -X search-backward 'nicholas#myhost:'
Or similarly you could search for error strings if they have a recognisable prefix. If you install the tmux 3.1 release candidate, you can search for regular expressions.
Alternatively, you could use capture-pane to load the entire history into an editor with key bindings you prefer, for example:
$ tmux capturep -S- -E- -p|vim -
Or pipe to grep or whatever. Note you will need to use a temporary file for this to work with emacs.
Or try to get into the habit of teeing commands with lots of output to a file to start with.

Tcsh completion in the format of ls -l

When setting autolist in tcsh.rc, and pressing Tab to complete a filename i get a list of available completions in the format of a "regular" ls command.
is there any way to set tcsh in a way that pressing tab will show a list of available completions in the format of "ls -l"?
or if not, then just sort the "regular" list by date?
pressing tab will show a list of available completions in the format of "ls -l"?
No, this is not possible.
Completion in tcsh works by getting a list of words (ie. my trousers are on fire), checking if one of the word matches, and then insert that word in the commandline.
There is no functionality which says "display this to the user, but insert something else in the commandline". So while you could complete commands with ls -l, this would be fairly useless, since you'll get the entire line in your commandline.
just sort the "regular" list by date?
This is also not possible, since tcsh sorts the completions. You can't disable this ...
Sorry :-( I believe that at least zsh is able to do this, but I'm not sure. Maybe bash can do this as well (but again, not sure).
(This information derived from a careful reading of the manpage, and tw.parse.c in the source code.)

How to have history in two files in linux

Is is possible to have the history of a specific user in one more file other than the default file mentioned as HISTFILE?
I would like to have as backup file if main file was removed and let it be like a backup for that one.
Regards,
Sriharsha Kalluru.
You can create a hardlink to the file
cp --link --verbose /home/$USER/.bash_history /somewhere/else/users_history
When the original file in his home is removed the file is still there and preserves the content from being lost.
Many times I've found myself using Ctrl-R in Bash to get a old command four times the terminal width, just to find out that too many days have passed and it's no longer in the .bash_history file. Here are two lines that will keep track of every command line you type at the bash prompt and use no external processes at all, just plain bash.
My first approach to this problem was increasing the maximum number of lines in the history to a very large quantity. But no matter how large it was, there was always a moment when I needed a long command I typed many months ago and it had already left the history. The current solution came to my mind when I learned about the PROMPT_COMMAND variable, a command that bash executes before showing each prompt. Here are the two lines:
export HISTTIMEFORMAT="%s "
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND ; }"'echo $$ $USER \
"$(history 1)" >> ~/.bash_eternal_history'
One goal I set to myself was to achieve it without using any external process, so bash wouldn't have to fork a new process after every ENTER pressed at its prompt. The first line sets the format of history lines to include the date as a Unix timestamp, so you can now when you typed every command. The second line, which is the core of the solution, first ensures that, if a previous PROMPT_COMMAND was set, it gets executed before our stuff and then appends a line of the format:
PID USER INDEX TIMESTAMP COMMAND
to a file called .bash_eternal_history in the current user home.
Adding the username, which at first seemed unnecesary, became useful later to distiguish between "sudo -s" sessions and normal sessions which retain the same value for "~/", and so append lines to the same .bash_eternal_history file.
I hope some of you find these two lines as useful as I do. :-)
Would hard links solve your problem?
Also you can read the man page here.
i would write a cronjob that copies the original histfiel to a backuplocation every minute or so. the you don't have to worry about defining a second histfile.
otherwise you could write every command the user enters to a alternate file
for this approach take a look here:
bash, run some command before or after every command entered from console

How do I search through MATLAB command history?

I would like to search for a specific command I've previously used. Is it possible to do a free text search on MATLAB command history?
Yes. Matlab stores your command history in a file called history.m in the "preferences folder," a directory containing preferences, history, and layout files. You can find the preferences folder using the prefdir command:
>> prefdir
ans =
/home/tobin/.matlab/R2010a
Then search the history.m file in that directory using the mechanism of your choice. For instance, using grep on unix:
>> chdir(prefdir)
>> !grep plot history.m
plot(f, abs(tf))
doc biplot
!grep plot history.m
You can also simply use the search function in the command history window if you just want to use the GUI.
If you want to accomplish this in a programmatic and platform-independent manner, you can first use MATLAB's Java internals to get the command history as a character array:
history = com.mathworks.mlservices.MLCommandHistoryServices.getSessionHistory;
historyText = char(history);
Then you can search through the character array however you like, using functions like STRFIND or REGEXP. You can also turn the character array into a cell array of strings (one line per cell) with the function CELLSTR, since they can sometimes be easier to work with.

Securely using password as bash argument

I'm extracting a part of a web application that handles the signup, the other part will be rewritten.
The idea is the signup part can exist as a separate application, interface with the rest of the application for creating and setting up the account. Obviously there are a ton of ways to do this, most of them network based solutions like SOAP, but I'd like to use a simpler solution: a setup script.
The concern is that certain sensitive data, specifically the admin password of the new account, would be passed through bash.
I was thinking of sharing a small class between the applications, so that the password can be passed already hashed, but I would also have to pass the salt, so it still seems like a (small) security risk. One of the concerns is bash logging (can I disable that for a single command?) but I'm sure there are other concerns as well?
This would be on the same private server, so the risk seems minimal, but I don't want to take any chances whatsoever.
Thanks.
Use the $HISTFILE environment variable, unset it (this is for all users):
echo "unset HISTFILE" >> /etc/profile
Then set it back again.
More info on $HISTFILE variable here: http://linux.about.com/cs/linux101/g/histfileenviron.htm
Hope this helps!
From the man page of bash:
HISTIGNORE
A colon-separated list of patterns used to decide which
command
lines should be saved on the history list. Each pattern
is
anchored at the beginning of the line and must match
the com-
plete line (no implicit ‘*’ is appended). Each pattern
is
tested against the line after the checks specified by
HISTCONTROL are applied. In addition to the normal shell
pattern
matching characters, ‘&’ matches the previous history line.
‘&’
may be escaped using a backslash; the backslash is
removed
before attempting a match. The second and subsequent
lines of a
multi-line compound command are not tested, and are added
to the
history regardless of the value of HISTIGNORE.
Or, based on your comment, you could store the password in a protected file, then read from it.
Passing the salt in clear is no problem (the salt is usually stored in clear), the purpose of the salt is avoiding the same password hashing to the same hash always (so users with the same password would have the same hash, and rainbow tables would only need a single hash for each possible password).
What is more problematic is passing sensitive data through command line arguments, an eavesdropper on the same box can see the arguments to any command (on Linux they appear on /proc//cmdline, and on most Unixes can be seen using ps; some systems restrict permissions on /proc// to only the owner of the process for security).
What you could do is pass the sensitive information through a file, don't forget to set the umask to a very restrictive setting before creating the file.
Bash doesn't normally log commands executed in scripts, but only in interactive sessions (depending on appropriate settings). To show this, use the following script:
#!/bin/bash
echo "-- shopt --"
shopt | grep -i hist
echo "-- set --"
set -o | grep -i hist
echo "--vars --"
for v in ${!HIST*}
do
echo "$v=${!v}"
done
Run it like this:
$ ./histshow
and compare the output to that from sourcing it like this:
$ . ./histshow
In the first case take note that HISTFILE is not set and that the set option history is off. In the second case, sourcing the script runs it in your interactive session and shows what your settings are for it.
I was only able to make a script keep an in-memory history by doing set -o history within the script and to log its history to a file by also setting HISTFILE and then doing an explicit history -w.

Resources