From owner-freebsd-questions@FreeBSD.ORG Fri Jul 1 14:10:13 2005 Return-Path: X-Original-To: freebsd-questions@freebsd.org Delivered-To: freebsd-questions@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 298B016A421 for ; Fri, 1 Jul 2005 14:10:13 +0000 (GMT) (envelope-from hornetmadness@gmail.com) Received: from rproxy.gmail.com (rproxy.gmail.com [64.233.170.207]) by mx1.FreeBSD.org (Postfix) with ESMTP id 67B3843D48 for ; Fri, 1 Jul 2005 14:10:12 +0000 (GMT) (envelope-from hornetmadness@gmail.com) Received: by rproxy.gmail.com with SMTP id 34so60278rns for ; Fri, 01 Jul 2005 07:10:11 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:reply-to:to:subject:cc:in-reply-to:mime-version:content-type:references; b=ZwbFeC6ZBqjYK5KH/oKyoocNB6MEGkWjfzBji+OpITNs89x61NxdF57nBSmC+9E4fF3zt4x/EOjmv+FU9pVcHkhSSpixENgHdtazdnmgQwYufSXXZsFHHzIRQeYCE1AB5hQEkg+wvkF+rfS8gPi0jlf4MDTFC8adYFB0z9hpht8= Received: by 10.38.198.5 with SMTP id v5mr266082rnf; Fri, 01 Jul 2005 07:10:11 -0700 (PDT) Received: by 10.38.8.44 with HTTP; Fri, 1 Jul 2005 07:10:11 -0700 (PDT) Message-ID: Date: Fri, 1 Jul 2005 10:10:11 -0400 From: Hornet To: John Cholewa In-Reply-To: <42C54872.50106@jc-news.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_1981_9202288.1120227011684" References: <42C54872.50106@jc-news.com> Cc: freebsd-questions@freebsd.org Subject: Re: autoblocking many ssh failed logins from the same IP.... X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Hornet List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 01 Jul 2005 14:10:13 -0000 ------=_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 () { chomp; push (@blacklist, $_); } close BLACK; open (WHITE, $whilelist) || die "$whilelist $!\n"; while () { chomp; push (@whtlst,$_); } close WHITE; open (READCACHE, $cache) || print "$cache $!\n"; while () { 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 () { 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 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--