Skip to content

Instantly share code, notes, and snippets.

@Robertof
Created April 24, 2016 23:58
Show Gist options
  • Save Robertof/4c07fe562aebcb4be8983888aba21c2a to your computer and use it in GitHub Desktop.
Save Robertof/4c07fe562aebcb4be8983888aba21c2a to your computer and use it in GitHub Desktop.
Hassle-free automatic IP renewer for what is known as "Technicolor AG plus VDNT-S Router VDSL2" or "Telecom Italia VDSL/Fibra modem".
#!/usr/bin/env bash
# Technicolor AG plus VDNT-S Router VDSL2 - (ba)sh IP renewer
# This script logs into the router and refreshes the IP address by toggling on
# and off the "automatic connection" parameter.
# It *NEEDS* to be configured. Please keep reading.
# Disable globbing, die on undefined variables and errors
set -efu
# Configuration
# IP address of your router
readonly ROUTER_ADDRESS="192.168.1.1"
# There are three ways to specify the password to access your router.
# - Use the password in *plaintext*. (WARNING: potentially insecure)
# - Hash the following string in MD5, either
# * manually, with:
# echo -n 'admin:Technicolor Gateway:password' | md5sum
# * or automatically, running this script with the parameter '-p'
# - Do the same, but using environment variables (ROUTER_PASSWORD=xxx ./script.sh).
[ -z ${ROUTER_PASSWORD+isset} ] &&
ROUTER_PASSWORD=""
# End of configuration
readonly DEFAULT_REALM="Technicolor Gateway"
readonly AUTHSTRING_PATH="5c7b0fdd32ff96ac19193e89df9c0d9d" # MD5 hash of 'GET:/index_auth.lp'
croak() { echo >&2 "ERROR: $*"; exit 1; }
get_md5() { echo -n "$1" | md5sum | awk '{print $1}'; }
# Test for dependencies
for executable in md5sum awk cut grep curl tail; do
command -v "$executable" >/dev/null 2>&1 ||
croak "'$executable' not found in \$PATH"
done
# Allow to generate "secure" passwords using `-p`
if [ "${1:-}" == "-p" ]; then
echo '** Password generation mode **'
echo 'Please enter the authentication realm of your router:'
read -p "[$DEFAULT_REALM] " realm
echo 'Please enter the password of your router' \
"(won't be displayed)"
read -s password
echo "*** Here's your encoded password. ***"
echo 'Use it with an environment variable or by editing' \
'the source of this script.'
get_md5 "admin:${realm:-$DEFAULT_REALM}:$password"
exit 0
fi
# Normal mode -- ensure that the password is not empty
[ -z "$ROUTER_PASSWORD" ] &&
croak 'The specified password is empty!' \
'Try running the script with `-p`.'
# Initiate the authentication procedure
echo -n "Retrieving authentication parameters: "
temp_storage="$(mktemp -d)"
trap "rm -rf $temp_storage" EXIT
req="$(
curl -sLc "$temp_storage/cookies" "http://$ROUTER_ADDRESS" | \
grep -Eo '(nonce|qop|realm) = "([^"]+)"'
)"
# Retrieve xAuth_SESSION_ID
read -r _ _ _ _ _ cookie_name cookie_value <<<"$(tail -n 1 $temp_storage/cookies)"
[ "$cookie_name" != "xAuth_SESSION_ID" ] &&
croak "Can't find xAuth_SESSION_ID!"
unset cookie_name
echo -n 'xAuth '
# Retrieve QOP/nonce/realm
while read line; do
var_name="$(echo "$line" | cut -d' ' -f1)"
var_value="$(echo "$line" | cut -d' ' -f3- | grep -Eo '[^"]+')"
# Bash magic
declare $var_name="$var_value"
echo -n "$var_name "
done <<<"$req"
echo
# Ensure that we got the required variables
[ -z ${nonce+isset} ] && croak 'ERROR: missing `nonce`'
[ -z ${qop+isset} ] && croak 'ERROR: missing `qop`'
[ -z ${realm+isset} ] && croak 'ERROR: missing `realm`'
# Generate the password hash
echo "Logging in..."
# Encode the password if it's not already an MD5 hash.
[ "${#ROUTER_PASSWORD}" -ne 32 ] &&
ROUTER_PASSWORD="$(get_md5 "admin:$realm:$ROUTER_PASSWORD")"
# Generate the final MD5 hash
ROUTER_PASSWORD="$(get_md5 "$ROUTER_PASSWORD:$nonce:00000001:xyz:$qop:$AUTHSTRING_PATH")"
# Log in
req="$(
curl -sic "$temp_storage/cookies" -b "$temp_storage/cookies" -XPOST \
--data-urlencode "rn=$cookie_value" \
--data-urlencode "hidepw=$ROUTER_PASSWORD" \
"http://$ROUTER_ADDRESS/index_auth.lp"
)"
echo $req | grep -vq passwordko ||
croak "Incorrect password!"
# We are now logged in, probably! Yay!
echo "Refreshing your IP address..."
toggle_wanStatus() {
curl -sb "$temp_storage/cookies" -XPOST \
--data-urlencode "rn=$cookie_value" \
"http://$ROUTER_ADDRESS/wanStatus.lp" | \
grep -o "<td colspan='2'.*" | \
cut -d'>' -f2 | cut -d'<' -f1
}
echo "Status:"
for i in 1 2; do
toggle_wanStatus
done
echo "Done!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment