Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 1 Jul 2005 10:10:11 -0400
From:      Hornet <hornetmadness@gmail.com>
To:        John Cholewa <freebsd-questions@jc-news.com>
Cc:        freebsd-questions@freebsd.org
Subject:   Re: autoblocking many ssh failed logins from the same IP....
Message-ID:  <f42935a6050701071012cbba8a@mail.gmail.com>
In-Reply-To: <42C54872.50106@jc-news.com>
References:  <42C54872.50106@jc-news.com>

next in thread | previous in thread | raw e-mail | index | archive | help
------=_Part_1981_9202288.1120227011684
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Below (and atached) is a script I wrote do exactly what you are talking abo=
ut.
It's commented, so edit to your taste. I have been using to for about 4 mon=
ths.

Since I am using PF as my firewall, it is customized for that. If you
are using something other then PF, again... edit to your taste.

-Erik-

#!/usr/bin/perl
# created by hornetmadness@gmail.com 03/05

my $time=3Dlocaltime();

use strict;
use Time::localtime;
use Mail::Send;

my $hostname=3D"domain.orIP.com";

#The white list that contains either the account or host.
my $whilelist=3D"/home/user/scripts/sshwhitelist";

#LOG to search on
my $logfile=3D"/var/log/auth.log";

#Where to read the current list of blackhole address.
my $blacklist=3D"/etc/pf.blackholes";

#Name of the table in your pf.conf
my $tablename=3D"blackhole";

#Where to store the cache file. This is removed and updated daily
my $cache=3D"/root/.sshprotect.cache";

#Where to log actions taken.
my $log=3D"/root/sshprotect.log";

#Command you want to run in response of a potential attack.
my $command=3D"whois";
my $useip=3D1;  #useful in conjunction with $command which will do
something with the IP.
            #comment out if not needed.

#Max attempts a host can have until blocked.
my $attempts=3D5;

# Set this to "run" the $command or "print" a report or "email" the report,
# also "update" will update the $blacklist and reload the blackholes table.
# "abuse" will try to find and email the offending network about the attack
# These can be combind to run all actions:
#my $action=3D"run print";
#my $action=3D"print";
my $action=3D"email run update abuse";
#my $action=3D"print email update";
#my $action=3D"print email";

#Email setup;
my $to=3D"to\@email.com";
my $from=3D"from\@email.com";
my $cc=3D"";
my $subject=3D"Excesssive login attempts";


my $debug=3D0;

my $host;
my @logs;
my @whtlst;
my %track;
my @blacklist;
my $block=3D1;
my @abuse;
my @cache;
my $currentcache;
my @runoutput;

my $version=3D"1.2.1beta";
print "Version: $version\n" if $debug;

#find todays datemask
use vars qw($yr $mon $day $today $mday);
$yr=3Dlocaltime->year() + 1900;
$mon=3Dlocaltime->mon() + 1;
$mday=3Dlocaltime->mday();
if ($mon !=3D /\d\d/) {$mon=3D"0$mon";}
if ($mday < 10) {$mday=3D"0$mday";}
$today=3D"$yr$mon$mday";
print "$today\n" if $debug;
#no Time::localtime;

open (WRITELOG, ">> $log") || die "$log $!\n";

open (BLACK,$blacklist) || die "$blacklist $!\n";
while (<BLACK>) {
  chomp;
  push (@blacklist, $_);
}
close BLACK;

open (WHITE, $whilelist) || die "$whilelist $!\n";
while (<WHITE>) {
  chomp;
  push (@whtlst,$_);
}
close WHITE;

open (READCACHE, $cache) || print "$cache $!\n";
while (<READCACHE>) {
  chomp;
  push (@cache, $_);
}
close READCACHE;

open (WRITECACHE, ">> $cache") || print "$cache $!\n";

if (@cache[0] < $today) {
  close WRITECACHE;
  system ("rm -f $cache");
  open (WRITECACHE, ">> $cache") || print "$cache $!\n";
  print "Cache file is out of date @cache[0] < $today\n" if $debug;
  @cache=3D();
  print WRITECACHE "$today\n"
}

