168 lines
3.7 KiB
Bash
Executable File
168 lines
3.7 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# Freetz! Web manager
|
|
# caskd
|
|
# CC0
|
|
|
|
: ${FB_ENDPOINT:-'192.168.178.1'}
|
|
: ${FB_CONFIG_PASS:-'defaultpassword'}
|
|
|
|
main() {
|
|
for i in curl iconv md5sum cut xmlstarlet; do
|
|
which "$i" >/dev/null || log_error "Missing dependency: $i"
|
|
done
|
|
|
|
log_info "Creating session"
|
|
FB_SESSION="$(fb_auth)"
|
|
if [ -z "$FB_SESSION" ]; then
|
|
return "$?"
|
|
fi
|
|
|
|
for arg in $@; do
|
|
case "$arg" in
|
|
export|import) eval fb_"$arg" || return "$?";;
|
|
*) ret="$?"; log_error "Invalid command $arg"; return "$ret";;
|
|
esac
|
|
done
|
|
}
|
|
|
|
log_error() {
|
|
printf '%s\n' "$1" >&2
|
|
}
|
|
|
|
log_info() {
|
|
printf '%s\n' "$1" >&2
|
|
}
|
|
|
|
fb_auth() {
|
|
local \
|
|
fb_endpoint="$FB_ENDPOINT" \
|
|
fb_username="$FB_USERNAME" \
|
|
fb_password="$FB_PASSWORD"
|
|
|
|
if [ -z "$fb_password" ]; then
|
|
log_error "Missing login password"
|
|
return 1
|
|
fi
|
|
|
|
log_info "Fetching login info from $fb_endpoint"
|
|
local login_data="$( \
|
|
if ! curl -sSLf "http://$fb_endpoint/login_sid.lua"; then
|
|
ret="$?"
|
|
log_error "Failed to fetch login data"
|
|
return "$ret"
|
|
fi
|
|
)"
|
|
|
|
local auth_challange="$( \
|
|
printf '%s' "$login_data" | \
|
|
xmlstarlet sel -t -v '/SessionInfo/Challenge' \
|
|
)"
|
|
|
|
if [ -z "$auth_challange" ]; then
|
|
log_error "Got empty challange back"
|
|
return 1
|
|
fi
|
|
|
|
# If no user is given, pick the user that was last used
|
|
if [ -z "$fb_username" ]; then
|
|
local fb_username="$( \
|
|
printf '%s' "$login_data" | \
|
|
xmlstarlet sel -t -v '/SessionInfo/Users//User[@last=1]' \
|
|
)"
|
|
|
|
# If no user authenticated, pick the first user
|
|
if [ -z "$fb_username" ]; then
|
|
local fb_username="$( \
|
|
printf '%s' "$login_data" | \
|
|
xmlstarlet sel -t -v '/SessionInfo/Users//User[1]' \
|
|
)"
|
|
fi
|
|
|
|
if [ -z "$fb_username" ]; then
|
|
log_error "Failed to autodetect username"
|
|
return 1
|
|
else
|
|
log_info "No username given, picking '$fb_username'"
|
|
fi
|
|
fi
|
|
|
|
log_info "Got challange $auth_challange"
|
|
local hashed="$( \
|
|
printf '%s' "$auth_challange-$fb_password" | \
|
|
iconv -f ISO8859-1 -t UTF-16LE | \
|
|
md5sum -b | \
|
|
cut -d' ' -f1)"
|
|
|
|
local response="$auth_challange-$hashed"
|
|
|
|
log_info "Sending challange response $response"
|
|
local session_id="$( \
|
|
curl -sSLf "http://$fb_endpoint/login_sid.lua" \
|
|
--data-urlencode "username=$fb_username" \
|
|
--data-urlencode "response=$response" | \
|
|
xmlstarlet sel -t -v '/SessionInfo/SID' \
|
|
)"
|
|
|
|
if [ "$session_id" == "0000000000000000" ]; then
|
|
log_error "Failed to log in"
|
|
return 1
|
|
fi
|
|
|
|
printf '%s' "$session_id"
|
|
log_info "Authenticated"
|
|
}
|
|
|
|
fb_export() {
|
|
local \
|
|
fb_endpoint="$FB_ENDPOINT" \
|
|
fb_session="$FB_SESSION" \
|
|
fb_config_pass="$FB_CONFIG_PASS"
|
|
|
|
log_info "Exporting configuration of $fb_endpoint"
|
|
if ! curl -\# -Lf "http://$fb_endpoint/cgi-bin/firmwarecfg" \
|
|
-X POST \
|
|
--form-string sid="$fb_session" \
|
|
--form-string ImportExportPassword="$fb_config_pass" \
|
|
--form-string ConfigExport=''
|
|
then
|
|
ret="$?"
|
|
log_error "Failed to export configuration"
|
|
return "$ret"
|
|
fi
|
|
}
|
|
|
|
fb_import() {
|
|
local \
|
|
fb_endpoint="$FB_ENDPOINT" \
|
|
fb_session="$FB_SESSION" \
|
|
fb_config_pass="$FB_CONFIG_PASS"
|
|
|
|
log_info "Telling Fritz! Box to load the entire configuration"
|
|
if ! curl -sSLf "http://$fb_endpoint/data.lua" \
|
|
-X POST \
|
|
--form-string sid="$fb_session" \
|
|
--form-string ImportExportPassword="$fb_config_pass" \
|
|
--form-string cfgtakeover='all' \
|
|
--form-string restore='' >/dev/null
|
|
then
|
|
ret="$?"
|
|
log_error "Failed to set configuration restore options"
|
|
return "$ret"
|
|
fi
|
|
|
|
log_info "Uploading configuration via STDIN"
|
|
if ! curl -\# -Lf "http://$fb_endpoint/cgi-bin/firmwarecfg" \
|
|
-X POST \
|
|
--form-string sid="$fb_session" \
|
|
--form-string ImportExportPassword="$fb_config_pass" \
|
|
-F ConfigImportFile="@-;filename=config.cfg;type=application/octet-stream" >/dev/null
|
|
then
|
|
ret="$?"
|
|
log_error "Failed to upload configuration"
|
|
return "$ret"
|
|
fi
|
|
}
|
|
|
|
main $@
|