Commit Diff


commit - /dev/null
commit + c49bbc503cd565c766fdd91ffd094f2fbe2d6170
blob - /dev/null
blob + 9393d5ae91ee554eec3abaca6f7a3c1c6ffd1c49 (mode 644)
--- /dev/null
+++ .gitignore
@@ -0,0 +1,6 @@
+change.pl
+#records/*
+#records-archive/*
+#tokens/*
+#zonefiles/*
+#zonefiles-archive/*
blob - /dev/null
blob + 6fab844a5ec5c07720a1820401279df0a354eb49 (mode 755)
--- /dev/null
+++ clean.pl
@@ -0,0 +1,38 @@
+#!/usr/bin/env perl
+#
+use 5.024;
+use strict;
+use warnings;
+use autodie;
+use Fcntl qw(:flock);
+use File::Basename;
+use File::stat;
+use POSIX qw(strftime);
+
+my $ttl = "300";
+my $workdir = dirname($0);
+
+opendir my $dh, "${workdir}/tokens";
+while (my $file = readdir $dh) {
+	chomp $file;
+	next if $file =~ /^\./;
+
+	open my $fh, '<', "${workdir}/tokens/$file";
+	my $client_ip = <$fh>;
+	chomp $client_ip;
+	close $fh;
+
+	my $mtime = stat("${workdir}/tokens/${file}")->mtime();
+	if ((time() - $mtime) > $ttl) {
+		_log("$client_ip $file removed");
+		unlink("${workdir}/tokens/${file}");
+	}
+}
+
+sub _log {
+	my ($msg) = @_;
+	open my $fh, '>>', '/var/log/ptrd.log';
+	flock $fh, LOCK_EX;
+	print $fh sprintf("%s %s: %s \n", strftime("%b %d %H:%M:%S", localtime), basename($0), $msg);
+	close $fh;
+}
blob - /dev/null
blob + 86322d3e15fef2f90acff0b463fc587d3452a1da (mode 755)
--- /dev/null
+++ fetch-tlds.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+ftp -MV https://data.iana.org/TLD/tlds-alpha-by-domain.txt
blob - /dev/null
blob + 36b4792b59988aaab13e92f55402adcaac1d3965 (mode 755)
--- /dev/null
+++ parse.pl
@@ -0,0 +1,105 @@
+#!/usr/bin/env perl
+#
+use 5.024;
+use strict;
+use warnings;
+use autodie;
+use Fcntl qw(:flock);
+use File::Basename;
+use File::Copy;
+use POSIX qw(strftime);
+use Net::IP;
+
+my $ipv4_range = new Net::IP("46.23.80.0/20");
+my $ipv6_range = new Net::IP("2a03:6000::/29");
+my $nsd = "/var/nsd/zones/reverse";
+my $v6_zone = "2a03.6000";
+my $workdir = dirname($0);
+my $serial;
+my $serial_prev;
+my $zonefile;
+
+opendir my $dh, "${workdir}/records";
+while (my $file = readdir $dh) {
+	chomp $file;
+	next if $file =~ /^\./;
+
+	open my $fh_ptr, '<', "${workdir}/records/$file";
+	my $replace = <$fh_ptr>;
+	chomp $replace;
+	my ($match, $rest) = split(' ', $replace, 2);
+	close $fh_ptr;
+
+	my $ip = new Net::IP($file);
+	if ($ip->overlaps($ipv4_range)) {
+		($zonefile = $file) =~ s/^((\d{1,3}\.){3})\d+$/${1}0/;
+	} elsif ($ip->overlaps($ipv6_range)) {
+		$zonefile = $v6_zone;
+	}
+
+	if (qx(rlog ${nsd}/${zonefile} | grep 'locked by') =~ m/locked by/) {
+		_log("$file zone file locked, trying again later...");
+		next;
+	} else {
+		open my $fh_in, '<', "${nsd}/$zonefile";
+		open my $fh_out, '>', "${workdir}/zonefiles/$zonefile";
+		while (my $row = <$fh_in>) {
+			chomp $row; 
+			if ($row =~ m/^\s*(\d+)\s*; serial$/) {
+				$serial = $serial_prev = $1;
+				my $timestamp = strftime ("%Y%m%d", localtime()) . "01";
+				if ($serial < $timestamp) {
+					$serial = $timestamp;
+				} else {
+					$serial++;
+				}
+				$row =~ s/${serial_prev}/${serial}/;
+			}
+
+			if ($row =~ m/^${match}\s+IN\s+PTR\s+\S+( ;.*)?$/) {
+				if ($1) {
+					my $comment = $1;
+					$row =~ s/^${match}\s+.*$/${replace}${comment}/;
+				} else {
+					$row =~ s/^${match}\s+.*$/${replace}/;
+				}
+			}
+			print $fh_out "$row\n";
+		}
+		close $fh_in;
+		close $fh_out;
+
+		(my $diff = qx(diff ${nsd}/${zonefile} ${workdir}/zonefiles/${zonefile} | wc -l)) =~ s/^\s*(.*?)\s*$/$1/;
+		if ($diff == 8) {
+			_log("$file diff within limits ($diff), $serial_prev -> $serial");
+			copy("${nsd}/${zonefile}", "${workdir}/zonefiles-archive/${zonefile}-${serial}");
+			qx(co -q -l ${nsd}/${zonefile});
+			copy("${workdir}/zonefiles/${zonefile}", "${nsd}/${zonefile}");
+			qx(ci -q -u -m"updated for ${file}" ${nsd}/${zonefile});
+			move("${workdir}/records/${file}", "${workdir}/records-archive/${file}-${serial}");
+
+			qx(rcctl reload nsd);
+			qx(rdist -f /etc/Distfile) if (-r '/etc/Distfile');
+
+			open my $fh_email, '|-', '/usr/sbin/sendmail -t';
+			print $fh_email "To: ptrd\@openbsd.amsterdam\n";
+			print $fh_email "From: ptrd\@openbsd.amsterdam\n";
+			print $fh_email "Subject: OpenBSD Amsterdam PTR $zonefile\n";
+			print $fh_email "Content-Type: text/plain; charset=utf-8\n\n";
+			print $fh_email "$serial_prev -> $serial\n$file\n$replace\n";
+			close $fh_email;
+		} else {
+			_log("$file diff is outside limits ($diff), cleaning up");
+			unlink("${workdir}/records/${file}", "${workdir}/zonefiles/${zonefile}");
+		}
+	}
+}
+
+sub _log {
+	my ($msg) = @_;
+	open my $fh, '>>', '/var/log/ptrd.log';
+	flock $fh, LOCK_EX;
+	print $fh sprintf("%s %s: %s \n", strftime("%b %d %H:%M:%S", localtime), basename($0), $msg);
+	close $fh;
+}
+
blob - /dev/null
blob + b6e64ac0d60e6a413aac75609759c47d49f28874 (mode 755)
--- /dev/null
+++ ptrd.pl
@@ -0,0 +1,223 @@
+#!/usr/bin/perl
+#
+use 5.024;
+use strict;
+use warnings;
+use autodie;
+use Digest::SHA qw(sha1_hex);
+use Fcntl qw(:flock);
+use File::Basename;
+use Getopt::Long;
+use POSIX qw(strftime WNOHANG);
+use Pod::Usage;
+use HTTP::Daemon;
+use HTTP::Response;
+use HTTP::Status;
+use Net::IP;
+
+GetOptions(
+	"listen=s" => \(my $LISTEN = "ptr4.openbsd.amsterdam"),
+	"port=i" => \(my $PORT = "80"),
+	"help" => \(my $HELP),
+	"man" => \(my $MAN),
+) or pod2usage(2);
+pod2usage(1) if $HELP; 
+pod2usage(-verbose => 2) if $MAN; 
+
+=head1 NAME
+
+=head1 SYNOPSIS
+
+ptrd.pl [options]
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-l> | --listen
+
+Address or hostname to listen on, default ptr4.openbsd.amsterdam.
+
+=item B<-p> | --port
+
+Port to listen on, default 80
+
+=back
+
+=head1 DESCRIPTION
+
+B<This program> is a Perl HTTP Daemon designed to listen for incoming PTR records of OpenBSD Amsterdam VMs.
+
+A token needs to be requested before the PTR record can be set.
+
+=cut
+
+my %O = (
+	'listen-host' => $LISTEN,
+	'listen-port' => $PORT,
+	'listen-clients' => 10,
+	'listen-max-req-per-child' => 10000,
+);
+
+my $d = HTTP::Daemon->new(
+	LocalAddr => $O{'listen-host'},
+	LocalPort => $O{'listen-port'},
+	Reuse => 1,
+) or die "Can't start http listener at $O{'listen-host'}:$O{'listen-port'}";
+_log("Started HTTP listener at $LISTEN from " . dirname($0));
+
+my %chld;
+my $workdir = dirname($0);
+my $error = 0;
+
+$SIG{INT}  = \&signal_handler;
+$SIG{TERM} = \&signal_handler;
+
+open my $fh_tlds, '<', "${workdir}/tlds-alpha-by-domain.txt";
+chomp(my @tlds = <$fh_tlds>);
+close $fh_tlds;
+
+if ($O{'listen-clients'}) {
+	$SIG{CHLD} = sub {
+		# checkout finished children
+		while ((my $kid = waitpid(-1, WNOHANG)) > 0) {
+			delete $chld{$kid};
+		}
+	};
+}
+
+while (1) {
+	if ($O{'listen-clients'}) {
+		# prefork all at once
+		for (scalar(keys %chld) .. $O{'listen-clients'} - 1 ) {
+			my $pid = fork;
+
+			if (!defined $pid) { # error
+				die "Can't fork for http child $_: $!";
+			}
+			if ($pid) { # parent
+				$chld{$pid} = 1;
+			} else { # child
+				$_ = 'DEFAULT' for @SIG{qw/ INT TERM CHLD /};
+				http_child($d);
+				exit;
+			}
+		}
+		sleep 1;
+	} else {
+		http_child($d);
+	}
+}
+
+sub http_child {
+	my $d = shift;
+	my $i;
+
+	while (++$i < $O{'listen-max-req-per-child'}) {
+		my $c = $d->accept or last;
+		my $r = $c->get_request(1) or last;
+		$c->autoflush(1);
+	
+		my $ipv4_range = new Net::IP("46.23.80.0/20");
+		my $ipv6_range = new Net::IP("2a03:6000::/29");
+
+		my $client_ip = $c->peerhost;
+		my $ip = new Net::IP($client_ip);
+		my ($first, $token, $hostname) = split(/\//, $r->uri->as_string);
+		my $tld = (defined($hostname) ? substr($hostname, rindex($hostname, '.')+1) : '');
+		$hostname = (!defined($hostname) ? $token : lc($hostname));
+
+		if ($ip->overlaps($ipv4_range) or $ip->overlaps($ipv6_range)) {
+
+			if ($token eq 'token') {
+				my $token = sha1_hex(int(rand(32)));
+				open my $fh_token, '>', "${workdir}/tokens/${token}";
+				print $fh_token "$client_ip\n";
+				close $fh_token;
+
+				_log("$client_ip $token");
+				_http_response($c, {content_type => 'text/plain'}, "$token");
+
+			} elsif (-e  "${workdir}/tokens/$token" and grep(/^${tld}$/i, @tlds) and ($hostname =~ /(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63}$)/)) {
+
+				open my $fh, '>', "${workdir}/records/${client_ip}";
+				if ($ip->overlaps($ipv4_range)) {
+					my $ptr = substr($client_ip, rindex($client_ip, '.')+1);
+					print $fh sprintf("%s\t\tIN\tPTR\t%s.\n", $ptr, $hostname);
+
+				} elsif ($ip->overlaps($ipv6_range)) {
+					my $dig = qx(dig +short \@46.23.80.23 -x ${client_ip});
+					if (!$dig) {
+						$error = 1;
+					} else {
+						my $ptr = substr($ip->reverse_ip(), 0, 47);
+						print $fh sprintf("%s\tIN\tPTR\t%s.\n", $ptr, $hostname);
+					}
+				}
+				close $fh;
+
+				if ($error == 1) {
+					_log("$client_ip $token $hostname - PTR doesn't exist");
+					_http_response($c, {content_type => 'text/plain'}, "Error PTR [$client_ip] doesn't exist, please contact the administrator.");
+					$error = 0;
+				} else {
+					_log("$client_ip $token $hostname");
+					_http_response($c, {content_type => 'text/plain'}, "Received PTR [$client_ip -> $hostname] will be processed asap.");
+				}
+
+			} elsif (!-e "${workdir}/tokens/$token" and defined($token)and $token ne 'token') {
+				_log("$client_ip RC_REQUEST_TIMEOUT $hostname");
+				_http_error($c, RC_REQUEST_TIMEOUT);
+
+			} else {
+				_log("$client_ip RC_BAD_REQUEST $hostname");
+				_http_error($c, RC_BAD_REQUEST);
+			}
+
+		} else {
+			#print sprintf("%s %s: %s RC_FORBIDDEN\n", $date, $0, $client_ip);
+			_log("$client_ip RC_FORBIDDEN");
+			_http_error($c, RC_FORBIDDEN);
+		}
+
+		$c->close();
+		undef $c;
+	}
+}
+
+sub _http_error {
+	my ($c, $code, $msg) = @_;
+	$c->send_error($code, $msg);
+}
+
+sub _http_response {
+	my $c = shift;
+	my $header = shift;
+	my $content = shift;
+	$c->send_response(
+		HTTP::Response->new(
+			RC_OK,
+			undef,
+			[
+				'Content-Type' => $header->{content_type},
+				'Cache-Control' => 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0',
+				'Pragma' => 'no-cache',
+				'Expires' => 'Wed, 29 Feb 1984 13:37:00 GMT',
+			],
+			"$content\r\n",
+		)
+	);
+}
+
+sub _log {
+	my ($msg) = @_;
+	open my $fh, '>>', '/var/log/ptrd.log';
+	flock $fh, LOCK_EX;
+	print $fh sprintf("%s %s: %s \n", strftime("%b %d %H:%M:%S", localtime), basename($0), $msg);
+	close $fh;
+}
+
+sub signal_handler {
+	_log("Caught a signal $!");
+	die "Caught a signal $!";
+}
blob - /dev/null
blob + f5ee9f2a109226a4d1e01bb1335dad16494081a5 (mode 755)
--- /dev/null
+++ rc.d/ptrd4
@@ -0,0 +1,13 @@
+#!/bin/ksh
+
+daemon="/home/runbsd/api/ptrd.pl"
+
+. /etc/rc.d/rc.subr
+
+pexp="$(eval echo ${daemon}${daemon_flags:+ ${daemon_flags}})"
+rc_bg="YES" 
+rc_reload="NO"
+
+pexp="/usr/bin/perl ${daemon}${daemon_flags:+ ${daemon_flags}}"
+
+rc_cmd $1
blob - /dev/null
blob + 5c3a7a4f9d9d06fddc03bbd3b24e775a5f2edd47 (mode 755)
--- /dev/null
+++ rc.d/ptrd6
@@ -0,0 +1,13 @@
+#!/bin/ksh
+
+daemon="/home/runbsd/api2/ptrd.pl"
+
+. /etc/rc.d/rc.subr
+
+pexp="$(eval echo ${daemon}${daemon_flags:+ ${daemon_flags}})"
+rc_bg="YES" 
+rc_reload="NO"
+
+pexp="/usr/bin/perl ${daemon}${daemon_flags:+ ${daemon_flags}}"
+
+rc_cmd $1
blob - /dev/null
blob + 46b0d0d1ef29481309a0bb12f888b1eaaeee9286 (mode 644)
--- /dev/null
+++ tlds-alpha-by-domain.txt
@@ -0,0 +1,1480 @@
+# Version 2023042900, Last Updated Sat Apr 29 07:07:01 2023 UTC
+AAA
+AARP
+ABARTH
+ABB
+ABBOTT
+ABBVIE
+ABC
+ABLE
+ABOGADO
+ABUDHABI
+AC
+ACADEMY
+ACCENTURE
+ACCOUNTANT
+ACCOUNTANTS
+ACO
+ACTOR
+AD
+ADS
+ADULT
+AE
+AEG
+AERO
+AETNA
+AF
+AFL
+AFRICA
+AG
+AGAKHAN
+AGENCY
+AI
+AIG
+AIRBUS
+AIRFORCE
+AIRTEL
+AKDN
+AL
+ALFAROMEO
+ALIBABA
+ALIPAY
+ALLFINANZ
+ALLSTATE
+ALLY
+ALSACE
+ALSTOM
+AM
+AMAZON
+AMERICANEXPRESS
+AMERICANFAMILY
+AMEX
+AMFAM
+AMICA
+AMSTERDAM
+ANALYTICS
+ANDROID
+ANQUAN
+ANZ
+AO
+AOL
+APARTMENTS
+APP
+APPLE
+AQ
+AQUARELLE
+AR
+ARAB
+ARAMCO
+ARCHI
+ARMY
+ARPA
+ART
+ARTE
+AS
+ASDA
+ASIA
+ASSOCIATES
+AT
+ATHLETA
+ATTORNEY
+AU
+AUCTION
+AUDI
+AUDIBLE
+AUDIO
+AUSPOST
+AUTHOR
+AUTO
+AUTOS
+AVIANCA
+AW
+AWS
+AX
+AXA
+AZ
+AZURE
+BA
+BABY
+BAIDU
+BANAMEX
+BANANAREPUBLIC
+BAND
+BANK
+BAR
+BARCELONA
+BARCLAYCARD
+BARCLAYS
+BAREFOOT
+BARGAINS
+BASEBALL
+BASKETBALL
+BAUHAUS
+BAYERN
+BB
+BBC
+BBT
+BBVA
+BCG
+BCN
+BD
+BE
+BEATS
+BEAUTY
+BEER
+BENTLEY
+BERLIN
+BEST
+BESTBUY
+BET
+BF
+BG
+BH
+BHARTI
+BI
+BIBLE
+BID
+BIKE
+BING
+BINGO
+BIO
+BIZ
+BJ
+BLACK
+BLACKFRIDAY
+BLOCKBUSTER
+BLOG
+BLOOMBERG
+BLUE
+BM
+BMS
+BMW
+BN
+BNPPARIBAS
+BO
+BOATS
+BOEHRINGER
+BOFA
+BOM
+BOND
+BOO
+BOOK
+BOOKING
+BOSCH
+BOSTIK
+BOSTON
+BOT
+BOUTIQUE
+BOX
+BR
+BRADESCO
+BRIDGESTONE
+BROADWAY
+BROKER
+BROTHER
+BRUSSELS
+BS
+BT
+BUILD
+BUILDERS
+BUSINESS
+BUY
+BUZZ
+BV
+BW
+BY
+BZ
+BZH
+CA
+CAB
+CAFE
+CAL
+CALL
+CALVINKLEIN
+CAM
+CAMERA
+CAMP
+CANON
+CAPETOWN
+CAPITAL
+CAPITALONE
+CAR
+CARAVAN
+CARDS
+CARE
+CAREER
+CAREERS
+CARS
+CASA
+CASE
+CASH
+CASINO
+CAT
+CATERING
+CATHOLIC
+CBA
+CBN
+CBRE
+CBS
+CC
+CD
+CENTER
+CEO
+CERN
+CF
+CFA
+CFD
+CG
+CH
+CHANEL
+CHANNEL
+CHARITY
+CHASE
+CHAT
+CHEAP
+CHINTAI
+CHRISTMAS
+CHROME
+CHURCH
+CI
+CIPRIANI
+CIRCLE
+CISCO
+CITADEL
+CITI
+CITIC
+CITY
+CITYEATS
+CK
+CL
+CLAIMS
+CLEANING
+CLICK
+CLINIC
+CLINIQUE
+CLOTHING
+CLOUD
+CLUB
+CLUBMED
+CM
+CN
+CO
+COACH
+CODES
+COFFEE
+COLLEGE
+COLOGNE
+COM
+COMCAST
+COMMBANK
+COMMUNITY
+COMPANY
+COMPARE
+COMPUTER
+COMSEC
+CONDOS
+CONSTRUCTION
+CONSULTING
+CONTACT
+CONTRACTORS
+COOKING
+COOKINGCHANNEL
+COOL
+COOP
+CORSICA
+COUNTRY
+COUPON
+COUPONS
+COURSES
+CPA
+CR
+CREDIT
+CREDITCARD
+CREDITUNION
+CRICKET
+CROWN
+CRS
+CRUISE
+CRUISES
+CU
+CUISINELLA
+CV
+CW
+CX
+CY
+CYMRU
+CYOU
+CZ
+DABUR
+DAD
+DANCE
+DATA
+DATE
+DATING
+DATSUN
+DAY
+DCLK
+DDS
+DE
+DEAL
+DEALER
+DEALS
+DEGREE
+DELIVERY
+DELL
+DELOITTE
+DELTA
+DEMOCRAT
+DENTAL
+DENTIST
+DESI
+DESIGN
+DEV
+DHL
+DIAMONDS
+DIET
+DIGITAL
+DIRECT
+DIRECTORY
+DISCOUNT
+DISCOVER
+DISH
+DIY
+DJ
+DK
+DM
+DNP
+DO
+DOCS
+DOCTOR
+DOG
+DOMAINS
+DOT
+DOWNLOAD
+DRIVE
+DTV
+DUBAI
+DUNLOP
+DUPONT
+DURBAN
+DVAG
+DVR
+DZ
+EARTH
+EAT
+EC
+ECO
+EDEKA
+EDU
+EDUCATION
+EE
+EG
+EMAIL
+EMERCK
+ENERGY
+ENGINEER
+ENGINEERING
+ENTERPRISES
+EPSON
+EQUIPMENT
+ER
+ERICSSON
+ERNI
+ES
+ESQ
+ESTATE
+ET
+ETISALAT
+EU
+EUROVISION
+EUS
+EVENTS
+EXCHANGE
+EXPERT
+EXPOSED
+EXPRESS
+EXTRASPACE
+FAGE
+FAIL
+FAIRWINDS
+FAITH
+FAMILY
+FAN
+FANS
+FARM
+FARMERS
+FASHION
+FAST
+FEDEX
+FEEDBACK
+FERRARI
+FERRERO
+FI
+FIAT
+FIDELITY
+FIDO
+FILM
+FINAL
+FINANCE
+FINANCIAL
+FIRE
+FIRESTONE
+FIRMDALE
+FISH
+FISHING
+FIT
+FITNESS
+FJ
+FK
+FLICKR
+FLIGHTS
+FLIR
+FLORIST
+FLOWERS
+FLY
+FM
+FO
+FOO
+FOOD
+FOODNETWORK
+FOOTBALL
+FORD
+FOREX
+FORSALE
+FORUM
+FOUNDATION
+FOX
+FR
+FREE
+FRESENIUS
+FRL
+FROGANS
+FRONTDOOR
+FRONTIER
+FTR
+FUJITSU
+FUN
+FUND
+FURNITURE
+FUTBOL
+FYI
+GA
+GAL
+GALLERY
+GALLO
+GALLUP
+GAME
+GAMES
+GAP
+GARDEN
+GAY
+GB
+GBIZ
+GD
+GDN
+GE
+GEA
+GENT
+GENTING
+GEORGE
+GF
+GG
+GGEE
+GH
+GI
+GIFT
+GIFTS
+GIVES
+GIVING
+GL
+GLASS
+GLE
+GLOBAL
+GLOBO
+GM
+GMAIL
+GMBH
+GMO
+GMX
+GN
+GODADDY
+GOLD
+GOLDPOINT
+GOLF
+GOO
+GOODYEAR
+GOOG
+GOOGLE
+GOP
+GOT
+GOV
+GP
+GQ
+GR
+GRAINGER
+GRAPHICS
+GRATIS
+GREEN
+GRIPE
+GROCERY
+GROUP
+GS
+GT
+GU
+GUARDIAN
+GUCCI
+GUGE
+GUIDE
+GUITARS
+GURU
+GW
+GY
+HAIR
+HAMBURG
+HANGOUT
+HAUS
+HBO
+HDFC
+HDFCBANK
+HEALTH
+HEALTHCARE
+HELP
+HELSINKI
+HERE
+HERMES
+HGTV
+HIPHOP
+HISAMITSU
+HITACHI
+HIV
+HK
+HKT
+HM
+HN
+HOCKEY
+HOLDINGS
+HOLIDAY
+HOMEDEPOT
+HOMEGOODS
+HOMES
+HOMESENSE
+HONDA
+HORSE
+HOSPITAL
+HOST
+HOSTING
+HOT
+HOTELES
+HOTELS
+HOTMAIL
+HOUSE
+HOW
+HR
+HSBC
+HT
+HU
+HUGHES
+HYATT
+HYUNDAI
+IBM
+ICBC
+ICE
+ICU
+ID
+IE
+IEEE
+IFM
+IKANO
+IL
+IM
+IMAMAT
+IMDB
+IMMO
+IMMOBILIEN
+IN
+INC
+INDUSTRIES
+INFINITI
+INFO
+ING
+INK
+INSTITUTE
+INSURANCE
+INSURE
+INT
+INTERNATIONAL
+INTUIT
+INVESTMENTS
+IO
+IPIRANGA
+IQ
+IR
+IRISH
+IS
+ISMAILI
+IST
+ISTANBUL
+IT
+ITAU
+ITV
+JAGUAR
+JAVA
+JCB
+JE
+JEEP
+JETZT
+JEWELRY
+JIO
+JLL
+JM
+JMP
+JNJ
+JO
+JOBS
+JOBURG
+JOT
+JOY
+JP
+JPMORGAN
+JPRS
+JUEGOS
+JUNIPER
+KAUFEN
+KDDI
+KE
+KERRYHOTELS
+KERRYLOGISTICS
+KERRYPROPERTIES
+KFH
+KG
+KH
+KI
+KIA
+KIDS
+KIM
+KINDER
+KINDLE
+KITCHEN
+KIWI
+KM
+KN
+KOELN
+KOMATSU
+KOSHER
+KP
+KPMG
+KPN
+KR
+KRD
+KRED
+KUOKGROUP
+KW
+KY
+KYOTO
+KZ
+LA
+LACAIXA
+LAMBORGHINI
+LAMER
+LANCASTER
+LANCIA
+LAND
+LANDROVER
+LANXESS
+LASALLE
+LAT
+LATINO
+LATROBE
+LAW
+LAWYER
+LB
+LC
+LDS
+LEASE
+LECLERC
+LEFRAK
+LEGAL
+LEGO
+LEXUS
+LGBT
+LI
+LIDL
+LIFE
+LIFEINSURANCE
+LIFESTYLE
+LIGHTING
+LIKE
+LILLY
+LIMITED
+LIMO
+LINCOLN
+LINK
+LIPSY
+LIVE
+LIVING
+LK
+LLC
+LLP
+LOAN
+LOANS
+LOCKER
+LOCUS
+LOL
+LONDON
+LOTTE
+LOTTO
+LOVE
+LPL
+LPLFINANCIAL
+LR
+LS
+LT
+LTD
+LTDA
+LU
+LUNDBECK
+LUXE
+LUXURY
+LV
+LY
+MA
+MADRID
+MAIF
+MAISON
+MAKEUP
+MAN
+MANAGEMENT
+MANGO
+MAP
+MARKET
+MARKETING
+MARKETS
+MARRIOTT
+MARSHALLS
+MASERATI
+MATTEL
+MBA
+MC
+MCKINSEY
+MD
+ME
+MED
+MEDIA
+MEET
+MELBOURNE
+MEME
+MEMORIAL
+MEN
+MENU
+MERCKMSD
+MG
+MH
+MIAMI
+MICROSOFT
+MIL
+MINI
+MINT
+MIT
+MITSUBISHI
+MK
+ML
+MLB
+MLS
+MM
+MMA
+MN
+MO
+MOBI
+MOBILE
+MODA
+MOE
+MOI
+MOM
+MONASH
+MONEY
+MONSTER
+MORMON
+MORTGAGE
+MOSCOW
+MOTO
+MOTORCYCLES
+MOV
+MOVIE
+MP
+MQ
+MR
+MS
+MSD
+MT
+MTN
+MTR
+MU
+MUSEUM
+MUSIC
+MUTUAL
+MV
+MW
+MX
+MY
+MZ
+NA
+NAB
+NAGOYA
+NAME
+NATURA
+NAVY
+NBA
+NC
+NE
+NEC
+NET
+NETBANK
+NETFLIX
+NETWORK
+NEUSTAR
+NEW
+NEWS
+NEXT
+NEXTDIRECT
+NEXUS
+NF
+NFL
+NG
+NGO
+NHK
+NI
+NICO
+NIKE
+NIKON
+NINJA
+NISSAN
+NISSAY
+NL
+NO
+NOKIA
+NORTHWESTERNMUTUAL
+NORTON
+NOW
+NOWRUZ
+NOWTV
+NP
+NR
+NRA
+NRW
+NTT
+NU
+NYC
+NZ
+OBI
+OBSERVER
+OFFICE
+OKINAWA
+OLAYAN
+OLAYANGROUP
+OLDNAVY
+OLLO
+OM
+OMEGA
+ONE
+ONG
+ONL
+ONLINE
+OOO
+OPEN
+ORACLE
+ORANGE
+ORG
+ORGANIC
+ORIGINS
+OSAKA
+OTSUKA
+OTT
+OVH
+PA
+PAGE
+PANASONIC
+PARIS
+PARS
+PARTNERS
+PARTS
+PARTY
+PASSAGENS
+PAY
+PCCW
+PE
+PET
+PF
+PFIZER
+PG
+PH
+PHARMACY
+PHD
+PHILIPS
+PHONE
+PHOTO
+PHOTOGRAPHY
+PHOTOS
+PHYSIO
+PICS
+PICTET
+PICTURES
+PID
+PIN
+PING
+PINK
+PIONEER
+PIZZA
+PK
+PL
+PLACE
+PLAY
+PLAYSTATION
+PLUMBING
+PLUS
+PM
+PN
+PNC
+POHL
+POKER
+POLITIE
+PORN
+POST
+PR
+PRAMERICA
+PRAXI
+PRESS
+PRIME
+PRO
+PROD
+PRODUCTIONS
+PROF
+PROGRESSIVE
+PROMO
+PROPERTIES
+PROPERTY
+PROTECTION
+PRU
+PRUDENTIAL
+PS
+PT
+PUB
+PW
+PWC
+PY
+QA
+QPON
+QUEBEC
+QUEST
+RACING
+RADIO
+RE
+READ
+REALESTATE
+REALTOR
+REALTY
+RECIPES
+RED
+REDSTONE
+REDUMBRELLA
+REHAB
+REISE
+REISEN
+REIT
+RELIANCE
+REN
+RENT
+RENTALS
+REPAIR
+REPORT
+REPUBLICAN
+REST
+RESTAURANT
+REVIEW
+REVIEWS
+REXROTH
+RICH
+RICHARDLI
+RICOH
+RIL
+RIO
+RIP
+RO
+ROCHER
+ROCKS
+RODEO
+ROGERS
+ROOM
+RS
+RSVP
+RU
+RUGBY
+RUHR
+RUN
+RW
+RWE
+RYUKYU
+SA
+SAARLAND
+SAFE
+SAFETY
+SAKURA
+SALE
+SALON
+SAMSCLUB
+SAMSUNG
+SANDVIK
+SANDVIKCOROMANT
+SANOFI
+SAP
+SARL
+SAS
+SAVE
+SAXO
+SB
+SBI
+SBS
+SC
+SCA
+SCB
+SCHAEFFLER
+SCHMIDT
+SCHOLARSHIPS
+SCHOOL
+SCHULE
+SCHWARZ
+SCIENCE
+SCOT
+SD
+SE
+SEARCH
+SEAT
+SECURE
+SECURITY
+SEEK
+SELECT
+SENER
+SERVICES
+SEVEN
+SEW
+SEX
+SEXY
+SFR
+SG
+SH
+SHANGRILA
+SHARP
+SHAW
+SHELL
+SHIA
+SHIKSHA
+SHOES
+SHOP
+SHOPPING
+SHOUJI
+SHOW
+SHOWTIME
+SI
+SILK
+SINA
+SINGLES
+SITE
+SJ
+SK
+SKI
+SKIN
+SKY
+SKYPE
+SL
+SLING
+SM
+SMART
+SMILE
+SN
+SNCF
+SO
+SOCCER
+SOCIAL
+SOFTBANK
+SOFTWARE
+SOHU
+SOLAR
+SOLUTIONS
+SONG
+SONY
+SOY
+SPA
+SPACE
+SPORT
+SPOT
+SR
+SRL
+SS
+ST
+STADA
+STAPLES
+STAR
+STATEBANK
+STATEFARM
+STC
+STCGROUP
+STOCKHOLM
+STORAGE
+STORE
+STREAM
+STUDIO
+STUDY
+STYLE
+SU
+SUCKS
+SUPPLIES
+SUPPLY
+SUPPORT
+SURF
+SURGERY
+SUZUKI
+SV
+SWATCH
+SWISS
+SX
+SY
+SYDNEY
+SYSTEMS
+SZ
+TAB
+TAIPEI
+TALK
+TAOBAO
+TARGET
+TATAMOTORS
+TATAR
+TATTOO
+TAX
+TAXI
+TC
+TCI
+TD
+TDK
+TEAM
+TECH
+TECHNOLOGY
+TEL
+TEMASEK
+TENNIS
+TEVA
+TF
+TG
+TH
+THD
+THEATER
+THEATRE
+TIAA
+TICKETS
+TIENDA
+TIFFANY
+TIPS
+TIRES
+TIROL
+TJ
+TJMAXX
+TJX
+TK
+TKMAXX
+TL
+TM
+TMALL
+TN
+TO
+TODAY
+TOKYO
+TOOLS
+TOP
+TORAY
+TOSHIBA
+TOTAL
+TOURS
+TOWN
+TOYOTA
+TOYS
+TR
+TRADE
+TRADING
+TRAINING
+TRAVEL
+TRAVELCHANNEL
+TRAVELERS
+TRAVELERSINSURANCE
+TRUST
+TRV
+TT
+TUBE
+TUI
+TUNES
+TUSHU
+TV
+TVS
+TW
+TZ
+UA
+UBANK
+UBS
+UG
+UK
+UNICOM
+UNIVERSITY
+UNO
+UOL
+UPS
+US
+UY
+UZ
+VA
+VACATIONS
+VANA
+VANGUARD
+VC
+VE
+VEGAS
+VENTURES
+VERISIGN
+VERSICHERUNG
+VET
+VG
+VI
+VIAJES
+VIDEO
+VIG
+VIKING
+VILLAS
+VIN
+VIP
+VIRGIN
+VISA
+VISION
+VIVA
+VIVO
+VLAANDEREN
+VN
+VODKA
+VOLKSWAGEN
+VOLVO
+VOTE
+VOTING
+VOTO
+VOYAGE
+VU
+VUELOS
+WALES
+WALMART
+WALTER
+WANG
+WANGGOU
+WATCH
+WATCHES
+WEATHER
+WEATHERCHANNEL
+WEBCAM
+WEBER
+WEBSITE
+WED
+WEDDING
+WEIBO
+WEIR
+WF
+WHOSWHO
+WIEN
+WIKI
+WILLIAMHILL
+WIN
+WINDOWS
+WINE
+WINNERS
+WME
+WOLTERSKLUWER
+WOODSIDE
+WORK
+WORKS
+WORLD
+WOW
+WS
+WTC
+WTF
+XBOX
+XEROX
+XFINITY
+XIHUAN
+XIN
+XN--11B4C3D
+XN--1CK2E1B
+XN--1QQW23A
+XN--2SCRJ9C
+XN--30RR7Y
+XN--3BST00M
+XN--3DS443G
+XN--3E0B707E
+XN--3HCRJ9C
+XN--3PXU8K
+XN--42C2D9A
+XN--45BR5CYL
+XN--45BRJ9C
+XN--45Q11C
+XN--4DBRK0CE
+XN--4GBRIM
+XN--54B7FTA0CC
+XN--55QW42G
+XN--55QX5D
+XN--5SU34J936BGSG
+XN--5TZM5G
+XN--6FRZ82G
+XN--6QQ986B3XL
+XN--80ADXHKS
+XN--80AO21A
+XN--80AQECDR1A
+XN--80ASEHDB
+XN--80ASWG
+XN--8Y0A063A
+XN--90A3AC
+XN--90AE
+XN--90AIS
+XN--9DBQ2A
+XN--9ET52U
+XN--9KRT00A
+XN--B4W605FERD
+XN--BCK1B9A5DRE4C
+XN--C1AVG
+XN--C2BR7G
+XN--CCK2B3B
+XN--CCKWCXETD
+XN--CG4BKI
+XN--CLCHC0EA0B2G2A9GCD
+XN--CZR694B
+XN--CZRS0T
+XN--CZRU2D
+XN--D1ACJ3B
+XN--D1ALF
+XN--E1A4C
+XN--ECKVDTC9D
+XN--EFVY88H
+XN--FCT429K
+XN--FHBEI
+XN--FIQ228C5HS
+XN--FIQ64B
+XN--FIQS8S
+XN--FIQZ9S
+XN--FJQ720A
+XN--FLW351E
+XN--FPCRJ9C3D
+XN--FZC2C9E2C
+XN--FZYS8D69UVGM
+XN--G2XX48C
+XN--GCKR3F0F
+XN--GECRJ9C
+XN--GK3AT1E
+XN--H2BREG3EVE
+XN--H2BRJ9C
+XN--H2BRJ9C8C
+XN--HXT814E
+XN--I1B6B1A6A2E
+XN--IMR513N
+XN--IO0A7I
+XN--J1AEF
+XN--J1AMH
+XN--J6W193G
+XN--JLQ480N2RG
+XN--JVR189M
+XN--KCRX77D1X4A
+XN--KPRW13D
+XN--KPRY57D
+XN--KPUT3I
+XN--L1ACC
+XN--LGBBAT1AD8J
+XN--MGB9AWBF
+XN--MGBA3A3EJT
+XN--MGBA3A4F16A
+XN--MGBA7C0BBN0A
+XN--MGBAAKC7DVF
+XN--MGBAAM7A8H
+XN--MGBAB2BD
+XN--MGBAH1A3HJKRD
+XN--MGBAI9AZGQP6J
+XN--MGBAYH7GPA
+XN--MGBBH1A
+XN--MGBBH1A71E
+XN--MGBC0A9AZCG
+XN--MGBCA7DZDO
+XN--MGBCPQ6GPA1A
+XN--MGBERP4A5D4AR
+XN--MGBGU82A
+XN--MGBI4ECEXP
+XN--MGBPL2FH
+XN--MGBT3DHD
+XN--MGBTX2B
+XN--MGBX4CD0AB
+XN--MIX891F
+XN--MK1BU44C
+XN--MXTQ1M
+XN--NGBC5AZD
+XN--NGBE9E0A
+XN--NGBRX
+XN--NODE
+XN--NQV7F
+XN--NQV7FS00EMA
+XN--NYQY26A
+XN--O3CW4H
+XN--OGBPF8FL
+XN--OTU796D
+XN--P1ACF
+XN--P1AI
+XN--PGBS0DH
+XN--PSSY2U
+XN--Q7CE6A
+XN--Q9JYB4C
+XN--QCKA1PMC
+XN--QXA6A
+XN--QXAM
+XN--RHQV96G
+XN--ROVU88B
+XN--RVC1E0AM3E
+XN--S9BRJ9C
+XN--SES554G
+XN--T60B56A
+XN--TCKWE
+XN--TIQ49XQYJ
+XN--UNUP4Y
+XN--VERMGENSBERATER-CTB
+XN--VERMGENSBERATUNG-PWB
+XN--VHQUV
+XN--VUQ861B
+XN--W4R85EL8FHU5DNRA
+XN--W4RS40L
+XN--WGBH1C
+XN--WGBL6A
+XN--XHQ521B
+XN--XKC2AL3HYE2A
+XN--XKC2DL3A5EE0H
+XN--Y9A3AQ
+XN--YFRO4I67O
+XN--YGBI2AMMX
+XN--ZFR164B
+XXX
+XYZ
+YACHTS
+YAHOO
+YAMAXUN
+YANDEX
+YE
+YODOBASHI
+YOGA
+YOKOHAMA
+YOU
+YOUTUBE
+YT
+YUN
+ZA
+ZAPPOS
+ZARA
+ZERO
+ZIP
+ZM
+ZONE
+ZUERICH
+ZW