open (LOG, $logfile) || die "logfile $!";
while (<LOG>) {
  chomp;

  if (
    /Failed password for illegal user (.*) from (.*) port/
    || /Failed password for (.*) from (.*) port/
    || /Illegal user (.*) from (.*)/
    || /Did not (receive) identification string from (.*)/
     ) {

    my $account=3D$1;
    my $host=3D$2;

    ckwhtlst($account, $host);
    if ($block =3D=3D 0 ) { next; }
    ckcache($host);
    if ($block =3D=3D 0 ) { next; }
    ckblklst($host);
    if ($block =3D=3D 0 ) { next; }
    $block=3D1;
    if ($track{$host}) {
      $track{$host}=3D$track{$host}+1;
      print "$host is now $track{$host} user=3D$account\n" if $debug;
    } else { $track{$host}=3D1; }
  }
}
close LOG;

for my $host (%track) {
  if (!$host) {print "Nothing Found\n"; exit;}
  if ($track{$host} >=3D $attempts) {
    push (@abuse,$host);
    ckcache($host);
    print WRITECACHE "$host\n" if !$block =3D=3D 0;
    if ($action =3D~ /print/) { print "Host $host, past $attempts
attempted logins\n"; }
    if ($action =3D~ /run/ && $useip) { (@runoutput=3D`$command $host`); }
    if ($action =3D~ /run/ && !$useip) { (@runoutput=3D`$command`); }
    if ($action =3D~ /update/) { update($host); }
  }
}


#Sends emails
if ($action !~/email/) {
  exit;
} elsif (@abuse) {
  send_email(@abuse);
}

if ($action !~/abuse/) {
  exit;
} elsif (@abuse) {
  abuse_email(@abuse);
}

sub ckwhtlst {
  (my $account, my $host)=3D@_;
  foreach (@whtlst) {
    if (!/$account|$host/) {
      $block=3D1;
      return;
    } else {
      print "$host or $account is on the while list.\n" if $debug;
      $block=3D0;
      return;
    }
  }
}

sub ckblklst {
  my $host=3D@_[0];
  foreach (@blacklist) {
    if (/$host/) {
     print "$host $_ is already blacklisted\n" if $debug;
      $block=3D0;
      return;
    } else { $block=3D1; } #print "$host is NOT blacklisted\n" if $debug; }
  }
}
sub ckcache {
  my $host=3D@_[0];
  if (!@cache) { $block=3D1; return;}
  foreach (@cache) {
    if (/$host/) {
      $block=3D0;
      print "$host is already cached\n" if $debug;
      return;
    } else { $block=3D1; } #print "$host is not found in cache\n" if $debug=
; }
  }
}

sub update {
  open (OUT, ">> $blacklist") || die "$blacklist $!\n";
  print OUT "@_[0]\n";
  system ("pfctl -t $tablename -f /etc/pf.conf");
  close OUT;
}

