Thursday, January 10, 2013

Easy Mac Bash Enhancements

Today I'm writing about two different things pertinent to enhancing Bash (on my mac):

  • Adding information to history
  • Making the prompt a little more likeable

As we all know, sometimes you enter a command in bash, but then find that you entered it a lot and need to look at the different ways you entered it. So there's the history; type "history" into the prompt, and you'll see all your commands (for some time, its limited in size by the HISTSIZE environment variable). 

But frequently, we might want more information than merely the command itself. Such as when it was entered, who entered it, on what terminal in what process. 

After searching around for a while, I found this script, and decided to enhance it:
log_history() {
# Detailed history log of shell activities, including time stamps, working directory etc.
#
# Based on 'hcmnt' by Dennis Williamson - 2009-06-05 - updated 2009-06-19
# (http://stackoverflow.com/questions/945288/saving-current-directory-to-bash-history)
#
# Add this function to your '~/.bashrc':
#
# Set the bash variable PROMPT_COMMAND to the name of this function and include
# these options:
#
#     e - add the output of an extra command contained in the histentrycmdextra variable
#     h - add the hostname
#     y - add the terminal device (tty)
#     n - don't add the directory
#     t - add the from and to directories for cd commands
#     l - path to the log file (default = $HOME/.bash_log)
#     ext or a variable
#
# See bottom of this function for examples.
#
    # make sure this is not changed elsewhere in '.bashrc';
    # if it is, you have to update the reg-ex's below
    export HISTTIMEFORMAT="[%F %T] ~~~ "
    local script=$FUNCNAME
    local histentrycmd=
    local cwd=
    local extra=
    local text=
    local logfile="$HOME/.bash_log"
    local hostname=
    local histentry=
    local histleader=
    local datetimestamp=
    local histlinenum=
    local options=":hyntel:"
    local option=
    OPTIND=1
    local usage="Usage: $script [-h] [-y] [-n|-t] [-e] [text] [-l logfile]"
    local ExtraOpt=
    local NoneOpt=
    local ToOpt=
    local tty=
    local ip=
    # *** process options to set flags ***
    while getopts $options option
    do
        case $option in
            h ) hostname=$HOSTNAME;;
            y ) tty=$(tty);;
            n ) if [[ $ToOpt ]]
                then
                    echo "$script: can't include both -n and -t."
                    echo $usage
                    return 1
                else
                    NoneOpt=1       # don't include path
                fi;;
            t ) if [[ $NoneOpt ]]
                then
                    echo "$script: can't include both -n and -t."
                    echo $usage
                    return 1
                else
                    ToOpt=1         # cd shows "from -> to"
                fi;;
            e ) ExtraOpt=1;;        # include histentrycmdextra
            l ) logfile=$OPTARG;;
            : ) echo "$script: missing filename: -$OPTARG."
                echo $usage
                return 1;;
            * ) echo "$script: invalid option: -$OPTARG."
                echo $usage
                return 1;;
        esac
    done
    text=($@)                       # arguments after the options are saved to add to the comment
    text="${text[*]:$OPTIND - 1:${#text[*]}}"
    # add the previous command(s) to the history file immediately
    # so that the history file is in sync across multiple shell sessions
    history -a
    # grab the most recent command from the command history
    histentry=$(history 1)
    # parse it out
    histleader=`expr "$histentry" : ' *\([0-9]*  \[[0-9]*-[0-9]*-[0-9]* [0-9]*:[0-9]*:[0-9]*\]\)'`
    histlinenum=`expr "$histleader" : ' *\([0-9]*  \)'`
    datetimestamp=`expr "$histleader" : '.*\(\[[0-9]*-[0-9]*-[0-9]* [0-9]*:[0-9]*:[0-9]*\]\)'`
    histentrycmd=${histentry#*~~~ }
    # protect against relogging previous command
    # if all that was actually entered by the user
    # was a (no-op) blank line
    #if [[ -z $__PREV_HISTLINE || -z $__PREV_HISTCMD ]]
    #then
        # new shell; initialize variables for next command
    #    export __PREV_HISTLINE=$histlinenum
    #    export __PREV_HISTCMD=$histentrycmd
    #    return
    #elif [[ $histlinenum == $__PREV_HISTLINE  && $histentrycmd == $__PREV_HISTCMD ]]
    #then
        # no new command was actually entered
    #    return
    #else
        # new command entered; store for next comparison
    #    export __PREV_HISTLINE=$histlinenum
    #    export __PREV_HISTCMD=$histentrycmd
    #fi
    if [[ -z $NoneOpt ]]            # are we adding the directory?
    then
        if [[ ${histentrycmd%% *} == "cd" || ${histentrycmd%% *} == "jd" ]]    # if it's a cd command, we want the old directory
        then                             #   so the comment matches other commands "where *were* you when this was done?"
            if [[ -z $OLDPWD ]]
            then
                OLDPWD="$HOME"
            fi
            if [[ $ToOpt ]]
            then
                cwd="$OLDPWD -> $PWD"    # show "from -> to" for cd
            else
                cwd=$OLDPWD              # just show "from"
            fi
        else
            cwd=$PWD                     # it's not a cd, so just show where we are
        fi
    fi
    if [[ $ExtraOpt && $histentrycmdextra ]]    # do we want a little something extra?
    then
        extra=$(eval "$histentrycmdextra")
    fi
    # strip off the old ### comment if there was one so they don't accumulate
    # then build the string (if text or extra aren't empty, add them with some decoration)
    histentrycmd="${datetimestamp} ${text:+[$text] }${tty:+[$tty] } [PPID:$PPID] ${ip:+[$ip]} ${extra:+[$extra] }~~~ ${hostname:+$hostname:}$cwd ~~~ ${histentrycmd# * ~~~ }"
    # save the entry in a logfile
    echo "$histentrycmd" >> $logfile || echo "$script: file error." ; return 1
} # END FUNCTION _loghistory


