#!/usr/bin/perl

# (c) 1999,2000 Mathijs Maassen

#------------------------------------
# /etc/ppp/chap-secrets:
# dashboard login    server  password
# F10xxxxxxx         *       xxx
#------------------------------------
# /etc/ppp/pap-secrets:
# xs4all login       server  password
# loginname          xs4all  xxx
#------------------------------------

use strict;
use IO::Socket;
use Sys::Syslog;

my $service      = "xs4all-F04"; # Basic ADSL
#my $service      = "xs4all-F03"; # Fast ADSL

my $host         = "10.128.1.6";
my $port         = "80";
my $chap_secrets = "/etc/ppp/chap-secrets";
my $pap_secrets  = "/etc/ppp/pap-secrets";

openlog("adsl-login", "pid", "daemon");
Sys::Syslog::setlogsock("unix");

my ($adsl_login, $adsl_pass) = &getpass("\\*", $chap_secrets);
my ($isp_login, $isp_pass)   = &getpass("xs4all", $pap_secrets);

$isp_login = urlencode($isp_login);
$isp_pass  = urlencode($isp_pass);

syslog("notice", "Connecting to $host:$port");

my @resp = sendtoserver("GET / HTTP/1.0\r\n" .
	"\r\n");

for (@resp) {
	($host, $port) = m!^Location: http://(\S+?):(\d+)! and last;
}

syslog("notice", "Redirected to $host:$port");

sendtoserver("GET /dashboard?fcn=viewService&service=${service} HTTP/1.0\r\n\r\n");

sendtoserver("GET /dashboard?fcn=serviceLogon&service=${service}&username=${isp_login}&password=${isp_pass} HTTP/1.0\r\n\r\n");

my $body;
for (sendtoserver("GET /dashboard?fcn=viewService&service=${service} HTTP/1.0\r\n\r\n")) {
	chomp;
	$body = 1 if /^$/;
	next if not $body;
	s/<br>/ /gi;
	s/(<.+?>|\s*$|^\s*)//g;
	next if not $_;
	syslog("notice", $_);
}

exit;

sub urlencode
{
	$_[0] =~ s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x", ord($1))/eg;
	return $_[0];
}

sub mydie
{
	syslog("notice", "@_");
	die "@_";
}

sub getpass
{
	my ($server, $secrets) = @_;
	my ($user, $pass);
	open(F, "<$secrets") or mydie("$secrets: $!\n");
	while (<F>) {
		($user, $pass) = /^(\S+)\s+$server\s+(\S+)/ and last;
	}
	close(F);
	mydie("$server not found in $secrets\n") if not $pass;
	return ($user, $pass);
}

sub sendtoserver
{
	my $sock = new IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => 'tcp');
	if (not $sock) {
		syslog("notice", "Connect to $host:$port failed");
		exit;
	}
	print $sock $_[0];
	my @lines = <$sock>;
	close($sock);
	print "@lines\n";
	return @lines;
}