sub send_email {
  my $subject=3D"$subject $today";
  my $msg =3D new Mail::Send;
  my $host;
  $msg->subject($subject);
  $msg->to($to);
  $msg->cc($cc) if $cc;
  $msg->add("From", "$from");
  $msg->add("Return-Path", "$from");
  $msg->add("Reply-To", "$from");

  my $fh=3D$msg->open;

  foreach (@_) {
    $host=3D$_;
    if (!$track{$_}) {return;}
    print $fh "\nThe host $_ has $track{$_} attempted logins.\n";
  }
  print $fh "\nThe threshold is set to $attempts attempts\n";
  print $fh "\nActions taken: $action\n\n";
  if (($action =3D~/run/ && $command) && !$useip) { print $fh "Ran:
$command\n\n Output:\n@runoutput"; }
  if (($action =3D~/run/ && $command) && $useip) { print $fh "Ran:
$command $host,\n\n Output:\n@runoutput"; }

  print $fh "\nVersion: $version\n";
  print "Sending email\n" if $debug;
  print WRITELOG "$time Sent email to $to about $_ \"$subject\"\n";
  $fh->close;
}

sub abuse_email {
  $subject=3D"[ABUSE] $subject $today";
  my $msg;
  my $fh;
  my $acct;
  my $domain;

  foreach my $ip (@_) {
    my $syntax=3D"$ip SOA";
    if (!$track{$ip}) {return;}
    if (~/\d{1,3\.\d{1,3}\.\d{1,3}\.\d{1,3}/) { $syntax=3D"-x $ip SOA"; }

    print "Running dig $syntax\n" if $debug;
    my @dig=3D`/usr/bin/dig $syntax`;

    foreach my $dig (@dig) {
      if ($dig =3D~ /in-addr\.arpa\..*SOA\t.*\. (.*)\./) {
        my $addy=3D$1;
        if (!$addy) { next; }
        if ($addy =3D~ /(\w+)\.(.+)/) {
          $acct=3D$1;
          $domain=3D$2;
        }
        $to=3D"$acct\@$domain";

        print "Found $to from Dig\n" if $debug;

        $msg =3D new Mail::Send;
        $msg->subject($subject);
        $msg->to($to);
        $msg->cc($cc) if $cc;
        $msg->add("From", "$from");
        $msg->add("Return-Path", "$from");
        $msg->add("Reply-To", "$from");
        $fh=3D$msg->open;
        print $fh "\nThis host $ip has attempted $track{$ip} erroneous
ssh logins to my server $hostname on $today.\n";
        print $fh "Please report this to your customer and advise them
on any AUP violations you enforce.\n";
        print $fh "\n\nThank you\nErik\n";

        print $fh "\nVersion: $version\n" if $debug;
        print "Sending abuse email to $to\n" if $debug;
        print WRITELOG "$time ABUSE:Sent email to $to about $ip\n";
        $fh->close;

      }

    }

  }

}

close WRITECACHE;
close LOG;

use Data::Dumper;
print Dumper %track if $debug;


On 7/1/05, John Cholewa <freebsd-questions@jc-news.com> wrote:
> Jun 30 10:36:05 phantom sshd[70478]: Failed password for news from 212.88=
.182.121 port 51218 ssh2
> Jun 30 10:36:16 phantom sshd[70500]: Failed password for sshd from 212.88=
.182.121 port 51608 ssh2
> Jun 30 10:36:39 phantom sshd[70569]: Failed password for root from 212.88=
.182.121 port 52297 ssh2
>=20
> I get the above a lot in my logs (except more of it).  Each day, a couple=
 hundred failed attempts to log in from one or sometimes two IP addresses s=
hows up.  I don't have anything like ipf running, and since this machine is=
 about fifteen hundred miles away from me, I don't want to experiment with =
software firewalling right now.
>=20
> That known, is there any way to tell sshd (or some more powerful daemon) =
to stop accepting login attempts from a given IP if it tries and fails to l=
og in too many times in a limited duration (like in the same minute)?
>=20
> I suppose, now that I'm thinking about it, that it'd be best to actually =
just read the man pages and figure out how to get sshd to ignore any attemp=
t to attach from ports other than 22.  I mean, why are other machines tryin=
g to ssh in at ports over fifty thousand anyway?
>=20
> --
>   -JC
>   http://www.livejournal.com/users/jcholewa/
>=20
> PS:  Oh, yeah ... "FreeBSD 4.8-RELEASE #0: Thu Apr  3 10:53:38 GMT 2003" =
; openssh-3.6.1_5 ; openssl-0.9.7d_1
>=20
>=20
>=20
> _______________________________________________
> freebsd-questions@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-questions
> To unsubscribe, send any mail to "freebsd-questions-unsubscribe@freebsd.o=
rg"
>

------=_Part_1981_9202288.1120227011684
Content-Type: application/octet-stream; name="sshprotect.pl"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="sshprotect.pl"

IyEvdXNyL2Jpbi9wZXJsCiMgY3JlYXRlZCBieSBob3JuZXRtYWRuZXNzQGdtYWlsLmNvbSAwMy8w
NQoKbXkgJHRpbWU9bG9jYWx0aW1lKCk7Cgp1c2Ugc3RyaWN0Owp1c2UgVGltZTo6bG9jYWx0aW1l
Owp1c2UgTWFpbDo6U2VuZDsKCm15ICRob3N0bmFtZT0iZG9tYWluLm9ySVAuY29tIjsKCiNUaGUg
d2hpdGUgbGlzdCB0aGF0IGNvbnRhaW5zIGVpdGhlciB0aGUgYWNjb3VudCBvciBob3N0LgpteSAk
d2hpbGVsaXN0PSIvaG9tZS91c2VyL3NjcmlwdHMvc3Nod2hpdGVsaXN0IjsKCiNMT0cgdG8gc2Vh
cmNoIG9uCm15ICRsb2dmaWxlPSIvdmFyL2xvZy9hdXRoLmxvZyI7CgojV2hlcmUgdG8gcmVhZCB0
aGUgY3VycmVudCBsaXN0IG9mIGJsYWNraG9sZSBhZGRyZXNzLgpteSAkYmxhY2tsaXN0PSIvZXRj
L3BmLmJsYWNraG9sZXMiOwoKI05hbWUgb2YgdGhlIHRhYmxlIGluIHlvdXIgcGYuY29uZgpteSAk
dGFibGVuYW1lPSJibGFja2hvbGUiOwoKI1doZXJlIHRvIHN0b3JlIHRoZSBjYWNoZSBmaWxlLiBU
aGlzIGlzIHJlbW92ZWQgYW5kIHVwZGF0ZWQgZGFpbHkKbXkgJGNhY2hlPSIvcm9vdC8uc3NocHJv
dGVjdC5jYWNoZSI7CgojV2hlcmUgdG8gbG9nIGFjdGlvbnMgdGFrZW4uCm15ICRsb2c9Ii9yb290
L3NzaHByb3RlY3QubG9nIjsKCiNDb21tYW5kIHlvdSB3YW50IHRvIHJ1biBpbiByZXNwb25zZSBv
ZiBhIHBvdGVudGlhbCBhdHRhY2suCm15ICRjb21tYW5kPSJ3aG9pcyI7Cm15ICR1c2VpcD0xOyAg
I3VzZWZ1bCBpbiBjb25qdW5jdGlvbiB3aXRoICRjb21tYW5kIHdoaWNoIHdpbGwgZG8gc29tZXRo
aW5nIHdpdGggdGhlIElQLgogICAgICAgICAgICAjY29tbWVudCBvdXQgaWYgbm90IG5lZWRlZC4K
CiNNYXggYXR0ZW1wdHMgYSBob3N0IGNhbiBoYXZlIHVudGlsIGJsb2NrZWQuCm15ICRhdHRlbXB0
cz01OwoKIyBTZXQgdGhpcyB0byAicnVuIiB0aGUgJGNvbW1hbmQgb3IgInByaW50IiBhIHJlcG9y
dCBvciAiZW1haWwiIHRoZSByZXBvcnQsIAojIGFsc28gInVwZGF0ZSIgd2lsbCB1cGRhdGUgdGhl
ICRibGFja2xpc3QgYW5kIHJlbG9hZCB0aGUgYmxhY2tob2xlcyB0YWJsZS4KIyAiYWJ1c2UiIHdp
bGwgdHJ5IHRvIGZpbmQgYW5kIGVtYWlsIHRoZSBvZmZlbmRpbmcgbmV0d29yayBhYm91dCB0aGUg
YXR0YWNrCiMgVGhlc2UgY2FuIGJlIGNvbWJpbmQgdG8gcnVuIGFsbCBhY3Rpb25zOgojbXkgJGFj
dGlvbj0icnVuIHByaW50IjsKI215ICRhY3Rpb249InByaW50IjsKbXkgJGFjdGlvbj0iZW1haWwg
cnVuIHVwZGF0ZSBhYnVzZSI7CiNteSAkYWN0aW9uPSJwcmludCBlbWFpbCB1cGRhdGUiOwojbXkg
JGFjdGlvbj0icHJpbnQgZW1haWwiOwoKI0VtYWlsIHNldHVwOwpteSAkdG89InRvXEBlbWFpbC5j
b20iOwpteSAkZnJvbT0iZnJvbVxAZW1haWwuY29tIjsKbXkgJGNjPSIiOwpteSAkc3ViamVjdD0i
RXhjZXNzc2l2ZSBsb2dpbiBhdHRlbXB0cyI7CgoKbXkgJGRlYnVnPTA7CgpteSAkaG9zdDsKbXkg
QGxvZ3M7Cm15IEB3aHRsc3Q7Cm15ICV0cmFjazsKbXkgQGJsYWNrbGlzdDsKbXkgJGJsb2NrPTE7
Cm15IEBhYnVzZTsKbXkgQGNhY2hlOwpteSAkY3VycmVudGNhY2hlOwpteSBAcnVub3V0cHV0OwoK
bXkgJHZlcnNpb249IjEuMi4xYmV0YSI7CnByaW50ICJWZXJzaW9uOiAkdmVyc2lvblxuIiBpZiAk
ZGVidWc7CgojZmluZCB0b2RheXMgZGF0ZW1hc2sKdXNlIHZhcnMgcXcoJHlyICRtb24gJGRheSAk
dG9kYXkgJG1kYXkpOwokeXI9bG9jYWx0aW1lLT55ZWFyKCkgKyAxOTAwOwokbW9uPWxvY2FsdGlt
ZS0+bW9uKCkgKyAxOwokbWRheT1sb2NhbHRpbWUtPm1kYXkoKTsKaWYgKCRtb24gIT0gL1xkXGQv
KSB7JG1vbj0iMCRtb24iO30KaWYgKCRtZGF5IDwgMTApIHskbWRheT0iMCRtZGF5Ijt9CiR0b2Rh
eT0iJHlyJG1vbiRtZGF5IjsKcHJpbnQgIiR0b2RheVxuIiBpZiAkZGVidWc7CiNubyBUaW1lOjps
b2NhbHRpbWU7CgpvcGVuIChXUklURUxPRywgIj4+ICRsb2ciKSB8fCBkaWUgIiRsb2cgJCFcbiI7
CgpvcGVuIChCTEFDSywkYmxhY2tsaXN0KSB8fCBkaWUgIiRibGFja2xpc3QgJCFcbiI7CndoaWxl
ICg8QkxBQ0s+KSB7CiAgY2hvbXA7CiAgcHVzaCAoQGJsYWNrbGlzdCwgJF8pOwp9CmNsb3NlIEJM
QUNLOwoKb3BlbiAoV0hJVEUsICR3aGlsZWxpc3QpIHx8IGRpZSAiJHdoaWxlbGlzdCAkIVxuIjsK
d2hpbGUgKDxXSElURT4pIHsKICBjaG9tcDsKICBwdXNoIChAd2h0bHN0LCRfKTsKfQpjbG9zZSBX
SElURTsKCm9wZW4gKFJFQURDQUNIRSwgJGNhY2hlKSB8fCBwcmludCAiJGNhY2hlICQhXG4iOwp3
aGlsZSAoPFJFQURDQUNIRT4pIHsKICBjaG9tcDsKICBwdXNoIChAY2FjaGUsICRfKTsKfQpjbG9z
ZSBSRUFEQ0FDSEU7CgpvcGVuIChXUklURUNBQ0hFLCAiPj4gJGNhY2hlIikgfHwgcHJpbnQgIiRj
YWNoZSAkIVxuIjsKCmlmIChAY2FjaGVbMF0gPCAkdG9kYXkpIHsgCiAgY2xvc2UgV1JJVEVDQUNI
RTsKICBzeXN0ZW0gKCJybSAtZiAkY2FjaGUiKTsgCiAgb3BlbiAoV1JJVEVDQUNIRSwgIj4+ICRj
YWNoZSIpIHx8IHByaW50ICIkY2FjaGUgJCFcbiI7CiAgcHJpbnQgIkNhY2hlIGZpbGUgaXMgb3V0
IG9mIGRhdGUgQGNhY2hlWzBdIDwgJHRvZGF5XG4iIGlmICRkZWJ1ZzsKICBAY2FjaGU9KCk7CiAg
cHJpbnQgV1JJVEVDQUNIRSAiJHRvZGF5XG4iCn0KCm9wZW4gKExPRywgJGxvZ2ZpbGUpIHx8IGRp
ZSAibG9nZmlsZSAkISI7CndoaWxlICg8TE9HPikgewogIGNob21wOwoKICBpZiAoCiAgICAvRmFp
bGVkIHBhc3N3b3JkIGZvciBpbGxlZ2FsIHVzZXIgKC4qKSBmcm9tICguKikgcG9ydC8KICAgIHx8
IC9GYWlsZWQgcGFzc3dvcmQgZm9yICguKikgZnJvbSAoLiopIHBvcnQvCiAgICB8fCAvSWxsZWdh
bCB1c2VyICguKikgZnJvbSAoLiopLwogICAgfHwgL0RpZCBub3QgKHJlY2VpdmUpIGlkZW50aWZp
Y2F0aW9uIHN0cmluZyBmcm9tICguKikvCiAgICAgKSB7CiAgICAgCiAgICBteSAkYWNjb3VudD0k
MTsKICAgIG15ICRob3N0PSQyOwogICAgCiAgICBja3dodGxzdCgkYWNjb3VudCwgJGhvc3QpOwog
ICAgaWYgKCRibG9jayA9PSAwICkgeyBuZXh0OyB9CiAgICBja2NhY2hlKCRob3N0KTsKICAgIGlm
ICgkYmxvY2sgPT0gMCApIHsgbmV4dDsgfQogICAgY2tibGtsc3QoJGhvc3QpOwogICAgaWYgKCRi
bG9jayA9PSAwICkgeyBuZXh0OyB9CiAgICAkYmxvY2s9MTsgICAKICAgIGlmICgkdHJhY2t7JGhv
c3R9KSB7IAogICAgICAkdHJhY2t7JGhvc3R9PSR0cmFja3skaG9zdH0rMTsgCiAgICAgIHByaW50
ICIkaG9zdCBpcyBub3cgJHRyYWNreyRob3N0fSB1c2VyPSRhY2NvdW50XG4iIGlmICRkZWJ1ZzsK
ICAgIH0gZWxzZSB7ICR0cmFja3skaG9zdH09MTsgfQogIH0KfQpjbG9zZSBMT0c7Cgpmb3IgbXkg
JGhvc3QgKCV0cmFjaykgewogIGlmICghJGhvc3QpIHtwcmludCAiTm90aGluZyBGb3VuZFxuIjsg
ZXhpdDt9CiAgaWYgKCR0cmFja3skaG9zdH0gPj0gJGF0dGVtcHRzKSB7CiAgICBwdXNoIChAYWJ1
c2UsJGhvc3QpOwogICAgY2tjYWNoZSgkaG9zdCk7CiAgICBwcmludCBXUklURUNBQ0hFICIkaG9z
dFxuIiBpZiAhJGJsb2NrID09IDA7CiAgICBpZiAoJGFjdGlvbiA9fiAvcHJpbnQvKSB7IHByaW50
ICJIb3N0ICRob3N0LCBwYXN0ICRhdHRlbXB0cyBhdHRlbXB0ZWQgbG9naW5zXG4iOyB9CiAgICBp
ZiAoJGFjdGlvbiA9fiAvcnVuLyAmJiAkdXNlaXApIHsgKEBydW5vdXRwdXQ9YCRjb21tYW5kICRo
b3N0YCk7IH0KICAgIGlmICgkYWN0aW9uID1+IC9ydW4vICYmICEkdXNlaXApIHsgKEBydW5vdXRw
dXQ9YCRjb21tYW5kYCk7IH0KICAgIGlmICgkYWN0aW9uID1+IC91cGRhdGUvKSB7IHVwZGF0ZSgk
aG9zdCk7IH0KICB9IAp9CgoKI1NlbmRzIGVtYWlscwppZiAoJGFjdGlvbiAhfi9lbWFpbC8pIHsg
CiAgZXhpdDsgCn0gZWxzaWYgKEBhYnVzZSkgewogIHNlbmRfZW1haWwoQGFidXNlKTsKfQoKaWYg
KCRhY3Rpb24gIX4vYWJ1c2UvKSB7CiAgZXhpdDsKfSBlbHNpZiAoQGFidXNlKSB7CiAgYWJ1c2Vf
ZW1haWwoQGFidXNlKTsKfQoKc3ViIGNrd2h0bHN0IHsKICAobXkgJGFjY291bnQsIG15ICRob3N0
KT1AXzsKICBmb3JlYWNoIChAd2h0bHN0KSB7CiAgICBpZiAoIS8kYWNjb3VudHwkaG9zdC8pIHsg
CiAgICAgICRibG9jaz0xOwogICAgICByZXR1cm47CiAgICB9IGVsc2UgeyAKICAgICAgcHJpbnQg
IiRob3N0IG9yICRhY2NvdW50IGlzIG9uIHRoZSB3aGlsZSBsaXN0LlxuIiBpZiAkZGVidWc7CiAg
ICAgICRibG9jaz0wOwogICAgICByZXR1cm47CiAgICB9CiAgfQp9CiAgCnN1YiBja2Jsa2xzdCB7
CiAgbXkgJGhvc3Q9QF9bMF07CiAgZm9yZWFjaCAoQGJsYWNrbGlzdCkgewogICAgaWYgKC8kaG9z
dC8pIHsgCiAgICAgcHJpbnQgIiRob3N0ICRfIGlzIGFscmVhZHkgYmxhY2tsaXN0ZWRcbiIgaWYg
JGRlYnVnOwogICAgICAkYmxvY2s9MDsKICAgICAgcmV0dXJuOwogICAgfSBlbHNlIHsgJGJsb2Nr
PTE7IH0gI3ByaW50ICIkaG9zdCBpcyBOT1QgYmxhY2tsaXN0ZWRcbiIgaWYgJGRlYnVnOyB9CiAg
fQp9CgpzdWIgY2tjYWNoZSB7CiAgbXkgJGhvc3Q9QF9bMF07CiAgaWYgKCFAY2FjaGUpIHsgJGJs
b2NrPTE7IHJldHVybjt9CiAgZm9yZWFjaCAoQGNhY2hlKSB7CiAgICBpZiAoLyRob3N0Lykgewog
ICAgICAkYmxvY2s9MDsKICAgICAgcHJpbnQgIiRob3N0IGlzIGFscmVhZHkgY2FjaGVkXG4iIGlm
ICRkZWJ1ZzsKICAgICAgcmV0dXJuOwogICAgfSBlbHNlIHsgJGJsb2NrPTE7IH0gI3ByaW50ICIk
aG9zdCBpcyBub3QgZm91bmQgaW4gY2FjaGVcbiIgaWYgJGRlYnVnOyB9CiAgfQp9CgpzdWIgdXBk
YXRlIHsKICBvcGVuIChPVVQsICI+PiAkYmxhY2tsaXN0IikgfHwgZGllICIkYmxhY2tsaXN0ICQh
XG4iOwogIHByaW50IE9VVCAiQF9bMF1cbiI7CiAgc3lzdGVtICgicGZjdGwgLXQgJHRhYmxlbmFt
ZSAtZiAvZXRjL3BmLmNvbmYiKTsKICBjbG9zZSBPVVQ7Cn0KCnN1YiBzZW5kX2VtYWlsIHsKICBt
eSAkc3ViamVjdD0iJHN1YmplY3QgJHRvZGF5IjsKICBteSAkbXNnID0gbmV3IE1haWw6OlNlbmQ7
CiAgbXkgJGhvc3Q7CiAgJG1zZy0+c3ViamVjdCgkc3ViamVjdCk7CiAgJG1zZy0+dG8oJHRvKTsK
ICAkbXNnLT5jYygkY2MpIGlmICRjYzsKICAkbXNnLT5hZGQoIkZyb20iLCAiJGZyb20iKTsKICAk
bXNnLT5hZGQoIlJldHVybi1QYXRoIiwgIiRmcm9tIik7CiAgJG1zZy0+YWRkKCJSZXBseS1UbyIs
ICIkZnJvbSIpOwogIAogIG15ICRmaD0kbXNnLT5vcGVuOwogIAogIGZvcmVhY2ggKEBfKSB7CiAg
ICAkaG9zdD0kXzsKICAgIGlmICghJHRyYWNreyRffSkge3JldHVybjt9CiAgICBwcmludCAkZmgg
IlxuVGhlIGhvc3QgJF8gaGFzICR0cmFja3skX30gYXR0ZW1wdGVkIGxvZ2lucy5cbiI7CiAgfSAg
CiAgcHJpbnQgJGZoICJcblRoZSB0aHJlc2hvbGQgaXMgc2V0IHRvICRhdHRlbXB0cyBhdHRlbXB0
c1xuIjsKICBwcmludCAkZmggIlxuQWN0aW9ucyB0YWtlbjogJGFjdGlvblxuXG4iOwogIGlmICgo
JGFjdGlvbiA9fi9ydW4vICYmICRjb21tYW5kKSAmJiAhJHVzZWlwKSB7IHByaW50ICRmaCAiUmFu
OiAkY29tbWFuZFxuXG4gT3V0cHV0OlxuQHJ1bm91dHB1dCI7IH0KICBpZiAoKCRhY3Rpb24gPX4v
cnVuLyAmJiAkY29tbWFuZCkgJiYgJHVzZWlwKSB7IHByaW50ICRmaCAiUmFuOiAkY29tbWFuZCAk
aG9zdCxcblxuIE91dHB1dDpcbkBydW5vdXRwdXQiOyB9CgogIHByaW50ICRmaCAiXG5WZXJzaW9u
OiAkdmVyc2lvblxuIjsKICBwcmludCAiU2VuZGluZyBlbWFpbFxuIiBpZiAkZGVidWc7CiAgcHJp
bnQgV1JJVEVMT0cgIiR0aW1lIFNlbnQgZW1haWwgdG8gJHRvIGFib3V0ICRfIFwiJHN1YmplY3Rc
IlxuIjsKICAkZmgtPmNsb3NlOwp9CgpzdWIgYWJ1c2VfZW1haWwgewogICRzdWJqZWN0PSJbQUJV
U0VdICRzdWJqZWN0ICR0b2RheSI7CiAgbXkgJG1zZzsKICBteSAkZmg7CiAgbXkgJGFjY3Q7CiAg
bXkgJGRvbWFpbjsKICAKICBmb3JlYWNoIG15ICRpcCAoQF8pIHsKICAgIG15ICRzeW50YXg9IiRp
cCBTT0EiOwogICAgaWYgKCEkdHJhY2t7JGlwfSkge3JldHVybjt9CiAgICBpZiAofi9cZHsxLDNc
LlxkezEsM31cLlxkezEsM31cLlxkezEsM30vKSB7ICRzeW50YXg9Ii14ICRpcCBTT0EiOyB9CiAg
ICAKICAgIHByaW50ICJSdW5uaW5nIGRpZyAkc3ludGF4XG4iIGlmICRkZWJ1ZzsKICAgIG15IEBk
aWc9YC91c3IvYmluL2RpZyAkc3ludGF4YDsKICAgIAogICAgZm9yZWFjaCBteSAkZGlnIChAZGln
KSB7CiAgICAgIGlmICgkZGlnID1+IC9pbi1hZGRyXC5hcnBhXC4uKlNPQVx0LipcLiAoLiopXC4v
KSB7CiAgICAgICAgbXkgJGFkZHk9JDE7CiAgICAgICAgaWYgKCEkYWRkeSkgeyBuZXh0OyB9CiAg
ICAgICAgaWYgKCRhZGR5ID1+IC8oXHcrKVwuKC4rKS8pIHsKICAgICAgICAgICRhY2N0PSQxOwog
ICAgICAgICAgJGRvbWFpbj0kMjsKICAgICAgICB9CiAgICAgICAgJHRvPSIkYWNjdFxAJGRvbWFp
biI7CgogICAgICAgIHByaW50ICJGb3VuZCAkdG8gZnJvbSBEaWdcbiIgaWYgJGRlYnVnOwogICAg
ICAgIAogICAgICAgICRtc2cgPSBuZXcgTWFpbDo6U2VuZDsKICAgICAgICAkbXNnLT5zdWJqZWN0
KCRzdWJqZWN0KTsKICAgICAgICAkbXNnLT50bygkdG8pOwogICAgICAgICRtc2ctPmNjKCRjYykg
aWYgJGNjOwogICAgICAgICRtc2ctPmFkZCgiRnJvbSIsICIkZnJvbSIpOwogICAgICAgICRtc2ct
PmFkZCgiUmV0dXJuLVBhdGgiLCAiJGZyb20iKTsKICAgICAgICAkbXNnLT5hZGQoIlJlcGx5LVRv
IiwgIiRmcm9tIik7CiAgICAgICAgJGZoPSRtc2ctPm9wZW47CiAgICAgICAgcHJpbnQgJGZoICJc
blRoaXMgaG9zdCAkaXAgaGFzIGF0dGVtcHRlZCAkdHJhY2t7JGlwfSBlcnJvbmVvdXMgc3NoIGxv
Z2lucyB0byBteSBzZXJ2ZXIgJGhvc3RuYW1lIG9uICR0b2RheS5cbiI7CiAgICAgICAgcHJpbnQg
JGZoICJQbGVhc2UgcmVwb3J0IHRoaXMgdG8geW91ciBjdXN0b21lciBhbmQgYWR2aXNlIHRoZW0g
b24gYW55IEFVUCB2aW9sYXRpb25zIHlvdSBlbmZvcmNlLlxuIjsKICAgICAgICBwcmludCAkZmgg
IlxuXG5UaGFuayB5b3VcbkVyaWtcbiI7CgogICAgICAgIHByaW50ICRmaCAiXG5WZXJzaW9uOiAk
dmVyc2lvblxuIiBpZiAkZGVidWc7CiAgICAgICAgcHJpbnQgIlNlbmRpbmcgYWJ1c2UgZW1haWwg
dG8gJHRvXG4iIGlmICRkZWJ1ZzsKICAgICAgICBwcmludCBXUklURUxPRyAiJHRpbWUgQUJVU0U6
U2VudCBlbWFpbCB0byAkdG8gYWJvdXQgJGlwXG4iOwogICAgICAgICRmaC0+Y2xvc2U7ICAgIAoK
ICAgICAgfQoKICAgIH0KCiAgfQoKfQoKY2xvc2UgV1JJVEVDQUNIRTsKY2xvc2UgTE9HOwoKdXNl
IERhdGE6OkR1bXBlcjsKcHJpbnQgRHVtcGVyICV0cmFjayBpZiAkZGVidWc7Cg==
------=_Part_1981_9202288.1120227011684--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?f42935a6050701071012cbba8a>