#!/bin/sh # v1.2 # 2010.02.12 # Add better portal pulling and rework the inital stages to require fewer page pulls (read: faster). # This hopefully means no more viewstate tweaks! # Fix by kmoore. # v1.1 # 2009.10.28 # Add automated state variable pulling for the last stage. # This means no more viewstate tweaks! # Fix by kmoore. # v1.0 # 2009.06.30 # Add automated state variable pulling for the first stage. # Fix by kmoore. # v0.9.1 # 2009.06.10 # Add an option to skip the warning message for those that know. # Fix by kmoore. # v0.9 # 2009.06.06 # ADP changed their site again. Viewstate dependencies are now in all # stages of the login process. There is also a new eventvalidation field. # The viewstate stuff needs to be automated now. # Fix by kmoore. # v0.8 # 2009.05.27 # ADP changed their site again. All that was needed was a cookie tweak. # I may look into automating the cookie pull so it's no longer an issue. # Fix by kmoore. # v0.7 # 2009.02.18 # ADP changed their site once again, requiring a viewstate and cookie tweak. # Fix by nhuskinson. # v0.6 # 2008.05.27 # ADP changed how their site worked. :( # Cleaned up a lot # Added dynamic version info (faaaaaaannnnnncy) # v0.5 # 2007.11.02 # ADP likes to change our path, but that's easy because now we're thinking with portals # v0.4 # 2007.07.27 # Added in timecard option sent in by nhuskinson # v0.3 # 2007.05.21 # Added more debuging support # Added in benefits support thanks to kmoore's code # v0.2 # 2007.04.?? # Moved password prompt to stderr for better scripting # Fixed a typo in the warning # v0.1 # 2007.04.03 # Initial release version="ADP login/out script $(cat $0 | grep "^#" | head -n 2 | tail -n 1 | awk '{print $2}') $(cat $0 | grep "^#" | head -n 3 | tail -n 1 | awk '{print $2}') -MKN" # define some vars dostatus="" dobenefits="" clockstatus="" verbose="" skipwarning="" dotimecard="" username= password= # get our opts TEMP=`getopt -o yvVu:p:sbiolt --long username:password:status:benefits:in:out:lunch:timecard:: -- "$@"` # Note the quotes around `$TEMP': they are essential! eval set -- "$TEMP" while true ; do case "$1" in -u|--username) username=$2; shift 2 ;; -p|--password) password=$2; shift 2 ;; -s|--status) dostatus="1"; shift ;; -b|--benefits) dobenefits="1"; shift ;; -t|--timecard) dotimecard="1"; shift ;; -i|--in) clockstatus="IN"; shift ;; -o|--out) clockstatus="OUT"; shift ;; -l|--lunch) clockstatus="LUNCH"; shift ;; -V) echo $version; exit; shift ;; -v) verbose="1"; shift ;; -y) skipwarning="1"; shift ;; --) shift ; break ;; *) echo Internal error! $1 ; exit 1 ;; esac done # check our parms if [ -z "$dostatus" ] && [ -z "$dobenefits" ] && [ -z "$dotimecard" ] && [ -z "$clockstatus" ]; then echo "Usage: $0 -u|--username -p|--password -s|--status -b|--benefits -t|--timecard -i|--in -o|--out -l|--lunch" >&2 echo " if username is unset then it will pull the current user's" >&2 echo " if password is a file on disk then it will read that for the password (highly unsafe, but really, it's only ADP...)" >&2 echo " if password is unset then it will prompt for the password" >&2 echo " the -y option can be used to skip the warning message if you already know the spiel" >&2 exit 1 fi # if you trust me... if [ -z "$skipwarning" ]; then echo -n "WARNING: This script is beta. There is no warrenty that this program will not sell all your files to the Russian government, puree your children and serve your soft drinks warm. Are you sure you want to continue(y/n)?" read sane if [ "$sane" != "y" ]; then exit 1 fi fi # ... use the -y option # default username? if [ -z "$username" ]; then username=`whoami` fi if [ -n "$verbose" ] ; then echo Username set to $username fi # prompt for password? if [ -e "$password" ]; then password=`cat "$password"` elif [ -z "$password" ]; then stty_orig=`stty -g` stty -echo echo -n Password for $username@adp: >&2 read password echo stty $stty_orig fi if [ -n "$verbose" ] ; then echo Password set to $password fi # toss our cookies rm /tmp/cookies.jar 2>/dev/null rm /tmp/portalstate.jar 2>/dev/null rm /tmp/curl.portalstate 2>/dev/null rm /tmp/curl.newview 2>/dev/null USERAGENT="Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.3) Gecko/20091010 Iceweasel/3.5.5 (like Firefox/3.5.5; Debian-3.5.5-1)" # pull portal and app variables curl -A "$USERAGENT" -b "Cookie: ezLaborManager=CompanyID=29781&CompanyName=DIGIUM&Language=en-US; elabor%2Ecom+Time=2=29781&1=DIGIUM;" "https://workforceportal.elabor.com/ezLaborManagerNetRedirect/ClientLogin.aspx?lng=en-US" -c /tmp/portalstate.jar 2>/dev/null > /tmp/curl.portalstate app=`cat /tmp/curl.portalstate | grep action | tail -n 1 | awk -F\" '{print $6}'| awk -F\/ '{print $3}'|sed 's/portal/app/'` portal=`cat /tmp/portalstate.jar|grep APP|sed 's/.*APP_POD //'`; if [ -n "$verbose" ] ; then echo Portal path is "$portal" echo App path is "$app" fi # pull secondary state variable curl -A "$USERAGENT" -b "Cookie: ezLaborManager=CompanyID=29781&CompanyName=DIGIUM&Language=en-US; EZLM_DC2_APP_POD=$portal;" -e "https://$portal/ezLaborManagerNetRedirect/ClientLogin.aspx?lng=en-US" "https://$app/ezLaborManagerNet/Login/Login.aspx?cID=29781&lng=en-US" -c /tmp/cookies.jar 2>/dev/null > /tmp/curl.newview viewstate=`cat /tmp/curl.newview | grep input|grep "VIEWSTATE"|sed 's/^.*value="//;s/".*$//;'|perl -MURI::Escape -lne 'print uri_escape($_)'` eventvalidation=`cat /tmp/curl.newview | grep input|grep "EVENTVALIDATION"|sed 's/^.*value="//;s/".*$//;'|perl -MURI::Escape -lne 'print uri_escape($_)'` if [ -n "$verbose" ] ; then echo Viewstate is $viewstate echo Eventvalidation is $eventvalidation fi # fetch our session id curl -A "$USERAGENT" -b "Cookie: ezLaborManager=CompanyID=29781&CompanyName=DIGIUM&Language=en-US; EZLM_DC2_APP_POD=$portal;" -d "__EVENTTARGET=btnLogin&__EVENTARGUMENT=&__VIEWSTATE=$viewstate&__EVENTVALIDATION=$eventvalidation&txtUserID=$username&txtPassword=$password" -e "https://$app/ezLaborManagerNet/Login/Login.aspx?cID=29781&lng=en-US" "https://$app/ezLaborManagerNet/Login/Login.aspx?cID=29781&lng=en-US" -c /tmp/cookies.jar 2>/dev/null >/tmp/curl.sid SID=`cat /tmp/cookies.jar | grep elSessionId | sed -e "s/^.*elSessionId=//;s/&.*$//"` if [ -n "`echo $SID | grep HTML`" ]; then echo "Bad user/pass for $username" exit 1 fi if [ -n "$verbose" ] ; then echo SID: is $SID else rm /tmp/curl.sid fi if [ `echo $SID | wc -c` != 33 ]; then echo "SID $SID fails sanity check" exit 1 fi # now, what do we want to do with our sid? if [ -n "$clockstatus" ]; then status=`curl -b /tmp/cookies.jar -d "{\"strXml\":\"undefinedundefinedundefinedundefined$SID$clockstatus\"}" -A "$USERAGENT" -e "https://$app/ezLaborManagerNet/EmployeeServices/EmployeeServicesStart.aspx?sID=$SID" -H "X-AjaxPro-Method: PerformClockFunction" "https://$app/ezLaborManagerNet/ajaxpro/ADP.EZLM.Web.AjaxLib.ClockFunctionProvider,ADP.EZLM.Web.AjaxLib.ashx" 2>/dev/null` if [ -n "`echo $status | grep Operation%20Successful`" ]; then echo "Success!" else echo "Error! status = $status" exit 1 fi fi if [ "$dostatus" = "1" ]; then # fetch status curl -b /tmp/cookies.jar -A "$USERAGENT" "https://$app/ezLaborManagerNet/EmployeeServices/EmployeeServicesStart.aspx?sID=$SID" 2>/dev/null | awk '/DataTable-BodyRow-Odd"/,/table/' | sed -e 's/ *//g' | grep -A 1 "" | egrep -v "^-|^<" fi if [ "$dobenefits" = "1" ]; then # fetch benefits curl -b /tmp/cookies.jar -A "$USERAGENT" -e "https://$app/ezLaborManagerNet/Login/Login.aspx?cID=29781&lng=en-US" "https://$app/ezLaborManagerNet/EmployeeServices/MyBenefits.aspx?sID=$SID" 2>/dev/null | awk '/DataTable-BodyRow-Odd"/,/table/' | sed -e 's/ *//g' | sed -e 's/\x0d//' | egrep -v "^&" | grep -A 7 "/dev/null | awk '/lbl_Actual/,/<\/td>/' | sed -e 's/ *//g' | sed -e 's/.*\(20[0-9]\+\-[0-9]\+\-[0-9][0-9]\).*t\"[a-z<>;]*\([0-9]\+.[0-9]\+\|\&\)[a-z<>;\/]*/\2 for week ending \1/g' | sed -e 's/&/0.00 /' fi if [ -z "$verbose" ] ; then # toss our cookies rm /tmp/cookies.jar /tmp/portalstate.jar /tmp/curl.portalstate /tmp/curl.newview fi