As long as this is somewhere that will be available to every terminal, you'll be in business.

Now, one thing I don't like is silent failure. If a command fails, it should output something. Most of the time, this occurs, but sometimes it does not. If you check the result, you can see this explicitly, but who wants to type that all the time? So I came up with this:

PROMPT_COMMAND='PS1="\033[0;33m\d \@ || \u\n\`if [[ \$? = "0" ]]; then echo "\\[\\033[32m\\]"; else echo "\\[\\033[31m\\]"; fi\`[\w]\$ \[\033[0m\] "; echo -ne "\033]0;`hostname -s`:`pwd`; `log_history -h -y -t -e -l ~/.bash_log`\007 "'

Now your prompt will be shorter for your commands, show you the time of each previous command (if you should ever need that) and turn red when things fail.

Saturday, June 2, 2012

Installing ossec in mac OSX lion

I'm installing OSSec on my mac as both a server and an agent-so mac host is the server that manages everything, and mac is also an agent of itself. My VM's will also have agents installed, and they will be responsible to my mac host.


Installation log:


2- Setting up the installation environment.


 - Choose where to install the OSSEC HIDS [/var/ossec]: 




    - Installation will be made at  /var/ossec .


3- Configuring the OSSEC HIDS.


  3.1- Do you want e-mail notification? (y/n) [y]: 


   - What's your e-mail address? 
**********************
   - What's your SMTP server ip/host? 
