Background DynDNS Update for iPod Touch

Discussion in 'iOS Jailbreak & Cydia' started by Egeste, Dec 27, 2008.

  1. Egeste

    Egeste New Member

    Joined:
    Jul 11, 2008
    Messages:
    9
    Likes Received:
    0
    So call me a little paranoid… But I wanted a way to be able to locate my iPod touch in the event it was stolen, and while Cylay is an attractive option for people who don’t mind paying a nominal yearly fee to locate, backup & wipe their jailbroken iPhone/iPod touch… I just wanted a way to know more or less where it is based on IP address and hence be able to find the network it’s on for my own personal amusement.

    To this end, I used the existing BDDC script and taylored it to my usage. Coupled with launchd and a php script on my server, there are alot of options available. For example (I havent set this up yet but…), it’s easy to imagine a scenario where you could have the script checkin with the server and notice that instead of an IP address, the server returns the string “stolen” - and then have the device perform a set of actions automatically (reverse-connect vnc/ssh, ping/nmap hosts on an internal network and report back the results, etc).

    The version I’m posting here is a stripped down version of the one I’m actually using, I’ll leave it to you and your enginuity to mod this to do your bidding. The code itself is actually quite simple =)

    bddc.sh - this is dyndns updater script. The way this file is currently setup, it should go into /var/mobile/Scripts

    Code:
    #!/bin/bash
    # exit codes:
    # 0  -> everything went fine
    # 1  -> some error occured during runtime
    # 2  -> some config error was caught
    # 11 -> ip address was private
    # 28 -> timeout at connecting to some host
     
    bddc_version="for_ipod_touch_by_Egeste"
     
    # executable paths
    cat=cat
    curl=curl
    date=date
    echo=echo
    egrep=egrep
    expr=expr
    grep=grep
    ifconfig=ifconfig
    ping=ping
    sed=sed
    uniq=uniq
     
    ######################
    # change logging level
    # 4 -> log every step, this is fine to see what bddc does (debugging mode) this is only prompted to the console if SILENT=0 AND LOGGING=4
    # 3 -> log whenever a check is done
    # 2 -> log when ip changes
    # 1 -> log errors (recommended for WRT environments)
    # 0 -> log nothing
    LOGGING=3
    LOGFILE=/var/mobile/Scripts/log/bddc.log
    ip_cache=/var/mobile/Scripts/cache/bddc_internal_ip.cache
    html_tmp_file=/tmp/bddc_html_tmp_file
     
    # turn silent mode on (no echo while running, [1 is silent])
    SILENT=0
    inet_if=en0
    check_url=YOUR_IPCHECK_ADDR
    remote_timeout=10
     
    #------------dyndns.org----------------
    dyndnsorg_username="YOUR_DYNDNS_UNAME"
    dyndnsorg_passwd="YOUR_DYNDNS_PASS"
    dyndnsorg_hostname=YOUR_DYNDNS_HOST
    dyndnsorg_wildcard=NOCHG
    dyndnsorg_mail=NOCHG
    dyndnsorg_backmx=NOCHG
    dyndnsorg_offline=NO
    dyndnsorg_ip=
     
    ########## / DNS Server Section ###########
    # the name of the client that is sent with updates and requests (do not change)
    bddc_name="bashdyndnschecker (bddc v${bddc_version})/bddc.klienux.org"
     
    # if you are using bddc on a wrt environment clear the cutting_string variable
    # do NOT edit this otherwise
    cutting_string="$echo ${str:${in1}:${in2}};" # for full featured Linux and Mac Os X
     
    # msg_error: print and/or log message of level error (1) according to settings; pass msg as arg;
    msg_error() {
    [ $SILENT -eq 0 ] && _msg_console "$@"
    [ $LOGGING -ge 1 ] && _msg_log "ERROR: $@"
    }
     
    msg_info() {
    [ $SILENT -eq 0 ] && _msg_console "$@"
    [ $LOGGING -ge 2 ] && _msg_log "INFO: $@"
    }
     
    msg_verbose() {
    [ $SILENT -eq 0 ] && _msg_console "$@"
    [ $LOGGING -ge 3 ] && _msg_log "VERBOSE: $@"
    }
     
    msg_tattle() {
    if [ $LOGGING -ge 4 ]; then
    _msg_log "VERBOSE: $@"
    [ $SILENT -eq 0 ] && _msg_console "$@"
    fi
    }
     
    _cut_string() {
    str=$1
    in1=$2
    in2=$3
    if [ "$( $expr substr "okokokok" 1 2 2> /dev/null )" == "ok" ]; then
    $echo $( $expr substr "${str}" ${in1} ${in2} )
    else
    let "in1=$in1 - 1"
    # moved this line into config space
    # (wrt users will get an error if this line is in the code)
    # $echo ${str:${in1}:${in2}};
    ${cutting_string}
    fi
    }
     
    # _msg_console: print message to console; pass msg as arg;
    _msg_console() {
    $echo -e "$@"
    }
     
    _msg_log() {
    $echo -e "[`$date +%d/%b/%Y:%T`] | $@" >> $LOGFILE
    }
     
    #### end of Functions
    #######################################
    if [ $LOGGING -ge 1 ]; then
    if [ ! -e ${LOGFILE} ] || [ ! -s ${LOGFILE} ]; then
    $echo "${bddc_name} Logfile:" >> ${LOGFILE} 2> /dev/null
    fi
    if [ ! -r ${LOGFILE} ] || [ ! -w ${LOGFILE} ] || [ -d ${LOGFILE} ]; then
    $echo "ERROR: Script has no write and/or no read permission for logfile ${LOGFILE}!"
    exit 2
    fi
    fi
     
    #############################
    #perform checks
    external=`$curl --connect-timeout "${remote_timeout}" -s -A "${bddc_name}" ${check_url} -o ${html_tmp_file}`
    internal=`$ifconfig ${inet_if} |$grep "inet " | $sed 's/[^0-9]*//;s/ .*//'`;
    ping_cur=`$ping -c 1 $dyndnsorg_hostname | grep "64 bytes from" | awk '{print $4}' | cut -d ":" -f1`
     
    # this fixes return values without ending newline, like wahtismyip.com automation page
    $echo -ne "\n\n" >> ${html_tmp_file}
    case $? in
    28) msg_error "timeout (${remote_timeout} second(s) tried on host: ${check_url})"; exit 28 ;;
    1)  msg_error "Could not download from host: \"${check_url}\", is it up?"; exit 1 ;;
    0)  msg_tattle "Got IP address from host: \"${check_url}\"" ;;
    esac
    #  Note: this was tested on few different sites and it works.  Your mileage may vary.
    #+ This looks for anything that is formatted like an IP number and prints it.
    #  Sites tested:
    #o http://www.whatismyip.com/automation/n09230945.asp
    #o http://ipdetect.dnspark.com:8888/
    #o http://www.ipchicken.com/
    #o http://checkip.dyndns.org/
    #o http://www.ip-number.com/index.asp
    #o http://www.lawrencegoetz.com/programs/ipinfo/
    #o http://www.cloudnet.com/support/getting_Connected/system.php
    #o http://www.mediacollege.com/internet/utilities/show-ip.shtml
    #  alt : |$sed -ne "s/[^0-9.]*\(\([0-9]\{1,3\}\.\)\{3\}\([0-9]\{1,3\}\)\).*/\1/p"  # doesn't work when there's a dot in the same line BEFORE the addr
    #  alt2: |$sed -ne "s/.*[^0-9]\(\([0-9]\{1,3\}\.\)\{3\}\([0-9]\{1,3\}\)\).*/\1/p"  # works well, one exception is when addr is on beginning of the line
    #  alt3: |$sed -ne "s/\(^\|.*[^0-9]\)\(\([0-9]\{1,3\}\.\)\{3\}\([0-9]\{1,3\}\)\).*/\2/p" |uniq  # works with all tested sites
    # current_ip=`$cat $html_tmp_file |$sed -ne "s/.*[^0-9]\(\([0-9]\{1,3\}\.\)\{3\}\([0-9]\{1,3\}\)\).*/\1/p" | $uniq ` # works well on Mac Os X
    #current_ip=`$cat $html_tmp_file | $egrep -e ^[\ \t]*\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}| $sed 's/ //g'`
     
    current_ip=`$cat $html_tmp_file |$sed -ne "s/\(^\|.*[^0-9]\)\(\([0-9]\{1,3\}\.\)\{3\}\([0-9]\{1,3\}\)\).*/\2/p" |$uniq`
     
    if [ "$current_ip" != "$ping_cur" ]
    then
     
    # dyndns.org
    dyndnsorg_ip=$current_ip;
    myurl=`$echo "http://${dyndnsorg_username}:${dyndnsorg_passwd}@members.dyndns.org/nic/update?system=dyndns&hostname=${dyndnsorg_hostname}&myip=${dyndnsorg_ip}&wildcard=${dyndnsorg_wildcard}&mx=${dyndnsorg_mail}&backmx=${dyndnsorg_backmx}&offline=${dyndnsorg_offline}"`
    dyndnsorg_feedback=`$curl --connect-timeout "${remote_timeout}" -s -A "${bddc_name}" ${myurl}`
     
    case $? in
    28) msg_error "timeout (${remote_timeout} second(s) tried on host: ${myurl})"; exit 28 ;;
    1)  msg_error "Could not connect to host: \"${myurl}\", is it up?"; exit 1 ;;
    0)  # everything went fine
    msg_tattle "Connected to host: \"${myurl}\""
    ;;
    esac
     
    if [ "$(_cut_string "${dyndnsorg_feedback}" 1 8)" == "badagent" ]; then
    msg_error "dyndns.org: ERROR The user agent that was sent has been blocked for not following the specifications (${dyndnsorg_feedback})"
    exit 1
    fi
     
    if [  "$(_cut_string "${dyndnsorg_feedback}" 1 5)" == "abuse" ]; then
    msg_error "dyndns.org: ERROR account blocked because of abuse (${dyndnsorg_feedback})"
    exit 1
    fi
     
    if [ "$(_cut_string "${dyndnsorg_feedback}" 1 7)" == "notfqdn" ]; then
    msg_error "dyndns.org: ERROR domain name is not fully qualified (${dyndnsorg_feedback})"
    exit 1
    fi
     
    if [ "$(_cut_string "${dyndnsorg_feedback}" 1 7)" == "badauth" ]; then
    msg_error "dyndns.org: ERROR bad authentication (${dyndnsorg_feedback})"
    exit 2
    fi
     
    if [ "$(_cut_string "${dyndnsorg_feedback}" 1 4)" == "good" ]; then
    msg_info "dyndns.org: update successful (${dyndnsorg_feedback})"
    fi
     
    if [ "$(_cut_string "${dyndnsorg_feedback}" 1 5)" == "nochg" ]; then
    msg_verbose "dyndns.org: still the same ip (${dyndnsorg_feedback})"
    fi
     
    msg_tattle "dyndns.org: $dyndnsorg_feedback"
     
    #logging
    msg_info "ip changed: $current_ip"
    $echo $internal > $ip_cache
     
    else
    msg_tattle "IP Address not changed since last update, skipping."
    fi
    msg_verbose "current ip: $current_ip"
     
    ## uncomment the next two lines for testing, to see if it works:
    # $echo $current_ip
    # exit 0
    rm $html_tmp_file
    sleep 300
    exit 0
    org.klienux.bddc.plist - This is the launchd Daemon plist file. This file goes in /Library/LaunchDaemons. To load it, type “launchctl load /Library/LaunchDaemons/org.klienux.bddc.plist”
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd>
    <plist version="1.0">
    	<dict>
    		<key>Label</key>
    			<string>org.klienux.bddc</string>
    		<key>ProgramArguments</key>
    			<array>
    				<string>bash</string>
    				<string>/var/mobile/Scripts/bddc.sh</string>
    			</array>
    		<key>KeepAlive</key>
    			<dict>
    				<key>NetworkState</key>
    				<true/>
    			</dict>
    	</dict>
    </plist>
    This a php script you can use on your server to show your IP address.
    PHP:
    <?php
        
    echo $_SERVER['REMOTE_ADDR'];
    ?>
    Make sure you look through the bddc.sh script and change any relevant values to match your desired settings. I WILL NOT BE SUPPORTING THIS SCRIPT

Share This Page