#!/bin/sh
#
# Set up global proxy used using the WPAD URL found using the the wpad
# DNS alias.  If no WPAD file is found, disable the use of a proxy.

set -e

log() {
	logger -t update-proxy-from-wpad "$@"
}

warning() {
	if [ -t 1 ] ; then # Only print warnings when stdout is a tty
		echo "warning: $@" 1>/dev/stderr
	fi
	logger -t update-proxy-from-wpad "warning: $@"
}

append_if_missing() {
	file="$1"
	string="$2"
	if [ -e "$file" ] ; then
		if ! grep -qxF "$string" "$file" ; then
			log "Appending '$string' to $file."
			echo "$string" >> $file
		fi
	fi
}

remove_if_matches() {
	file="$1"
	shift
	regexp="$@"
	if [ -e "$file" ] ; then
		if grep -qE "$regexp" "$file" ; then
			log "Removing line matching '$regexp' from $file."
			sed -i $file -e "/$regexp/d"
		fi
	fi
}

# Update /etc/environment with the current proxy settings extracted
# from the WPAD file
update_etc_environment() {
	file=/etc/environment
	touch $file
	chmod a+r $file
	sed -e "s%^http_proxy=.*%http_proxy=$http_proxy%" \
	    -e "s%^ftp_proxy=.*%ftp_proxy=$ftp_proxy%" \
	    -e "s%^https_proxy=.*%https_proxy=$https_proxy%" \
	    < $file > $file.new && chmod a+r $file.new

	# Only replace if new file have content and is different from the old
	# file
	if [ ! -s $file.new ] || cmp -s $file.new $file ; then
		rm $file.new
	else
		mv $file.new $file
	fi
	append_if_missing $file http_proxy=$http_proxy
	append_if_missing $file ftp_proxy=$ftp_proxy
	append_if_missing $file https_proxy=$https_proxy
}

# Make sure APT used from cron also get the wanted proxy settings
# /etc/apt/apt.conf is created by debian-installer if a proxy was used
# during installation, so we update this file.
update_apt_conf() {
	file=/etc/apt/apt.conf.d/03debian-edu-config
	touch $file
	chmod a+r $file
	sed -e "s%^Acquire::http::Proxy .*%Acquire::http::Proxy \"$http_proxy\";%" \
	    -e "s%^Acquire::ftp::Proxy .*%Acquire::ftp::Proxy \"$ftp_proxy\";%" \
	    -e "s%^Acquire::https::Proxy .*%Acquire::https::Proxy \"$https_proxy\";%" \
	    < $file > $file.new && chmod a+r $file.new

	# Only replace if new file have content and is different from the
	# old file
	if [ ! -s $file.new ] || cmp -s $file.new $file ; then
		rm $file.new
	else
		mv $file.new $file
	fi
	append_if_missing $file "Acquire::http::Proxy \"$http_proxy\";"
	append_if_missing $file "Acquire::ftp::Proxy \"$ftp_proxy\";"
	append_if_missing $file "Acquire::https::Proxy \"$https_proxy\";"

	# Fix main /etc/apt/apt.conf file (which we used until Debian Edu bullseye).
	#
	# FIXME: This code portion can be removed in the bookworm+1 release cycle
	previously_used_file=/etc/apt/apt.conf
	if [ -e $previously_used_file ]; then
		remove_if_matches $previously_used_file ".*Acquire::http::Proxy\ .*;"
		remove_if_matches $previously_used_file ".*Acquire::ftp::Proxy\ .*;"
		remove_if_matches $previously_used_file ".*Acquire::https::Proxy\ .*;"
	fi
}

update_dconf() {
	if ! command -v dconf >/dev/null; then
		# If the dconf command is not install, let's ignore it.
		# This might happen on main-server installations without
		# a desktop environment installed.
		return 0
	fi

	proxy_host="${http_proxy#*://}"
	proxy_port="${proxy_host##*:}"
	proxy_host="${proxy_host%:*}"
	cat >/etc/dconf/db/site.d/50-proxy <<EOF
[system/proxy/http]
host='${proxy_host}'
port=${proxy_port}
enabled=true

[system/proxy/https]
host='${proxy_host}'
port=${proxy_port}
enabled=true

[system/proxy/ftp]
host='${proxy_host}'
port=${proxy_port}
enabled=true
EOF
	dconf update
}

if [ -r /etc/debian-edu/config ] ; then
	. /etc/debian-edu/config
fi

# Make sure to fetch the wpad file without proxy settings, to behave
# like browsers who need to get their proxy settings without using a
# proxy.
http_proxy=$(/usr/share/debian-edu-config/tools/wpad-extract 2>/dev/null || true)

if [ -z "$http_proxy" ]; then

	warning "Failed to extract proxy host from WPAD data. Not configuring proxy usage."

else

	ftp_proxy=$http_proxy
	https_proxy=$http_proxy

	update_apt_conf

	# Do not set proxy in /etc/environment and dconf for machines that
	# move around, # as the value will be wrong when arriving at a new
	# network.
	case $PROFILE in
	*Roaming-Workstation*|*Standalone*) ;;
	*)
		update_etc_environment
		update_dconf
	esac
fi