smtp.gmail.com


  3.2- Do you want to run the integrity check daemon? (y/n) [y]: 




   - Running syscheck (integrity check daemon).


  3.3- Do you want to run the rootkit detection engine? (y/n) [y]: 




   - Running rootcheck (rootkit detection).


  3.4- Active response allows you to execute a specific 
       command based on the events received. For example,
       you can block an IP address or disable access for
       a specific user.  
       More information at:
       http://www.ossec.net/en/manual.html#active-response
       
   - Do you want to enable active response? (y/n) [y]: 




     - Active response enabled.
   
   - By default, we can enable the host-deny and the 
     firewall-drop responses. The first one will add
     a host to the /etc/hosts.deny and the second one
     will block the host on iptables (if linux) or on
     ipfilter (if Solaris, FreeBSD or NetBSD).
   - They can be used to stop SSHD brute force scans, 
     portscans and some other forms of attacks. You can 
     also add them to block on snort events, for example.


   - Do you want to enable the firewall-drop response? (y/n) [y]: 




     - firewall-drop enabled (local) for levels >= 6


   - Default white list for the active response:
      - 8.8.8.8
      - 8.8.4.4


   - Do you want to add more IPs to the white list? (y/n)? [n]: 




  3.5- Do you want to enable remote syslog (port 514 udp)? (y/n) [y]: 




   - Remote syslog enabled.


  3.6- Setting the configuration to analyze the following logs:
    -- /var/log/secure.log
    -- /var/log/system.log


 - If you want to monitor any other file, just change 
   the ossec.conf and add a new localfile entry.
   Any questions about the configuration can be answered
   by visiting us online at http://www.ossec.net


While installing, I ran into this error:


To fix it, I found this:

Which later led me to this: https://groups.google.com/forum/?fromgroups#!topic/ossec-list/CcpufVmh6rM
So I installed a different version of gcc with ports, gcc47.
This put /opt/local/gcc-mp-4.7; i merely did sudo mv gcc-mp-4.7, ran the installer, and then moved it back. This succeeded, and then I got this build log:
http://pastebin.com/psbeAmrV
This was funny because it gave a LOT of warnings in the compilation of the components. Compilation didn't fail (I didn't put the compilation warnings in the pastebin link), but there was some funny inability to do chmod on ossec. It complained about some argument errors.... I'm not sure if that is something that I  should look into or if it will be ok, but I'm going to try and use it and hopefully things will work out fine. I'll look into things further if they don't pan out or if it malfunctions.


Final result: 

 - System is Darwin.
 - Init script modified to start OSSEC HIDS during boot.

 - Configuration finished properly.

 - To start OSSEC HIDS:
/var/ossec/bin/ossec-control start

 - To stop OSSEC HIDS:
/var/ossec/bin/ossec-control stop

 - The configuration can be viewed or modified at /var/ossec/etc/ossec.conf


    Thanks for using the OSSEC HIDS.
    If you have any question, suggestion or if you find any bug,
    contact us at contact@ossec.net or using our public maillist at
    ossec-list@ossec.net
    ( http://www.ossec.net/main/support/ ).

    More information can be found at http://www.ossec.net






Tuesday, April 17, 2012

Correctly configuring googlemock on Mac with eclipse

So, if you ever do C++ development on a mac, you'll want a unit testing framework.

The GoogleMock utility, available at http://code.google.com/p/googlemock/, includes both a unit testing framework and a system for creating mock objects. 

cppcheck and splint are both static source checkers, and they help you find errors in your C++ code. It's really cool to have a problem, not know how to fix it, discover that it is actually really vague and that it might take hours to find the source and solve it-only to be able to run a single command that will give you a strong indication or at least a hint of where to look to find the solution.

All, log4cxx is kind of a debugging tool with a lot more features than the usual printf statement. Enhance your execution having the ability to record where execution went and what every variable was when it ran! I haven't used log4cxx, but I know that if you use log4j, you could just add a line that would set the logging sensitivity, and if you set it to pedantic or something it would log the entrance into every function and every variable change.

I just spent a day or so configuring googlemock for a computer networks class project. I can say that if you don't read the instructions carefully, it will really bite you. 

If you are on a linux system, you can install of these with a single command:
sudo apt-get install google-mock cppcheck splint liblog4cxx10

But I've been doing all the work on mac, so I'll give step by step instructions on mac. After untarring: 
cd gmock-1.6.0 ; autoreconf -fvi ; GMOCK_DIR=/path/to/gmock-1.6.0 ; GTEST_DIR=$GMOCK_DIR/gtest ; 
g++ -I${GTEST_DIR}/include -I${GTEST_DIR} -I${GMOCK_DIR}/include -I${GMOCK_DIR} -c ${GTEST_DIR}/src/gtest-all.cc ; 
g++ -I${GTEST_DIR}/include -I${GTEST_DIR} -I${GMOCK_DIR}/include -I${GMOCK_DIR} -c ${GMOCK_DIR}/src/gmock-all.cc ; 
ar -rv libgmock.a gtest-all.o gmock-all.o

then move libgmock.a to $GMOCK_DIR/lib

cd $GMOCK_DIR/make ; make ; ./gmock_test && echo "all tests should succeed!"

#NOTE: you might have to run the configure command in $GMOCK_DIR somewhere along the line... I did it, but it's not in the instructions ; cd $GMOCK_DIR ; ./configure 

If you want eclipse to work with this, add a new build configuration and add the include files from gmock and gtest, then add the archive in the link step. To do all of these, in eclipse, go to project -> properties -> C/C++ General -> Paths and symbols -> includes
(make sure that you have the right build configuration selected, the ones that you will build and run your tests from.)
select GNU C++ under languages, and then on the right where it says add, click the button, then click filesystem. Add $GMOCK_DIR/include and $GTEST_DIR/include (not the variables, I mean actually navigate to those directories!)

Now that you've done that, to include the archive file in the link step:
Project -> properties -> C/C++ Build -> Settings -> MacOSX C++ Linker
In the command line pattern textbox, add the directory to your libgmock.a that you compiled, should be at $GMOCK_DIR/lib/libgmock.a

The above steps work on all platforms, but doing a manual setup is a pain, especially a nuisance because in linux you want everything to be managed by the repo. Because I did my setup on mac, I don't know where the libgmock.a file is, and I don't know if it automatically places the gmock include files in the default include path where it would just get found by the compiler if you just did #include <gmock/gmock.h>... You have to do your own exploring here, but it shouldn't be too hard, as the step are 1-1 from what I've done. Just find out how it sets up the include and if it drops a libgmock.a file anywhere, or if you have to compile that.

Tuesday, January 31, 2012

Custom VIM Auto Backup Plugin

Check out my public .vimrc and my custom plugin script.

http://dl.dropbox.com/u/19904351/.vimrc
http://dl.dropbox.com/u/19904351/custom_backup.vim

A little bit of info about this script:
each time that you save a file in vim, it automatically places it in $HOME/VIMBackups/ with some extra stuff on the end...
It creates a year month day directory, and inside that directory it places directory/ and then the directory and file of the file you just saved in vim.

So say you were working on ~/.vim/plugin/aplugin.vim, and then you saved it.

The script would create a new directory in Dropbox/VIMBackups/<year,month,day>/<full homedirectory>/.vim/plugin/aplugin.vim.(hour,minute,second).bak

Thursday, August 25, 2011

Port existing windows installation to vmware fusion using vmware converter

Please see my note at the bottom on why not to attempt to manually migrate your windows machine to virtual machine image.

Instead of using the migration assistant over the wire to migrate your pc (which requires too much space and is limited by speed) you can use vmware fusion to migrate your existing windows installation.

Convert physical machine to virtual machine. This is also an excellent tool because it allows you to migrate over the wire as well. Please see the link to the download and the manual below:

Download:
http://www.vmware.com/products/converter/

Manual:
http://www.vmware.com/pdf/VMware_Converter_manual.pdf


Why not to manually attempt to migrate existing windows machine to vmware image.
This is a bad idea to start with. I have several good reasons enumerated and expounded upon below

  1. The problem has already been solved for you by vmware. Why do it twice? The exising solution is expedient in relation to doing it manually. Repeatedly having to boot the windows machine into different ISO startup disks.
  2. Manually doing the backup may cause a lot of unnecessary pain.
    1. Manually sizing up the partitions in the virtual disk to reflect the windows machine is very likely to cause MBR problems when you copy the image(s) over.
    2. Continually doing work when the option to be lazy and accomplish the same thing is available is frowned upon by most computer scientists and software engineers I know.
  3. The vmware utility works for certain. It has capacities that are easy to use in comparison to the knowledge required to set clonezilla to work through a samba server over a command line.