ÿØÿà JFIF    ÿÛ „ ( %!1!%*+...983,7(-.- PKRp]lǻPoll.pmnu[ # IO::Poll.pm # # Copyright (c) 1997-8 Graham Barr . All rights reserved. # This program is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. package IO::Poll; use strict; use IO::Handle; use Exporter (); our(@ISA, @EXPORT_OK, @EXPORT, $VERSION); @ISA = qw(Exporter); $VERSION = "0.10"; @EXPORT = qw( POLLIN POLLOUT POLLERR POLLHUP POLLNVAL ); @EXPORT_OK = qw( POLLPRI POLLRDNORM POLLWRNORM POLLRDBAND POLLWRBAND POLLNORM ); # [0] maps fd's to requested masks # [1] maps fd's to returned masks # [2] maps fd's to handles sub new { my $class = shift; my $self = bless [{},{},{}], $class; $self; } sub mask { my $self = shift; my $io = shift; my $fd = fileno($io); return unless defined $fd; if (@_) { my $mask = shift; if($mask) { $self->[0]{$fd}{$io} = $mask; # the error events are always returned $self->[1]{$fd} = 0; # output mask $self->[2]{$io} = $io; # remember handle } else { delete $self->[0]{$fd}{$io}; unless(%{$self->[0]{$fd}}) { # We no longer have any handles for this FD delete $self->[1]{$fd}; delete $self->[0]{$fd}; } delete $self->[2]{$io}; } } return unless exists $self->[0]{$fd} and exists $self->[0]{$fd}{$io}; return $self->[0]{$fd}{$io}; } sub poll { my($self,$timeout) = @_; $self->[1] = {}; my($fd,$mask,$iom); my @poll = (); while(($fd,$iom) = each %{$self->[0]}) { $mask = 0; $mask |= $_ for values(%$iom); push(@poll,$fd => $mask); } my $ret = _poll(defined($timeout) ? $timeout * 1000 : -1,@poll); return $ret unless $ret > 0; while(@poll) { my($fd,$got) = splice(@poll,0,2); $self->[1]{$fd} = $got if $got; } return $ret; } sub events { my $self = shift; my $io = shift; my $fd = fileno($io); exists $self->[1]{$fd} and exists $self->[0]{$fd}{$io} ? $self->[1]{$fd} & ($self->[0]{$fd}{$io}|POLLHUP|POLLERR|POLLNVAL) : 0; } sub remove { my $self = shift; my $io = shift; $self->mask($io,0); } sub handles { my $self = shift; return values %{$self->[2]} unless @_; my $events = shift || 0; my($fd,$ev,$io,$mask); my @handles = (); while(($fd,$ev) = each %{$self->[1]}) { while (($io,$mask) = each %{$self->[0]{$fd}}) { $mask |= POLLHUP|POLLERR|POLLNVAL; # must allow these push @handles,$self->[2]{$io} if ($ev & $mask) & $events; } } return @handles; } 1; __END__ =head1 NAME IO::Poll - Object interface to system poll call =head1 SYNOPSIS use IO::Poll qw(POLLRDNORM POLLWRNORM POLLIN POLLHUP); $poll = IO::Poll->new(); $poll->mask($input_handle => POLLIN); $poll->mask($output_handle => POLLOUT); $poll->poll($timeout); $ev = $poll->events($input); =head1 DESCRIPTION C is a simple interface to the system level poll routine. =head1 METHODS =over 4 =item mask ( IO [, EVENT_MASK ] ) If EVENT_MASK is given, then, if EVENT_MASK is non-zero, IO is added to the list of file descriptors and the next call to poll will check for any event specified in EVENT_MASK. If EVENT_MASK is zero then IO will be removed from the list of file descriptors. If EVENT_MASK is not given then the return value will be the current event mask value for IO. =item poll ( [ TIMEOUT ] ) Call the system level poll routine. If TIMEOUT is not specified then the call will block. Returns the number of handles which had events happen, or -1 on error. =item events ( IO ) Returns the event mask which represents the events that happened on IO during the last call to C. =item remove ( IO ) Remove IO from the list of file descriptors for the next poll. =item handles( [ EVENT_MASK ] ) Returns a list of handles. If EVENT_MASK is not given then a list of all handles known will be returned. If EVENT_MASK is given then a list of handles will be returned which had one of the events specified by EVENT_MASK happen during the last call ti C =back =head1 SEE ALSO L, L, L =head1 AUTHOR Graham Barr. Currently maintained by the Perl Porters. Please report all bugs to . =head1 COPYRIGHT Copyright (c) 1997-8 Graham Barr . All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut PKRp]"00Socket/INET.pmnu[# IO::Socket::INET.pm # # Copyright (c) 1997-8 Graham Barr . All rights reserved. # This program is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. package IO::Socket::INET; use strict; our(@ISA, $VERSION); use IO::Socket; use Socket; use Carp; use Exporter; use Errno; @ISA = qw(IO::Socket); $VERSION = "1.35"; my $EINVAL = exists(&Errno::EINVAL) ? Errno::EINVAL() : 1; IO::Socket::INET->register_domain( AF_INET ); my %socket_type = ( tcp => SOCK_STREAM, udp => SOCK_DGRAM, icmp => SOCK_RAW ); my %proto_number; $proto_number{tcp} = Socket::IPPROTO_TCP() if defined &Socket::IPPROTO_TCP; $proto_number{udp} = Socket::IPPROTO_UDP() if defined &Socket::IPPROTO_UDP; $proto_number{icmp} = Socket::IPPROTO_ICMP() if defined &Socket::IPPROTO_ICMP; my %proto_name = reverse %proto_number; sub new { my $class = shift; unshift(@_, "PeerAddr") if @_ == 1; return $class->SUPER::new(@_); } sub _cache_proto { my @proto = @_; for (map lc($_), $proto[0], split(' ', $proto[1])) { $proto_number{$_} = $proto[2]; } $proto_name{$proto[2]} = $proto[0]; } sub _get_proto_number { my $name = lc(shift); return undef unless defined $name; return $proto_number{$name} if exists $proto_number{$name}; my @proto = eval { getprotobyname($name) }; return undef unless @proto; _cache_proto(@proto); return $proto[2]; } sub _get_proto_name { my $num = shift; return undef unless defined $num; return $proto_name{$num} if exists $proto_name{$num}; my @proto = eval { getprotobynumber($num) }; return undef unless @proto; _cache_proto(@proto); return $proto[0]; } sub _sock_info { my($addr,$port,$proto) = @_; my $origport = $port; my @serv = (); $port = $1 if(defined $addr && $addr =~ s,:([\w\(\)/]+)$,,); if(defined $proto && $proto =~ /\D/) { my $num = _get_proto_number($proto); unless (defined $num) { $@ = "Bad protocol '$proto'"; return; } $proto = $num; } if(defined $port) { my $defport = ($port =~ s,\((\d+)\)$,,) ? $1 : undef; my $pnum = ($port =~ m,^(\d+)$,)[0]; @serv = getservbyname($port, _get_proto_name($proto) || "") if ($port =~ m,\D,); $port = $serv[2] || $defport || $pnum; unless (defined $port) { $@ = "Bad service '$origport'"; return; } $proto = _get_proto_number($serv[3]) if @serv && !$proto; } return ($addr || undef, $port || undef, $proto || undef ); } sub _error { my $sock = shift; my $err = shift; { local($!); my $title = ref($sock).": "; $@ = join("", $_[0] =~ /^$title/ ? "" : $title, @_); $sock->close() if(defined fileno($sock)); } $! = $err; return undef; } sub _get_addr { my($sock,$addr_str, $multi) = @_; my @addr; if ($multi && $addr_str !~ /^\d+(?:\.\d+){3}$/) { (undef, undef, undef, undef, @addr) = gethostbyname($addr_str); } else { my $h = inet_aton($addr_str); push(@addr, $h) if defined $h; } @addr; } sub configure { my($sock,$arg) = @_; my($lport,$rport,$laddr,$raddr,$proto,$type); $arg->{LocalAddr} = $arg->{LocalHost} if exists $arg->{LocalHost} && !exists $arg->{LocalAddr}; ($laddr,$lport,$proto) = _sock_info($arg->{LocalAddr}, $arg->{LocalPort}, $arg->{Proto}) or return _error($sock, $!, $@); $laddr = defined $laddr ? inet_aton($laddr) : INADDR_ANY; return _error($sock, $EINVAL, "Bad hostname '",$arg->{LocalAddr},"'") unless(defined $laddr); $arg->{PeerAddr} = $arg->{PeerHost} if exists $arg->{PeerHost} && !exists $arg->{PeerAddr}; unless(exists $arg->{Listen}) { ($raddr,$rport,$proto) = _sock_info($arg->{PeerAddr}, $arg->{PeerPort}, $proto) or return _error($sock, $!, $@); } $proto ||= _get_proto_number('tcp'); $type = $arg->{Type} || $socket_type{lc _get_proto_name($proto)}; my @raddr = (); if(defined $raddr) { @raddr = $sock->_get_addr($raddr, $arg->{MultiHomed}); return _error($sock, $EINVAL, "Bad hostname '",$arg->{PeerAddr},"'") unless @raddr; } while(1) { $sock->socket(AF_INET, $type, $proto) or return _error($sock, $!, "$!"); if (defined $arg->{Blocking}) { defined $sock->blocking($arg->{Blocking}) or return _error($sock, $!, "$!"); } if ($arg->{Reuse} || $arg->{ReuseAddr}) { $sock->sockopt(SO_REUSEADDR,1) or return _error($sock, $!, "$!"); } if ($arg->{ReusePort}) { $sock->sockopt(SO_REUSEPORT,1) or return _error($sock, $!, "$!"); } if ($arg->{Broadcast}) { $sock->sockopt(SO_BROADCAST,1) or return _error($sock, $!, "$!"); } if($lport || ($laddr ne INADDR_ANY) || exists $arg->{Listen}) { $sock->bind($lport || 0, $laddr) or return _error($sock, $!, "$!"); } if(exists $arg->{Listen}) { $sock->listen($arg->{Listen} || 5) or return _error($sock, $!, "$!"); last; } # don't try to connect unless we're given a PeerAddr last unless exists($arg->{PeerAddr}); $raddr = shift @raddr; return _error($sock, $EINVAL, 'Cannot determine remote port') unless($rport || $type == SOCK_DGRAM || $type == SOCK_RAW); last unless($type == SOCK_STREAM || defined $raddr); return _error($sock, $EINVAL, "Bad hostname '",$arg->{PeerAddr},"'") unless defined $raddr; # my $timeout = ${*$sock}{'io_socket_timeout'}; # my $before = time() if $timeout; undef $@; if ($sock->connect(pack_sockaddr_in($rport, $raddr))) { # ${*$sock}{'io_socket_timeout'} = $timeout; return $sock; } return _error($sock, $!, $@ || "Timeout") unless @raddr; # if ($timeout) { # my $new_timeout = $timeout - (time() - $before); # return _error($sock, # (exists(&Errno::ETIMEDOUT) ? Errno::ETIMEDOUT() : $EINVAL), # "Timeout") if $new_timeout <= 0; # ${*$sock}{'io_socket_timeout'} = $new_timeout; # } } $sock; } sub connect { @_ == 2 || @_ == 3 or croak 'usage: $sock->connect(NAME) or $sock->connect(PORT, ADDR)'; my $sock = shift; return $sock->SUPER::connect(@_ == 1 ? shift : pack_sockaddr_in(@_)); } sub bind { @_ == 2 || @_ == 3 or croak 'usage: $sock->bind(NAME) or $sock->bind(PORT, ADDR)'; my $sock = shift; return $sock->SUPER::bind(@_ == 1 ? shift : pack_sockaddr_in(@_)) } sub sockaddr { @_ == 1 or croak 'usage: $sock->sockaddr()'; my($sock) = @_; my $name = $sock->sockname; $name ? (sockaddr_in($name))[1] : undef; } sub sockport { @_ == 1 or croak 'usage: $sock->sockport()'; my($sock) = @_; my $name = $sock->sockname; $name ? (sockaddr_in($name))[0] : undef; } sub sockhost { @_ == 1 or croak 'usage: $sock->sockhost()'; my($sock) = @_; my $addr = $sock->sockaddr; $addr ? inet_ntoa($addr) : undef; } sub peeraddr { @_ == 1 or croak 'usage: $sock->peeraddr()'; my($sock) = @_; my $name = $sock->peername; $name ? (sockaddr_in($name))[1] : undef; } sub peerport { @_ == 1 or croak 'usage: $sock->peerport()'; my($sock) = @_; my $name = $sock->peername; $name ? (sockaddr_in($name))[0] : undef; } sub peerhost { @_ == 1 or croak 'usage: $sock->peerhost()'; my($sock) = @_; my $addr = $sock->peeraddr; $addr ? inet_ntoa($addr) : undef; } 1; __END__ =head1 NAME IO::Socket::INET - Object interface for AF_INET domain sockets =head1 SYNOPSIS use IO::Socket::INET; =head1 DESCRIPTION C provides an object interface to creating and using sockets in the AF_INET domain. It is built upon the L interface and inherits all the methods defined by L. =head1 CONSTRUCTOR =over 4 =item new ( [ARGS] ) Creates an C object, which is a reference to a newly created symbol (see the C package). C optionally takes arguments, these arguments are in key-value pairs. In addition to the key-value pairs accepted by L, C provides. PeerAddr Remote host address [:] PeerHost Synonym for PeerAddr PeerPort Remote port or service [()] | LocalAddr Local host bind address hostname[:port] LocalHost Synonym for LocalAddr LocalPort Local host bind port [()] | Proto Protocol name (or number) "tcp" | "udp" | ... Type Socket type SOCK_STREAM | SOCK_DGRAM | ... Listen Queue size for listen ReuseAddr Set SO_REUSEADDR before binding Reuse Set SO_REUSEADDR before binding (deprecated, prefer ReuseAddr) ReusePort Set SO_REUSEPORT before binding Broadcast Set SO_BROADCAST before binding Timeout Timeout value for various operations MultiHomed Try all addresses for multi-homed hosts Blocking Determine if connection will be blocking mode If C is defined then a listen socket is created, else if the socket type, which is derived from the protocol, is SOCK_STREAM then connect() is called. If the C argument is given, but false, the queue size will be set to 5. Although it is not illegal, the use of C on a socket which is in non-blocking mode is of little use. This is because the first connect will never fail with a timeout as the connect call will not block. The C can be a hostname or the IP-address on the "xx.xx.xx.xx" form. The C can be a number or a symbolic service name. The service name might be followed by a number in parenthesis which is used if the service is not known by the system. The C specification can also be embedded in the C by preceding it with a ":". If C is not given and you specify a symbolic C port, then the constructor will try to derive C from the service name. As a last resort C "tcp" is assumed. The C parameter will be deduced from C if not specified. If the constructor is only passed a single argument, it is assumed to be a C specification. If C is set to 0, the connection will be in nonblocking mode. If not specified it defaults to 1 (blocking mode). Examples: $sock = IO::Socket::INET->new(PeerAddr => 'www.perl.org', PeerPort => 'http(80)', Proto => 'tcp'); $sock = IO::Socket::INET->new(PeerAddr => 'localhost:smtp(25)'); $sock = IO::Socket::INET->new(Listen => 5, LocalAddr => 'localhost', LocalPort => 9000, Proto => 'tcp'); $sock = IO::Socket::INET->new('127.0.0.1:25'); $sock = IO::Socket::INET->new( PeerPort => 9999, PeerAddr => inet_ntoa(INADDR_BROADCAST), Proto => udp, LocalAddr => 'localhost', Broadcast => 1 ) or die "Can't bind : $@\n"; NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE As of VERSION 1.18 all IO::Socket objects have autoflush turned on by default. This was not the case with earlier releases. NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE =back =head2 METHODS =over 4 =item sockaddr () Return the address part of the sockaddr structure for the socket =item sockport () Return the port number that the socket is using on the local host =item sockhost () Return the address part of the sockaddr structure for the socket in a text form xx.xx.xx.xx =item peeraddr () Return the address part of the sockaddr structure for the socket on the peer host =item peerport () Return the port number for the socket on the peer host. =item peerhost () Return the address part of the sockaddr structure for the socket on the peer host in a text form xx.xx.xx.xx =back =head1 SEE ALSO L, L =head1 AUTHOR Graham Barr. Currently maintained by the Perl Porters. Please report all bugs to . =head1 COPYRIGHT Copyright (c) 1996-8 Graham Barr . All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut PKRp]XpJ_ _ Socket/UNIX.pmnu[# IO::Socket::UNIX.pm # # Copyright (c) 1997-8 Graham Barr . All rights reserved. # This program is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. package IO::Socket::UNIX; use strict; our(@ISA, $VERSION); use IO::Socket; use Carp; @ISA = qw(IO::Socket); $VERSION = "1.26"; $VERSION = eval $VERSION; IO::Socket::UNIX->register_domain( AF_UNIX ); sub new { my $class = shift; unshift(@_, "Peer") if @_ == 1; return $class->SUPER::new(@_); } sub configure { my($sock,$arg) = @_; my($bport,$cport); my $type = $arg->{Type} || SOCK_STREAM; $sock->socket(AF_UNIX, $type, 0) or return undef; if(exists $arg->{Local}) { my $addr = sockaddr_un($arg->{Local}); $sock->bind($addr) or return undef; } if(exists $arg->{Listen} && $type != SOCK_DGRAM) { $sock->listen($arg->{Listen} || 5) or return undef; } elsif(exists $arg->{Peer}) { my $addr = sockaddr_un($arg->{Peer}); $sock->connect($addr) or return undef; } $sock; } sub hostpath { @_ == 1 or croak 'usage: $sock->hostpath()'; my $n = $_[0]->sockname || return undef; (sockaddr_un($n))[0]; } sub peerpath { @_ == 1 or croak 'usage: $sock->peerpath()'; my $n = $_[0]->peername || return undef; (sockaddr_un($n))[0]; } 1; # Keep require happy __END__ =head1 NAME IO::Socket::UNIX - Object interface for AF_UNIX domain sockets =head1 SYNOPSIS use IO::Socket::UNIX; my $SOCK_PATH = "$ENV{HOME}/unix-domain-socket-test.sock"; # Server: my $server = IO::Socket::UNIX->new( Type => SOCK_STREAM(), Local => $SOCK_PATH, Listen => 1, ); my $count = 1; while (my $conn = $server->accept()) { $conn->print("Hello " . ($count++) . "\n"); } # Client: my $client = IO::Socket::UNIX->new( Type => SOCK_STREAM(), Peer => $SOCK_PATH, ); # Now read and write from $client =head1 DESCRIPTION C provides an object interface to creating and using sockets in the AF_UNIX domain. It is built upon the L interface and inherits all the methods defined by L. =head1 CONSTRUCTOR =over 4 =item new ( [ARGS] ) Creates an C object, which is a reference to a newly created symbol (see the C package). C optionally takes arguments, these arguments are in key-value pairs. In addition to the key-value pairs accepted by L, C provides. Type Type of socket (eg SOCK_STREAM or SOCK_DGRAM) Local Path to local fifo Peer Path to peer fifo Listen Queue size for listen If the constructor is only passed a single argument, it is assumed to be a C specification. If the C argument is given, but false, the queue size will be set to 5. =back =head1 METHODS =over 4 =item hostpath() Returns the pathname to the fifo at the local end =item peerpath() Returns the pathanme to the fifo at the peer end =back =head1 SEE ALSO L, L =head1 AUTHOR Graham Barr. Currently maintained by the Perl Porters. Please report all bugs to . =head1 COPYRIGHT Copyright (c) 1996-8 Graham Barr . All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut PKRp][fDir.pmnu[# IO::Dir.pm # # Copyright (c) 1997-8 Graham Barr . All rights reserved. # This program is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. package IO::Dir; use 5.006; use strict; use Carp; use Symbol; use Exporter; use IO::File; our(@ISA, $VERSION, @EXPORT_OK); use Tie::Hash; use File::stat; use File::Spec; @ISA = qw(Tie::Hash Exporter); $VERSION = "1.10"; $VERSION = eval $VERSION; @EXPORT_OK = qw(DIR_UNLINK); sub DIR_UNLINK () { 1 } sub new { @_ >= 1 && @_ <= 2 or croak 'usage: IO::Dir->new([DIRNAME])'; my $class = shift; my $dh = gensym; if (@_) { IO::Dir::open($dh, $_[0]) or return undef; } bless $dh, $class; } sub DESTROY { my ($dh) = @_; local($., $@, $!, $^E, $?); no warnings 'io'; closedir($dh); } sub open { @_ == 2 or croak 'usage: $dh->open(DIRNAME)'; my ($dh, $dirname) = @_; return undef unless opendir($dh, $dirname); # a dir name should always have a ":" in it; assume dirname is # in current directory $dirname = ':' . $dirname if ( ($^O eq 'MacOS') && ($dirname !~ /:/) ); ${*$dh}{io_dir_path} = $dirname; 1; } sub close { @_ == 1 or croak 'usage: $dh->close()'; my ($dh) = @_; closedir($dh); } sub read { @_ == 1 or croak 'usage: $dh->read()'; my ($dh) = @_; readdir($dh); } sub seek { @_ == 2 or croak 'usage: $dh->seek(POS)'; my ($dh,$pos) = @_; seekdir($dh,$pos); } sub tell { @_ == 1 or croak 'usage: $dh->tell()'; my ($dh) = @_; telldir($dh); } sub rewind { @_ == 1 or croak 'usage: $dh->rewind()'; my ($dh) = @_; rewinddir($dh); } sub TIEHASH { my($class,$dir,$options) = @_; my $dh = $class->new($dir) or return undef; $options ||= 0; ${*$dh}{io_dir_unlink} = $options & DIR_UNLINK; $dh; } sub FIRSTKEY { my($dh) = @_; $dh->rewind; scalar $dh->read; } sub NEXTKEY { my($dh) = @_; scalar $dh->read; } sub EXISTS { my($dh,$key) = @_; -e File::Spec->catfile(${*$dh}{io_dir_path}, $key); } sub FETCH { my($dh,$key) = @_; &lstat(File::Spec->catfile(${*$dh}{io_dir_path}, $key)); } sub STORE { my($dh,$key,$data) = @_; my($atime,$mtime) = ref($data) ? @$data : ($data,$data); my $file = File::Spec->catfile(${*$dh}{io_dir_path}, $key); unless(-e $file) { my $io = IO::File->new($file,O_CREAT | O_RDWR); $io->close if $io; } utime($atime,$mtime, $file); } sub DELETE { my($dh,$key) = @_; # Only unlink if unlink-ing is enabled return 0 unless ${*$dh}{io_dir_unlink}; my $file = File::Spec->catfile(${*$dh}{io_dir_path}, $key); -d $file ? rmdir($file) : unlink($file); } 1; __END__ =head1 NAME IO::Dir - supply object methods for directory handles =head1 SYNOPSIS use IO::Dir; $d = IO::Dir->new("."); if (defined $d) { while (defined($_ = $d->read)) { something($_); } $d->rewind; while (defined($_ = $d->read)) { something_else($_); } undef $d; } tie %dir, 'IO::Dir', "."; foreach (keys %dir) { print $_, " " , $dir{$_}->size,"\n"; } =head1 DESCRIPTION The C package provides two interfaces to perl's directory reading routines. The first interface is an object approach. C provides an object constructor and methods, which are just wrappers around perl's built in directory reading routines. =over 4 =item new ( [ DIRNAME ] ) C is the constructor for C objects. It accepts one optional argument which, if given, C will pass to C =back The following methods are wrappers for the directory related functions built into perl (the trailing 'dir' has been removed from the names). See L for details of these functions. =over 4 =item open ( DIRNAME ) =item read () =item seek ( POS ) =item tell () =item rewind () =item close () =back C also provides an interface to reading directories via a tied hash. The tied hash extends the interface beyond just the directory reading routines by the use of C, from the C package, C, C and C. =over 4 =item tie %hash, 'IO::Dir', DIRNAME [, OPTIONS ] =back The keys of the hash will be the names of the entries in the directory. Reading a value from the hash will be the result of calling C. Deleting an element from the hash will delete the corresponding file or subdirectory, provided that C is included in the C. Assigning to an entry in the hash will cause the time stamps of the file to be modified. If the file does not exist then it will be created. Assigning a single integer to a hash element will cause both the access and modification times to be changed to that value. Alternatively a reference to an array of two values can be passed. The first array element will be used to set the access time and the second element will be used to set the modification time. =head1 SEE ALSO L =head1 AUTHOR Graham Barr. Currently maintained by the Perl Porters. Please report all bugs to . =head1 COPYRIGHT Copyright (c) 1997-2003 Graham Barr . All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut PKRp]D>> Socket.pmnu[ # IO::Socket.pm # # Copyright (c) 1997-8 Graham Barr . All rights reserved. # This program is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. package IO::Socket; require 5.006; use IO::Handle; use Socket 1.3; use Carp; use strict; our(@ISA, $VERSION, @EXPORT_OK); use Exporter; use Errno; # legacy require IO::Socket::INET; require IO::Socket::UNIX if ($^O ne 'epoc' && $^O ne 'symbian'); @ISA = qw(IO::Handle); $VERSION = "1.38"; @EXPORT_OK = qw(sockatmark); sub import { my $pkg = shift; if (@_ && $_[0] eq 'sockatmark') { # not very extensible but for now, fast Exporter::export_to_level('IO::Socket', 1, $pkg, 'sockatmark'); } else { my $callpkg = caller; Exporter::export 'Socket', $callpkg, @_; } } sub new { my($class,%arg) = @_; my $sock = $class->SUPER::new(); $sock->autoflush(1); ${*$sock}{'io_socket_timeout'} = delete $arg{Timeout}; return scalar(%arg) ? $sock->configure(\%arg) : $sock; } my @domain2pkg; sub register_domain { my($p,$d) = @_; $domain2pkg[$d] = $p; } sub configure { my($sock,$arg) = @_; my $domain = delete $arg->{Domain}; croak 'IO::Socket: Cannot configure a generic socket' unless defined $domain; croak "IO::Socket: Unsupported socket domain" unless defined $domain2pkg[$domain]; croak "IO::Socket: Cannot configure socket in domain '$domain'" unless ref($sock) eq "IO::Socket"; bless($sock, $domain2pkg[$domain]); $sock->configure($arg); } sub socket { @_ == 4 or croak 'usage: $sock->socket(DOMAIN, TYPE, PROTOCOL)'; my($sock,$domain,$type,$protocol) = @_; socket($sock,$domain,$type,$protocol) or return undef; ${*$sock}{'io_socket_domain'} = $domain; ${*$sock}{'io_socket_type'} = $type; ${*$sock}{'io_socket_proto'} = $protocol; $sock; } sub socketpair { @_ == 4 || croak 'usage: IO::Socket->socketpair(DOMAIN, TYPE, PROTOCOL)'; my($class,$domain,$type,$protocol) = @_; my $sock1 = $class->new(); my $sock2 = $class->new(); socketpair($sock1,$sock2,$domain,$type,$protocol) or return (); ${*$sock1}{'io_socket_type'} = ${*$sock2}{'io_socket_type'} = $type; ${*$sock1}{'io_socket_proto'} = ${*$sock2}{'io_socket_proto'} = $protocol; ($sock1,$sock2); } sub connect { @_ == 2 or croak 'usage: $sock->connect(NAME)'; my $sock = shift; my $addr = shift; my $timeout = ${*$sock}{'io_socket_timeout'}; my $err; my $blocking; $blocking = $sock->blocking(0) if $timeout; if (!connect($sock, $addr)) { if (defined $timeout && ($!{EINPROGRESS} || $!{EWOULDBLOCK})) { require IO::Select; my $sel = new IO::Select $sock; undef $!; my($r,$w,$e) = IO::Select::select(undef,$sel,$sel,$timeout); if(@$e[0]) { # Windows return from select after the timeout in case of # WSAECONNREFUSED(10061) if exception set is not used. # This behavior is different from Linux. # Using the exception # set we now emulate the behavior in Linux # - Karthik Rajagopalan $err = $sock->getsockopt(SOL_SOCKET,SO_ERROR); $@ = "connect: $err"; } elsif(!@$w[0]) { $err = $! || (exists &Errno::ETIMEDOUT ? &Errno::ETIMEDOUT : 1); $@ = "connect: timeout"; } elsif (!connect($sock,$addr) && not ($!{EISCONN} || ($^O eq 'MSWin32' && ($! == (($] < 5.019004) ? 10022 : Errno::EINVAL)))) ) { # Some systems refuse to re-connect() to # an already open socket and set errno to EISCONN. # Windows sets errno to WSAEINVAL (10022) (pre-5.19.4) or # EINVAL (22) (5.19.4 onwards). $err = $!; $@ = "connect: $!"; } } elsif ($blocking || !($!{EINPROGRESS} || $!{EWOULDBLOCK})) { $err = $!; $@ = "connect: $!"; } } $sock->blocking(1) if $blocking; $! = $err if $err; $err ? undef : $sock; } # Enable/disable blocking IO on sockets. # Without args return the current status of blocking, # with args change the mode as appropriate, returning the # old setting, or in case of error during the mode change # undef. sub blocking { my $sock = shift; return $sock->SUPER::blocking(@_) if $^O ne 'MSWin32' && $^O ne 'VMS'; # Windows handles blocking differently # # http://groups.google.co.uk/group/perl.perl5.porters/browse_thread/thread/b4e2b1d88280ddff/630b667a66e3509f?#630b667a66e3509f # http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/ioctlsocket_2.asp # # 0x8004667e is FIONBIO # # which is used to set blocking behaviour. # NOTE: # This is a little confusing, the perl keyword for this is # 'blocking' but the OS level behaviour is 'non-blocking', probably # because sockets are blocking by default. # Therefore internally we have to reverse the semantics. my $orig= !${*$sock}{io_sock_nonblocking}; return $orig unless @_; my $block = shift; if ( !$block != !$orig ) { ${*$sock}{io_sock_nonblocking} = $block ? 0 : 1; ioctl($sock, 0x8004667e, pack("L!",${*$sock}{io_sock_nonblocking})) or return undef; } return $orig; } sub close { @_ == 1 or croak 'usage: $sock->close()'; my $sock = shift; ${*$sock}{'io_socket_peername'} = undef; $sock->SUPER::close(); } sub bind { @_ == 2 or croak 'usage: $sock->bind(NAME)'; my $sock = shift; my $addr = shift; return bind($sock, $addr) ? $sock : undef; } sub listen { @_ >= 1 && @_ <= 2 or croak 'usage: $sock->listen([QUEUE])'; my($sock,$queue) = @_; $queue = 5 unless $queue && $queue > 0; return listen($sock, $queue) ? $sock : undef; } sub accept { @_ == 1 || @_ == 2 or croak 'usage $sock->accept([PKG])'; my $sock = shift; my $pkg = shift || $sock; my $timeout = ${*$sock}{'io_socket_timeout'}; my $new = $pkg->new(Timeout => $timeout); my $peer = undef; if(defined $timeout) { require IO::Select; my $sel = new IO::Select $sock; unless ($sel->can_read($timeout)) { $@ = 'accept: timeout'; $! = (exists &Errno::ETIMEDOUT ? &Errno::ETIMEDOUT : 1); return; } } $peer = accept($new,$sock) or return; ${*$new}{$_} = ${*$sock}{$_} for qw( io_socket_domain io_socket_type io_socket_proto ); return wantarray ? ($new, $peer) : $new; } sub sockname { @_ == 1 or croak 'usage: $sock->sockname()'; getsockname($_[0]); } sub peername { @_ == 1 or croak 'usage: $sock->peername()'; my($sock) = @_; ${*$sock}{'io_socket_peername'} ||= getpeername($sock); } sub connected { @_ == 1 or croak 'usage: $sock->connected()'; my($sock) = @_; getpeername($sock); } sub send { @_ >= 2 && @_ <= 4 or croak 'usage: $sock->send(BUF, [FLAGS, [TO]])'; my $sock = $_[0]; my $flags = $_[2] || 0; my $peer = $_[3] || $sock->peername; croak 'send: Cannot determine peer address' unless(defined $peer); my $r = defined(getpeername($sock)) ? send($sock, $_[1], $flags) : send($sock, $_[1], $flags, $peer); # remember who we send to, if it was successful ${*$sock}{'io_socket_peername'} = $peer if(@_ == 4 && defined $r); $r; } sub recv { @_ == 3 || @_ == 4 or croak 'usage: $sock->recv(BUF, LEN [, FLAGS])'; my $sock = $_[0]; my $len = $_[2]; my $flags = $_[3] || 0; # remember who we recv'd from ${*$sock}{'io_socket_peername'} = recv($sock, $_[1]='', $len, $flags); } sub shutdown { @_ == 2 or croak 'usage: $sock->shutdown(HOW)'; my($sock, $how) = @_; ${*$sock}{'io_socket_peername'} = undef; shutdown($sock, $how); } sub setsockopt { @_ == 4 or croak '$sock->setsockopt(LEVEL, OPTNAME, OPTVAL)'; setsockopt($_[0],$_[1],$_[2],$_[3]); } my $intsize = length(pack("i",0)); sub getsockopt { @_ == 3 or croak '$sock->getsockopt(LEVEL, OPTNAME)'; my $r = getsockopt($_[0],$_[1],$_[2]); # Just a guess $r = unpack("i", $r) if(defined $r && length($r) == $intsize); $r; } sub sockopt { my $sock = shift; @_ == 1 ? $sock->getsockopt(SOL_SOCKET,@_) : $sock->setsockopt(SOL_SOCKET,@_); } sub atmark { @_ == 1 or croak 'usage: $sock->atmark()'; my($sock) = @_; sockatmark($sock); } sub timeout { @_ == 1 || @_ == 2 or croak 'usage: $sock->timeout([VALUE])'; my($sock,$val) = @_; my $r = ${*$sock}{'io_socket_timeout'}; ${*$sock}{'io_socket_timeout'} = defined $val ? 0 + $val : $val if(@_ == 2); $r; } sub sockdomain { @_ == 1 or croak 'usage: $sock->sockdomain()'; my $sock = shift; if (!defined(${*$sock}{'io_socket_domain'})) { my $addr = $sock->sockname(); ${*$sock}{'io_socket_domain'} = sockaddr_family($addr) if (defined($addr)); } ${*$sock}{'io_socket_domain'}; } sub socktype { @_ == 1 or croak 'usage: $sock->socktype()'; my $sock = shift; ${*$sock}{'io_socket_type'} = $sock->sockopt(Socket::SO_TYPE) if (!defined(${*$sock}{'io_socket_type'}) && defined(eval{Socket::SO_TYPE})); ${*$sock}{'io_socket_type'} } sub protocol { @_ == 1 or croak 'usage: $sock->protocol()'; my($sock) = @_; ${*$sock}{'io_socket_proto'} = $sock->sockopt(Socket::SO_PROTOCOL) if (!defined(${*$sock}{'io_socket_proto'}) && defined(eval{Socket::SO_PROTOCOL})); ${*$sock}{'io_socket_proto'}; } 1; __END__ =head1 NAME IO::Socket - Object interface to socket communications =head1 SYNOPSIS use IO::Socket; =head1 DESCRIPTION C provides an object interface to creating and using sockets. It is built upon the L interface and inherits all the methods defined by L. C only defines methods for those operations which are common to all types of socket. Operations which are specified to a socket in a particular domain have methods defined in sub classes of C C will export all functions (and constants) defined by L. =head1 CONSTRUCTOR =over 4 =item new ( [ARGS] ) Creates an C, which is a reference to a newly created symbol (see the C package). C optionally takes arguments, these arguments are in key-value pairs. C only looks for one key C which tells new which domain the socket will be in. All other arguments will be passed to the configuration method of the package for that domain, See below. NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE As of VERSION 1.18 all IO::Socket objects have autoflush turned on by default. This was not the case with earlier releases. NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE =back =head1 METHODS See L for complete descriptions of each of the following supported C methods, which are just front ends for the corresponding built-in functions: socket socketpair bind listen accept send recv peername (getpeername) sockname (getsockname) shutdown Some methods take slightly different arguments to those defined in L in attempt to make the interface more flexible. These are =over 4 =item accept([PKG]) perform the system call C on the socket and return a new object. The new object will be created in the same class as the listen socket, unless C is specified. This object can be used to communicate with the client that was trying to connect. In a scalar context the new socket is returned, or undef upon failure. In a list context a two-element array is returned containing the new socket and the peer address; the list will be empty upon failure. The timeout in the [PKG] can be specified as zero to effect a "poll", but you shouldn't do that because a new IO::Select object will be created behind the scenes just to do the single poll. This is horrendously inefficient. Use rather true select() with a zero timeout on the handle, or non-blocking IO. =item socketpair(DOMAIN, TYPE, PROTOCOL) Call C and return a list of two sockets created, or an empty list on failure. =back Additional methods that are provided are: =over 4 =item atmark True if the socket is currently positioned at the urgent data mark, false otherwise. use IO::Socket; my $sock = IO::Socket::INET->new('some_server'); $sock->read($data, 1024) until $sock->atmark; Note: this is a reasonably new addition to the family of socket functions, so all systems may not support this yet. If it is unsupported by the system, an attempt to use this method will abort the program. The atmark() functionality is also exportable as sockatmark() function: use IO::Socket 'sockatmark'; This allows for a more traditional use of sockatmark() as a procedural socket function. If your system does not support sockatmark(), the C declaration will fail at compile time. =item connected If the socket is in a connected state, the peer address is returned. If the socket is not in a connected state, undef is returned. Note that connected() considers a half-open TCP socket to be "in a connected state". Specifically, connected() does not distinguish between the B and B TCP states; it returns the peer address, rather than undef, in either case. Thus, in general, connected() cannot be used to reliably learn whether the peer has initiated a graceful shutdown because in most cases (see below) the local TCP state machine remains in B until the local application calls shutdown() or close(); only at that point does connected() return undef. The "in most cases" hedge is because local TCP state machine behavior may depend on the peer's socket options. In particular, if the peer socket has SO_LINGER enabled with a zero timeout, then the peer's close() will generate a RST segment, upon receipt of which the local TCP transitions immediately to B, and in that state, connected() I return undef. =item protocol Returns the numerical number for the protocol being used on the socket, if known. If the protocol is unknown, as with an AF_UNIX socket, zero is returned. =item sockdomain Returns the numerical number for the socket domain type. For example, for an AF_INET socket the value of &AF_INET will be returned. =item sockopt(OPT [, VAL]) Unified method to both set and get options in the SOL_SOCKET level. If called with one argument then getsockopt is called, otherwise setsockopt is called. =item getsockopt(LEVEL, OPT) Get option associated with the socket. Other levels than SOL_SOCKET may be specified here. =item setsockopt(LEVEL, OPT, VAL) Set option associated with the socket. Other levels than SOL_SOCKET may be specified here. =item socktype Returns the numerical number for the socket type. For example, for a SOCK_STREAM socket the value of &SOCK_STREAM will be returned. =item timeout([VAL]) Set or get the timeout value (in seconds) associated with this socket. If called without any arguments then the current setting is returned. If called with an argument the current setting is changed and the previous value returned. =back =head1 LIMITATIONS On some systems, for an IO::Socket object created with new_from_fd(), or created with accept() from such an object, the protocol(), sockdomain() and socktype() methods may return undef. =head1 SEE ALSO L, L, L, L =head1 AUTHOR Graham Barr. atmark() by Lincoln Stein. Currently maintained by the Perl Porters. Please report all bugs to . =head1 COPYRIGHT Copyright (c) 1997-8 Graham Barr . All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. The atmark() implementation: Copyright 2001, Lincoln Stein . This module is distributed under the same terms as Perl itself. Feel free to use, modify and redistribute it as long as you retain the correct attribution. =cut PKRp] )CC Handle.pmnu[package IO::Handle; =head1 NAME IO::Handle - supply object methods for I/O handles =head1 SYNOPSIS use IO::Handle; $io = IO::Handle->new(); if ($io->fdopen(fileno(STDIN),"r")) { print $io->getline; $io->close; } $io = IO::Handle->new(); if ($io->fdopen(fileno(STDOUT),"w")) { $io->print("Some text\n"); } # setvbuf is not available by default on Perls 5.8.0 and later. use IO::Handle '_IOLBF'; $io->setvbuf($buffer_var, _IOLBF, 1024); undef $io; # automatically closes the file if it's open autoflush STDOUT 1; =head1 DESCRIPTION C is the base class for all other IO handle classes. It is not intended that objects of C would be created directly, but instead C is inherited from by several other classes in the IO hierarchy. If you are reading this documentation, looking for a replacement for the C package, then I suggest you read the documentation for C too. =head1 CONSTRUCTOR =over 4 =item new () Creates a new C object. =item new_from_fd ( FD, MODE ) Creates an C like C does. It requires two parameters, which are passed to the method C; if the fdopen fails, the object is destroyed. Otherwise, it is returned to the caller. =back =head1 METHODS See L for complete descriptions of each of the following supported C methods, which are just front ends for the corresponding built-in functions: $io->close $io->eof $io->fcntl( FUNCTION, SCALAR ) $io->fileno $io->format_write( [FORMAT_NAME] ) $io->getc $io->ioctl( FUNCTION, SCALAR ) $io->read ( BUF, LEN, [OFFSET] ) $io->print ( ARGS ) $io->printf ( FMT, [ARGS] ) $io->say ( ARGS ) $io->stat $io->sysread ( BUF, LEN, [OFFSET] ) $io->syswrite ( BUF, [LEN, [OFFSET]] ) $io->truncate ( LEN ) See L for complete descriptions of each of the following supported C methods. All of them return the previous value of the attribute and takes an optional single argument that when given will set the value. If no argument is given the previous value is unchanged (except for $io->autoflush will actually turn ON autoflush by default). $io->autoflush ( [BOOL] ) $| $io->format_page_number( [NUM] ) $% $io->format_lines_per_page( [NUM] ) $= $io->format_lines_left( [NUM] ) $- $io->format_name( [STR] ) $~ $io->format_top_name( [STR] ) $^ $io->input_line_number( [NUM]) $. The following methods are not supported on a per-filehandle basis. IO::Handle->format_line_break_characters( [STR] ) $: IO::Handle->format_formfeed( [STR]) $^L IO::Handle->output_field_separator( [STR] ) $, IO::Handle->output_record_separator( [STR] ) $\ IO::Handle->input_record_separator( [STR] ) $/ Furthermore, for doing normal I/O you might need these: =over 4 =item $io->fdopen ( FD, MODE ) C is like an ordinary C except that its first parameter is not a filename but rather a file handle name, an IO::Handle object, or a file descriptor number. (For the documentation of the C method, see L.) =item $io->opened Returns true if the object is currently a valid file descriptor, false otherwise. =item $io->getline This works like <$io> described in L except that it's more readable and can be safely called in a list context but still returns just one line. If used as the conditional within a C or C-style C loop, however, you will need to emulate the functionality of <$io> with C<< defined($_ = $io->getline) >>. =item $io->getlines This works like <$io> when called in a list context to read all the remaining lines in a file, except that it's more readable. It will also croak() if accidentally called in a scalar context. =item $io->ungetc ( ORD ) Pushes a character with the given ordinal value back onto the given handle's input stream. Only one character of pushback per handle is guaranteed. =item $io->write ( BUF, LEN [, OFFSET ] ) This C is somewhat like C found in C, in that it is the opposite of read. The wrapper for the perl C function is called C. However, whilst the C C function returns the number of bytes written, this C function simply returns true if successful (like C). A more C-like C is C (see above). =item $io->error Returns a true value if the given handle has experienced any errors since it was opened or since the last call to C, or if the handle is invalid. It only returns false for a valid handle with no outstanding errors. =item $io->clearerr Clear the given handle's error indicator. Returns -1 if the handle is invalid, 0 otherwise. =item $io->sync C synchronizes a file's in-memory state with that on the physical medium. C does not operate at the perlio api level, but operates on the file descriptor (similar to sysread, sysseek and systell). This means that any data held at the perlio api level will not be synchronized. To synchronize data that is buffered at the perlio api level you must use the flush method. C is not implemented on all platforms. Returns "0 but true" on success, C on error, C for an invalid handle. See L. =item $io->flush C causes perl to flush any buffered data at the perlio api level. Any unread data in the buffer will be discarded, and any unwritten data will be written to the underlying file descriptor. Returns "0 but true" on success, C on error. =item $io->printflush ( ARGS ) Turns on autoflush, print ARGS and then restores the autoflush status of the C object. Returns the return value from print. =item $io->blocking ( [ BOOL ] ) If called with an argument C will turn on non-blocking IO if C is false, and turn it off if C is true. C will return the value of the previous setting, or the current setting if C is not given. If an error occurs C will return undef and C<$!> will be set. =back If the C functions setbuf() and/or setvbuf() are available, then C and C set the buffering policy for an IO::Handle. The calling sequences for the Perl functions are the same as their C counterparts--including the constants C<_IOFBF>, C<_IOLBF>, and C<_IONBF> for setvbuf()--except that the buffer parameter specifies a scalar variable to use as a buffer. You should only change the buffer before any I/O, or immediately after calling flush. WARNING: The IO::Handle::setvbuf() is not available by default on Perls 5.8.0 and later because setvbuf() is rather specific to using the stdio library, while Perl prefers the new perlio subsystem instead. WARNING: A variable used as a buffer by C or C B in any way until the IO::Handle is closed or C or C is called again, or memory corruption may result! Remember that the order of global destruction is undefined, so even if your buffer variable remains in scope until program termination, it may be undefined before the file IO::Handle is closed. Note that you need to import the constants C<_IOFBF>, C<_IOLBF>, and C<_IONBF> explicitly. Like C, setbuf returns nothing. setvbuf returns "0 but true", on success, C on failure. Lastly, there is a special method for working under B<-T> and setuid/gid scripts: =over 4 =item $io->untaint Marks the object as taint-clean, and as such data read from it will also be considered taint-clean. Note that this is a very trusting action to take, and appropriate consideration for the data source and potential vulnerability should be kept in mind. Returns 0 on success, -1 if setting the taint-clean flag failed. (eg invalid handle) =back =head1 NOTE An C object is a reference to a symbol/GLOB reference (see the C package). Some modules that inherit from C may want to keep object related variables in the hash table part of the GLOB. In an attempt to prevent modules trampling on each other I propose the that any such module should prefix its variables with its own name separated by _'s. For example the IO::Socket module keeps a C variable in 'io_socket_timeout'. =head1 SEE ALSO L, L, L =head1 BUGS Due to backwards compatibility, all filehandles resemble objects of class C, or actually classes derived from that class. They actually aren't. Which means you can't derive your own class from C and inherit those methods. =head1 HISTORY Derived from FileHandle.pm by Graham Barr EFE =cut use 5.006_001; use strict; our($VERSION, @EXPORT_OK, @ISA); use Carp; use Symbol; use SelectSaver; use IO (); # Load the XS module require Exporter; @ISA = qw(Exporter); $VERSION = "1.36"; $VERSION = eval $VERSION; @EXPORT_OK = qw( autoflush output_field_separator output_record_separator input_record_separator input_line_number format_page_number format_lines_per_page format_lines_left format_name format_top_name format_line_break_characters format_formfeed format_write print printf say getline getlines printflush flush SEEK_SET SEEK_CUR SEEK_END _IOFBF _IOLBF _IONBF ); ################################################ ## Constructors, destructors. ## sub new { my $class = ref($_[0]) || $_[0] || "IO::Handle"; if (@_ != 1) { # Since perl will automatically require IO::File if needed, but # also initialises IO::File's @ISA as part of the core we must # ensure IO::File is loaded if IO::Handle is. This avoids effect- # ively "half-loading" IO::File. if ($] > 5.013 && $class eq 'IO::File' && !$INC{"IO/File.pm"}) { require IO::File; shift; return IO::File::->new(@_); } croak "usage: $class->new()"; } my $io = gensym; bless $io, $class; } sub new_from_fd { my $class = ref($_[0]) || $_[0] || "IO::Handle"; @_ == 3 or croak "usage: $class->new_from_fd(FD, MODE)"; my $io = gensym; shift; IO::Handle::fdopen($io, @_) or return undef; bless $io, $class; } # # There is no need for DESTROY to do anything, because when the # last reference to an IO object is gone, Perl automatically # closes its associated files (if any). However, to avoid any # attempts to autoload DESTROY, we here define it to do nothing. # sub DESTROY {} ################################################ ## Open and close. ## sub _open_mode_string { my ($mode) = @_; $mode =~ /^\+?(<|>>?)$/ or $mode =~ s/^r(\+?)$/$1/ or $mode =~ s/^a(\+?)$/$1>>/ or croak "IO::Handle: bad open mode: $mode"; $mode; } sub fdopen { @_ == 3 or croak 'usage: $io->fdopen(FD, MODE)'; my ($io, $fd, $mode) = @_; local(*GLOB); if (ref($fd) && "".$fd =~ /GLOB\(/o) { # It's a glob reference; Alias it as we cannot get name of anon GLOBs my $n = qualify(*GLOB); *GLOB = *{*$fd}; $fd = $n; } elsif ($fd =~ m#^\d+$#) { # It's an FD number; prefix with "=". $fd = "=$fd"; } open($io, _open_mode_string($mode) . '&' . $fd) ? $io : undef; } sub close { @_ == 1 or croak 'usage: $io->close()'; my($io) = @_; close($io); } ################################################ ## Normal I/O functions. ## # flock # select sub opened { @_ == 1 or croak 'usage: $io->opened()'; defined fileno($_[0]); } sub fileno { @_ == 1 or croak 'usage: $io->fileno()'; fileno($_[0]); } sub getc { @_ == 1 or croak 'usage: $io->getc()'; getc($_[0]); } sub eof { @_ == 1 or croak 'usage: $io->eof()'; eof($_[0]); } sub print { @_ or croak 'usage: $io->print(ARGS)'; my $this = shift; print $this @_; } sub printf { @_ >= 2 or croak 'usage: $io->printf(FMT,[ARGS])'; my $this = shift; printf $this @_; } sub say { @_ or croak 'usage: $io->say(ARGS)'; my $this = shift; local $\ = "\n"; print $this @_; } # Special XS wrapper to make them inherit lexical hints from the caller. _create_getline_subs( <<'END' ) or die $@; sub getline { @_ == 1 or croak 'usage: $io->getline()'; my $this = shift; return scalar <$this>; } sub getlines { @_ == 1 or croak 'usage: $io->getlines()'; wantarray or croak 'Can\'t call $io->getlines in a scalar context, use $io->getline'; my $this = shift; return <$this>; } 1; # return true for error checking END *gets = \&getline; # deprecated sub truncate { @_ == 2 or croak 'usage: $io->truncate(LEN)'; truncate($_[0], $_[1]); } sub read { @_ == 3 || @_ == 4 or croak 'usage: $io->read(BUF, LEN [, OFFSET])'; read($_[0], $_[1], $_[2], $_[3] || 0); } sub sysread { @_ == 3 || @_ == 4 or croak 'usage: $io->sysread(BUF, LEN [, OFFSET])'; sysread($_[0], $_[1], $_[2], $_[3] || 0); } sub write { @_ >= 2 && @_ <= 4 or croak 'usage: $io->write(BUF [, LEN [, OFFSET]])'; local($\) = ""; $_[2] = length($_[1]) unless defined $_[2]; print { $_[0] } substr($_[1], $_[3] || 0, $_[2]); } sub syswrite { @_ >= 2 && @_ <= 4 or croak 'usage: $io->syswrite(BUF [, LEN [, OFFSET]])'; if (defined($_[2])) { syswrite($_[0], $_[1], $_[2], $_[3] || 0); } else { syswrite($_[0], $_[1]); } } sub stat { @_ == 1 or croak 'usage: $io->stat()'; stat($_[0]); } ################################################ ## State modification functions. ## sub autoflush { my $old = new SelectSaver qualify($_[0], caller); my $prev = $|; $| = @_ > 1 ? $_[1] : 1; $prev; } sub output_field_separator { carp "output_field_separator is not supported on a per-handle basis" if ref($_[0]); my $prev = $,; $, = $_[1] if @_ > 1; $prev; } sub output_record_separator { carp "output_record_separator is not supported on a per-handle basis" if ref($_[0]); my $prev = $\; $\ = $_[1] if @_ > 1; $prev; } sub input_record_separator { carp "input_record_separator is not supported on a per-handle basis" if ref($_[0]); my $prev = $/; $/ = $_[1] if @_ > 1; $prev; } sub input_line_number { local $.; () = tell qualify($_[0], caller) if ref($_[0]); my $prev = $.; $. = $_[1] if @_ > 1; $prev; } sub format_page_number { my $old; $old = new SelectSaver qualify($_[0], caller) if ref($_[0]); my $prev = $%; $% = $_[1] if @_ > 1; $prev; } sub format_lines_per_page { my $old; $old = new SelectSaver qualify($_[0], caller) if ref($_[0]); my $prev = $=; $= = $_[1] if @_ > 1; $prev; } sub format_lines_left { my $old; $old = new SelectSaver qualify($_[0], caller) if ref($_[0]); my $prev = $-; $- = $_[1] if @_ > 1; $prev; } sub format_name { my $old; $old = new SelectSaver qualify($_[0], caller) if ref($_[0]); my $prev = $~; $~ = qualify($_[1], caller) if @_ > 1; $prev; } sub format_top_name { my $old; $old = new SelectSaver qualify($_[0], caller) if ref($_[0]); my $prev = $^; $^ = qualify($_[1], caller) if @_ > 1; $prev; } sub format_line_break_characters { carp "format_line_break_characters is not supported on a per-handle basis" if ref($_[0]); my $prev = $:; $: = $_[1] if @_ > 1; $prev; } sub format_formfeed { carp "format_formfeed is not supported on a per-handle basis" if ref($_[0]); my $prev = $^L; $^L = $_[1] if @_ > 1; $prev; } sub formline { my $io = shift; my $picture = shift; local($^A) = $^A; local($\) = ""; formline($picture, @_); print $io $^A; } sub format_write { @_ < 3 || croak 'usage: $io->write( [FORMAT_NAME] )'; if (@_ == 2) { my ($io, $fmt) = @_; my $oldfmt = $io->format_name(qualify($fmt,caller)); CORE::write($io); $io->format_name($oldfmt); } else { CORE::write($_[0]); } } sub fcntl { @_ == 3 || croak 'usage: $io->fcntl( OP, VALUE );'; my ($io, $op) = @_; return fcntl($io, $op, $_[2]); } sub ioctl { @_ == 3 || croak 'usage: $io->ioctl( OP, VALUE );'; my ($io, $op) = @_; return ioctl($io, $op, $_[2]); } # this sub is for compatibility with older releases of IO that used # a sub called constant to determine if a constant existed -- GMB # # The SEEK_* and _IO?BF constants were the only constants at that time # any new code should just check defined(&CONSTANT_NAME) sub constant { no strict 'refs'; my $name = shift; (($name =~ /^(SEEK_(SET|CUR|END)|_IO[FLN]BF)$/) && defined &{$name}) ? &{$name}() : undef; } # so that flush.pl can be deprecated sub printflush { my $io = shift; my $old; $old = new SelectSaver qualify($io, caller) if ref($io); local $| = 1; if(ref($io)) { print $io @_; } else { print @_; } } 1; PKRp]3Y8 Select.pmnu[# IO::Select.pm # # Copyright (c) 1997-8 Graham Barr . All rights reserved. # This program is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. package IO::Select; use strict; use warnings::register; use vars qw($VERSION @ISA); require Exporter; $VERSION = "1.22"; @ISA = qw(Exporter); # This is only so we can do version checking sub VEC_BITS () {0} sub FD_COUNT () {1} sub FIRST_FD () {2} sub new { my $self = shift; my $type = ref($self) || $self; my $vec = bless [undef,0], $type; $vec->add(@_) if @_; $vec; } sub add { shift->_update('add', @_); } sub remove { shift->_update('remove', @_); } sub exists { my $vec = shift; my $fno = $vec->_fileno(shift); return undef unless defined $fno; $vec->[$fno + FIRST_FD]; } sub _fileno { my($self, $f) = @_; return unless defined $f; $f = $f->[0] if ref($f) eq 'ARRAY'; ($f =~ /^\d+$/) ? $f : fileno($f); } sub _update { my $vec = shift; my $add = shift eq 'add'; my $bits = $vec->[VEC_BITS]; $bits = '' unless defined $bits; my $count = 0; my $f; foreach $f (@_) { my $fn = $vec->_fileno($f); if ($add) { next unless defined $fn; my $i = $fn + FIRST_FD; if (defined $vec->[$i]) { $vec->[$i] = $f; # if array rest might be different, so we update next; } $vec->[FD_COUNT]++; vec($bits, $fn, 1) = 1; $vec->[$i] = $f; } else { # remove if ( ! defined $fn ) { # remove if fileno undef'd $fn = 0; for my $fe (@{$vec}[FIRST_FD .. $#$vec]) { if (defined($fe) && $fe == $f) { $vec->[FD_COUNT]--; $fe = undef; vec($bits, $fn, 1) = 0; last; } ++$fn; } } else { my $i = $fn + FIRST_FD; next unless defined $vec->[$i]; $vec->[FD_COUNT]--; vec($bits, $fn, 1) = 0; $vec->[$i] = undef; } } $count++; } $vec->[VEC_BITS] = $vec->[FD_COUNT] ? $bits : undef; $count; } sub can_read { my $vec = shift; my $timeout = shift; my $r = $vec->[VEC_BITS]; defined($r) && (select($r,undef,undef,$timeout) > 0) ? handles($vec, $r) : (); } sub can_write { my $vec = shift; my $timeout = shift; my $w = $vec->[VEC_BITS]; defined($w) && (select(undef,$w,undef,$timeout) > 0) ? handles($vec, $w) : (); } sub has_exception { my $vec = shift; my $timeout = shift; my $e = $vec->[VEC_BITS]; defined($e) && (select(undef,undef,$e,$timeout) > 0) ? handles($vec, $e) : (); } sub has_error { warnings::warn("Call to deprecated method 'has_error', use 'has_exception'") if warnings::enabled(); goto &has_exception; } sub count { my $vec = shift; $vec->[FD_COUNT]; } sub bits { my $vec = shift; $vec->[VEC_BITS]; } sub as_string # for debugging { my $vec = shift; my $str = ref($vec) . ": "; my $bits = $vec->bits; my $count = $vec->count; $str .= defined($bits) ? unpack("b*", $bits) : "undef"; $str .= " $count"; my @handles = @$vec; splice(@handles, 0, FIRST_FD); for (@handles) { $str .= " " . (defined($_) ? "$_" : "-"); } $str; } sub _max { my($a,$b,$c) = @_; $a > $b ? $a > $c ? $a : $c : $b > $c ? $b : $c; } sub select { shift if defined $_[0] && !ref($_[0]); my($r,$w,$e,$t) = @_; my @result = (); my $rb = defined $r ? $r->[VEC_BITS] : undef; my $wb = defined $w ? $w->[VEC_BITS] : undef; my $eb = defined $e ? $e->[VEC_BITS] : undef; if(select($rb,$wb,$eb,$t) > 0) { my @r = (); my @w = (); my @e = (); my $i = _max(defined $r ? scalar(@$r)-1 : 0, defined $w ? scalar(@$w)-1 : 0, defined $e ? scalar(@$e)-1 : 0); for( ; $i >= FIRST_FD ; $i--) { my $j = $i - FIRST_FD; push(@r, $r->[$i]) if defined $rb && defined $r->[$i] && vec($rb, $j, 1); push(@w, $w->[$i]) if defined $wb && defined $w->[$i] && vec($wb, $j, 1); push(@e, $e->[$i]) if defined $eb && defined $e->[$i] && vec($eb, $j, 1); } @result = (\@r, \@w, \@e); } @result; } sub handles { my $vec = shift; my $bits = shift; my @h = (); my $i; my $max = scalar(@$vec) - 1; for ($i = FIRST_FD; $i <= $max; $i++) { next unless defined $vec->[$i]; push(@h, $vec->[$i]) if !defined($bits) || vec($bits, $i - FIRST_FD, 1); } @h; } 1; __END__ =head1 NAME IO::Select - OO interface to the select system call =head1 SYNOPSIS use IO::Select; $s = IO::Select->new(); $s->add(\*STDIN); $s->add($some_handle); @ready = $s->can_read($timeout); @ready = IO::Select->new(@handles)->can_read(0); =head1 DESCRIPTION The C package implements an object approach to the system C static method. =item bits() Return the bit string suitable as argument to the core select() call. =item select ( READ, WRITE, EXCEPTION [, TIMEOUT ] ) C or C). Each time the filehandle is ready to write, the C method must be called, with no arguments. Note that some operating systems, most notably C do not report a C failure using write-ready; so you must also C for exceptional status. While C returns false, the value of C<$!> indicates whether it should be tried again (by being set to the value C, or C on MSWin32), or whether a permanent error has occurred (e.g. C). Once the socket has been connected to the peer, C will return true and the socket will now be ready to use. Note that calls to the platform's underlying C function may block. If C has to perform this lookup, the constructor will block even when in non-blocking mode. To avoid this blocking behaviour, the caller should pass in the result of such a lookup using the C or C arguments. This can be achieved by using L, or the C function can be called in a child process. use IO::Socket::IP; use Errno qw( EINPROGRESS EWOULDBLOCK ); my @peeraddrinfo = ... # Caller must obtain the getaddinfo result here my $socket = IO::Socket::IP->new( PeerAddrInfo => \@peeraddrinfo, Blocking => 0, ) or die "Cannot construct socket - $@"; while( !$socket->connect and ( $! == EINPROGRESS || $! == EWOULDBLOCK ) ) { my $wvec = ''; vec( $wvec, fileno $socket, 1 ) = 1; my $evec = ''; vec( $evec, fileno $socket, 1 ) = 1; select( undef, $wvec, $evec, undef ) or die "Cannot select - $!"; } die "Cannot connect - $!" if $!; ... The example above uses C, but any similar mechanism should work analogously. C takes care when creating new socket filehandles to preserve the actual file descriptor number, so such techniques as C or C should be transparent to its reallocation of a different socket underneath, perhaps in order to switch protocol family between C and C. For another example using C and C, see the F file in the module distribution. =cut =head1 C AND C PARSING To support the C API, the host and port information may be passed in a single string rather than as two separate arguments. If either C or C (or their C<...Addr> synonyms) have any of the following special forms then special parsing is applied. The value of the C<...Host> argument will be split to give both the hostname and port (or service name): hostname.example.org:http # Host name 192.0.2.1:80 # IPv4 address [2001:db8::1]:80 # IPv6 address In each case, the port or service name (e.g. C<80>) is passed as the C or C argument. Either of C or C (or their C<...Port> synonyms) can be either a service name, a decimal number, or a string containing both a service name and number, in a form such as http(80) In this case, the name (C) will be tried first, but if the resolver does not understand it then the port number (C<80>) will be used instead. If the C<...Host> argument is in this special form and the corresponding C<...Service> or C<...Port> argument is also defined, the one parsed from the C<...Host> argument will take precedence and the other will be ignored. =head2 ( $host, $port ) = IO::Socket::IP->split_addr( $addr ) Utility method that provides the parsing functionality described above. Returns a 2-element list, containing either the split hostname and port description if it could be parsed, or the given address and C if it was not recognised. IO::Socket::IP->split_addr( "hostname:http" ) # ( "hostname", "http" ) IO::Socket::IP->split_addr( "192.0.2.1:80" ) # ( "192.0.2.1", "80" ) IO::Socket::IP->split_addr( "[2001:db8::1]:80" ) # ( "2001:db8::1", "80" ) IO::Socket::IP->split_addr( "something.else" ) # ( "something.else", undef ) =cut sub split_addr { shift; my ( $addr ) = @_; local ( $1, $2 ); # Placate a taint-related bug; [perl #67962] if( $addr =~ m/\A\[($IPv6_re)\](?::([^\s:]*))?\z/ or $addr =~ m/\A([^\s:]*):([^\s:]*)\z/ ) { return ( $1, $2 ) if defined $2 and length $2; return ( $1, undef ); } return ( $addr, undef ); } =head2 $addr = IO::Socket::IP->join_addr( $host, $port ) Utility method that performs the reverse of C, returning a string formed by joining the specified host address and port number. The host address will be wrapped in C<[]> brackets if required (because it is a raw IPv6 numeric address). This can be especially useful when combined with the C or C methods. say "Connected to ", IO::Socket::IP->join_addr( $sock->peerhost_service ); =cut sub join_addr { shift; my ( $host, $port ) = @_; $host = "[$host]" if $host =~ m/:/; return join ":", $host, $port if defined $port; return $host; } # Since IO::Socket->new( Domain => ... ) will delete the Domain parameter # before calling ->configure, we need to keep track of which it was package # hide from indexer IO::Socket::IP::_ForINET; use base qw( IO::Socket::IP ); sub configure { # This is evil my $self = shift; my ( $arg ) = @_; bless $self, "IO::Socket::IP"; $self->configure( { %$arg, Family => Socket::AF_INET() } ); } package # hide from indexer IO::Socket::IP::_ForINET6; use base qw( IO::Socket::IP ); sub configure { # This is evil my $self = shift; my ( $arg ) = @_; bless $self, "IO::Socket::IP"; $self->configure( { %$arg, Family => Socket::AF_INET6() } ); } =head1 C INCOMPATIBILITES =over 4 =item * The behaviour enabled by C is in fact implemented by C as it is required to correctly support searching for a useable address from the results of the C call. The constructor will ignore the value of this argument, except if it is defined but false. An exception is thrown in this case, because that would request it disable the C search behaviour in the first place. =item * C implements both the C and C parameters, but it implements the interaction of both in a different way. In C<::INET>, supplying a timeout overrides the non-blocking behaviour, meaning that the C operation will still block despite that the caller asked for a non-blocking socket. This is not explicitly specified in its documentation, nor does this author believe that is a useful behaviour - it appears to come from a quirk of implementation. In C<::IP> therefore, the C parameter takes precedence - if a non-blocking socket is requested, no operation will block. The C parameter here simply defines the maximum time that a blocking C call will wait, if it blocks at all. In order to specifically obtain the "blocking connect then non-blocking send and receive" behaviour of specifying this combination of options to C<::INET> when using C<::IP>, perform first a blocking connect, then afterwards turn the socket into nonblocking mode. my $sock = IO::Socket::IP->new( PeerHost => $peer, Timeout => 20, ) or die "Cannot connect - $@"; $sock->blocking( 0 ); This code will behave identically under both C and C. =back =cut =head1 TODO =over 4 =item * Investigate whether C upsets BSD's C watchers, and if so, consider what possible workarounds might be applied. =back =head1 AUTHOR Paul Evans =cut 0x55AA; PKH]F# Socket/SSL.pmnu[#vim: set sts=4 sw=4 ts=8 ai: # # IO::Socket::SSL: # provide an interface to SSL connections similar to IO::Socket modules # # Current Code Shepherd: Steffen Ullrich # Code Shepherd before: Peter Behroozi, # # The original version of this module was written by # Marko Asplund, , who drew from # Crypt::SSLeay (Net::SSL) by Gisle Aas. # package IO::Socket::SSL; our $VERSION = '2.066'; use IO::Socket; use Net::SSLeay 1.46; use IO::Socket::SSL::PublicSuffix; use Exporter (); use Errno qw( EWOULDBLOCK EAGAIN ETIMEDOUT EINTR EPIPE ); use Carp; use strict; my $use_threads; BEGIN { die "no support for weaken - please install Scalar::Util" if ! do { local $SIG{__DIE__}; eval { require Scalar::Util; Scalar::Util->import("weaken"); 1 } || eval { require WeakRef; WeakRef->import("weaken"); 1 } }; require Config; $use_threads = $Config::Config{usethreads}; } # results from commonly used constant functions from Net::SSLeay for fast access my $Net_SSLeay_ERROR_WANT_READ = Net::SSLeay::ERROR_WANT_READ(); my $Net_SSLeay_ERROR_WANT_WRITE = Net::SSLeay::ERROR_WANT_WRITE(); my $Net_SSLeay_ERROR_SYSCALL = Net::SSLeay::ERROR_SYSCALL(); my $Net_SSLeay_VERIFY_NONE = Net::SSLeay::VERIFY_NONE(); my $Net_SSLeay_VERIFY_PEER = Net::SSLeay::VERIFY_PEER(); use constant SSL_VERIFY_NONE => &Net::SSLeay::VERIFY_NONE; use constant SSL_VERIFY_PEER => &Net::SSLeay::VERIFY_PEER; use constant SSL_VERIFY_FAIL_IF_NO_PEER_CERT => Net::SSLeay::VERIFY_FAIL_IF_NO_PEER_CERT(); use constant SSL_VERIFY_CLIENT_ONCE => Net::SSLeay::VERIFY_CLIENT_ONCE(); # from openssl/ssl.h; should be better in Net::SSLeay use constant SSL_SENT_SHUTDOWN => 1; use constant SSL_RECEIVED_SHUTDOWN => 2; use constant SSL_OCSP_NO_STAPLE => 0b00001; use constant SSL_OCSP_MUST_STAPLE => 0b00010; use constant SSL_OCSP_FAIL_HARD => 0b00100; use constant SSL_OCSP_FULL_CHAIN => 0b01000; use constant SSL_OCSP_TRY_STAPLE => 0b10000; # capabilities of underlying Net::SSLeay/openssl my $can_client_sni; # do we support SNI on the client side my $can_server_sni; # do we support SNI on the server side my $can_multi_cert; # RSA and ECC certificate in same context my $can_npn; # do we support NPN (obsolete) my $can_alpn; # do we support ALPN my $can_ecdh; # do we support ECDH key exchange my $set_groups_list; # SSL_CTX_set1_groups_list || SSL_CTX_set1_curves_list || undef my $can_ocsp; # do we support OCSP my $can_ocsp_staple; # do we support OCSP stapling my $can_tckt_keycb; # TLS ticket key callback my $can_pha; # do we support PHA my $session_upref; # SSL_SESSION_up_ref is implemented my %sess_cb; # SSL_CTX_sess_set_(new|remove)_cb my $check_partial_chain; # use X509_V_FLAG_PARTIAL_CHAIN if available my $openssl_version; my $netssleay_version; BEGIN { $openssl_version = Net::SSLeay::OPENSSL_VERSION_NUMBER(); $netssleay_version = do { no warnings; $Net::SSLeay::VERSION + 0.0; }; $can_client_sni = $openssl_version >= 0x10000000; $can_server_sni = defined &Net::SSLeay::get_servername; $can_npn = defined &Net::SSLeay::P_next_proto_negotiated && ! Net::SSLeay::constant("LIBRESSL_VERSION_NUMBER"); # LibreSSL 2.6.1 disabled NPN by keeping the relevant functions # available but removed the actual functionality from these functions. $can_alpn = defined &Net::SSLeay::CTX_set_alpn_protos; $can_ecdh = ($openssl_version >= 0x1010000f) ? 'auto' : defined(&Net::SSLeay::CTX_set_ecdh_auto) ? 'can_auto' : (defined &Net::SSLeay::CTX_set_tmp_ecdh && # There is a regression with elliptic curves on 1.0.1d with 64bit # http://rt.openssl.org/Ticket/Display.html?id=2975 ( $openssl_version != 0x1000104f || length(pack("P",0)) == 4 )) ? 'tmp_ecdh' : ''; $set_groups_list = defined &Net::SSLeay::CTX_set1_groups_list ? \&Net::SSLeay::CTX_set1_groups_list : defined &Net::SSLeay::CTX_set1_curves_list ? \&Net::SSLeay::CTX_set1_curves_list : undef; $can_multi_cert = $can_ecdh && $openssl_version >= 0x10002000; $can_ocsp = defined &Net::SSLeay::OCSP_cert2ids # OCSP got broken in 1.75..1.77 && ($netssleay_version < 1.75 || $netssleay_version > 1.77); $can_ocsp_staple = $can_ocsp && defined &Net::SSLeay::set_tlsext_status_type; $can_tckt_keycb = defined &Net::SSLeay::CTX_set_tlsext_ticket_getkey_cb && $netssleay_version >= 1.80; $can_pha = defined &Net::SSLeay::CTX_set_post_handshake_auth; if (defined &Net::SSLeay::SESSION_up_ref) { $session_upref = 1; } if ($session_upref && defined &Net::SSLeay::CTX_sess_set_new_cb && defined &Net::SSLeay::CTX_sess_set_remove_cb) { %sess_cb = ( new => \&Net::SSLeay::CTX_sess_set_new_cb, remove => \&Net::SSLeay::CTX_sess_set_remove_cb, ); } if (my $c = defined &Net::SSLeay::CTX_get0_param && eval { Net::SSLeay::X509_V_FLAG_PARTIAL_CHAIN() }) { $check_partial_chain = sub { my $ctx = shift; my $param = Net::SSLeay::CTX_get0_param($ctx); Net::SSLeay::X509_VERIFY_PARAM_set_flags($param, $c); }; } } my $algo2digest = do { my %digest; sub { my $digest_name = shift; return $digest{$digest_name} ||= do { Net::SSLeay::SSLeay_add_ssl_algorithms(); Net::SSLeay::EVP_get_digestbyname($digest_name) or die "Digest algorithm $digest_name is not available"; }; } }; my $CTX_tlsv1_3_new; if ( defined &Net::SSLeay::CTX_set_min_proto_version and defined &Net::SSLeay::CTX_set_max_proto_version and my $tls13 = eval { Net::SSLeay::TLS1_3_VERSION() } ) { $CTX_tlsv1_3_new = sub { my $ctx = Net::SSLeay::CTX_new(); return $ctx if Net::SSLeay::CTX_set_min_proto_version($ctx,$tls13) && Net::SSLeay::CTX_set_max_proto_version($ctx,$tls13); Net::SSLeay::CTX_free($ctx); return; }; } # global defaults my %DEFAULT_SSL_ARGS = ( SSL_check_crl => 0, SSL_version => '', SSL_verify_callback => undef, SSL_verifycn_scheme => undef, # fallback cn verification SSL_verifycn_publicsuffix => undef, # fallback default list verification #SSL_verifycn_name => undef, # use from PeerAddr/PeerHost - do not override in set_args_filter_hack 'use_defaults' SSL_npn_protocols => undef, # meaning depends whether on server or client side SSL_alpn_protocols => undef, # list of protocols we'll accept/send, for example ['http/1.1','spdy/3.1'] # Use system-wide default cipher list to support use of system-wide # crypto policy (#1076390, #1127577, CPAN RT#97816) # https://fedoraproject.org/wiki/Changes/CryptoPolicy SSL_cipher_list => 'PROFILE=SYSTEM', ); my %DEFAULT_SSL_CLIENT_ARGS = ( %DEFAULT_SSL_ARGS, SSL_verify_mode => SSL_VERIFY_PEER, SSL_ca_file => undef, SSL_ca_path => undef, ); # set values inside _init to work with perlcc, RT#95452 my %DEFAULT_SSL_SERVER_ARGS; # Initialization of OpenSSL internals # This will be called once during compilation - perlcc users might need to # call it again by hand, see RT#95452 { sub init { # library_init returns false if the library was already initialized. # This way we can find out if the library needs to be re-initialized # inside code compiled with perlcc Net::SSLeay::library_init() or return; Net::SSLeay::load_error_strings(); Net::SSLeay::OpenSSL_add_all_digests(); Net::SSLeay::randomize(); %DEFAULT_SSL_SERVER_ARGS = ( %DEFAULT_SSL_ARGS, SSL_verify_mode => SSL_VERIFY_NONE, SSL_honor_cipher_order => 1, # trust server to know the best cipher SSL_dh => do { my $bio = Net::SSLeay::BIO_new(Net::SSLeay::BIO_s_mem()); # generated with: openssl dhparam 2048 Net::SSLeay::BIO_write($bio,<<'DH'); -----BEGIN DH PARAMETERS----- MIIBCAKCAQEAr8wskArj5+1VCVsnWt/RUR7tXkHJ7mGW7XxrLSPOaFyKyWf8lZht iSY2Lc4oa4Zw8wibGQ3faeQu/s8fvPq/aqTxYmyHPKCMoze77QJHtrYtJAosB9SY CN7s5Hexxb5/vQ4qlQuOkVrZDiZO9GC4KaH9mJYnCoAsXDhDft6JT0oRVSgtZQnU gWFKShIm+JVjN94kGs0TcBEesPTK2g8XVHK9H8AtSUb9BwW2qD/T5RmgNABysApO Ps2vlkxjAHjJcqc3O+OiImKik/X2rtBTZjpKmzN3WWTB0RJZCOWaLlDO81D01o1E aZecz3Np9KIYey900f+X7zC2bJxEHp95ywIBAg== -----END DH PARAMETERS----- DH my $dh = Net::SSLeay::PEM_read_bio_DHparams($bio); Net::SSLeay::BIO_free($bio); $dh or die "no DH"; $dh; }, ( $can_ecdh eq 'auto' ? () : # automatically enabled by openssl $can_ecdh eq 'can_auto' ? (SSL_ecdh_curve => 'auto') : $can_ecdh eq 'tmp_ecdh' ? ( SSL_ecdh_curve => 'prime256v1' ) : (), ) ); } # Call it once at compile time and try it at INIT. # This should catch all cases of including the module, e.g. 'use' (INIT) or # 'require' (compile time) and works also with perlcc { no warnings; INIT { init() } init(); } } # global defaults which can be changed using set_defaults # either key/value can be set or it can just be set to an external hash my $GLOBAL_SSL_ARGS = {}; my $GLOBAL_SSL_CLIENT_ARGS = {}; my $GLOBAL_SSL_SERVER_ARGS = {}; # hack which is used to filter bad settings from used modules my $FILTER_SSL_ARGS = undef; # non-XS Versions of Scalar::Util will fail BEGIN{ die "You need the XS Version of Scalar::Util for dualvar() support" if !do { local $SIG{__DIE__}; local $SIG{__WARN__}; # be silent eval { use Scalar::Util 'dualvar'; dualvar(0,''); 1 }; }; } # get constants for SSL_OP_NO_* now, instead calling the related functions # every time we setup a connection my %SSL_OP_NO; for(qw( SSLv2 SSLv3 TLSv1 TLSv1_1 TLSv11:TLSv1_1 TLSv1_2 TLSv12:TLSv1_2 TLSv1_3 TLSv13:TLSv1_3 )) { my ($k,$op) = m{:} ? split(m{:},$_,2) : ($_,$_); my $sub = "Net::SSLeay::OP_NO_$op"; local $SIG{__DIE__}; $SSL_OP_NO{$k} = eval { no strict 'refs'; &$sub } || 0; } # Make SSL_CTX_clear_options accessible through SSL_CTX_ctrl unless it is # already implemented in Net::SSLeay if (!defined &Net::SSLeay::CTX_clear_options) { *Net::SSLeay::CTX_clear_options = sub { my ($ctx,$opt) = @_; # 77 = SSL_CTRL_CLEAR_OPTIONS Net::SSLeay::CTX_ctrl($ctx,77,$opt,0); }; } # Try to work around problems with alternative trust path by default, RT#104759 my $DEFAULT_X509_STORE_flags = 0; { local $SIG{__DIE__}; eval { $DEFAULT_X509_STORE_flags |= Net::SSLeay::X509_V_FLAG_TRUSTED_FIRST() }; } our $DEBUG; use vars qw(@ISA $SSL_ERROR @EXPORT); { # These constants will be used in $! at return from SSL_connect, # SSL_accept, _generic_(read|write), thus notifying the caller # the usual way of problems. Like with EWOULDBLOCK, EINPROGRESS.. # these are especially important for non-blocking sockets my $x = $Net_SSLeay_ERROR_WANT_READ; use constant SSL_WANT_READ => dualvar( \$x, 'SSL wants a read first' ); my $y = $Net_SSLeay_ERROR_WANT_WRITE; use constant SSL_WANT_WRITE => dualvar( \$y, 'SSL wants a write first' ); @EXPORT = qw( SSL_WANT_READ SSL_WANT_WRITE SSL_VERIFY_NONE SSL_VERIFY_PEER SSL_VERIFY_FAIL_IF_NO_PEER_CERT SSL_VERIFY_CLIENT_ONCE SSL_OCSP_NO_STAPLE SSL_OCSP_TRY_STAPLE SSL_OCSP_MUST_STAPLE SSL_OCSP_FAIL_HARD SSL_OCSP_FULL_CHAIN $SSL_ERROR GEN_DNS GEN_IPADD ); } my @caller_force_inet4; # in case inet4 gets forced we store here who forced it my $IOCLASS; my $family_key; # 'Domain'||'Family' BEGIN { # declare @ISA depending of the installed socket class # try to load inet_pton from Socket or Socket6 and make sure it is usable local $SIG{__DIE__}; local $SIG{__WARN__}; # be silent my $ip6 = eval { require Socket; Socket->VERSION(1.95); Socket::inet_pton( AF_INET6(),'::1') && AF_INET6() or die; Socket->import( qw/inet_pton NI_NUMERICHOST NI_NUMERICSERV/ ); # behavior different to Socket6::getnameinfo - wrap *_getnameinfo = sub { my ($err,$host,$port) = Socket::getnameinfo(@_) or return; return if $err; return ($host,$port); }; 'Socket'; } || eval { require Socket6; Socket6::inet_pton( AF_INET6(),'::1') && AF_INET6() or die; Socket6->import( qw/inet_pton NI_NUMERICHOST NI_NUMERICSERV/ ); # behavior different to Socket::getnameinfo - wrap *_getnameinfo = sub { return Socket6::getnameinfo(@_); }; 'Socket6'; } || undef; # try IO::Socket::IP or IO::Socket::INET6 for IPv6 support $family_key = 'Domain'; # traditional if ($ip6) { # if we have IO::Socket::IP >= 0.31 we will use this in preference # because it can handle both IPv4 and IPv6 if ( eval { require IO::Socket::IP; IO::Socket::IP->VERSION(0.31) }) { @ISA = qw(IO::Socket::IP); constant->import( CAN_IPV6 => "IO::Socket::IP" ); $family_key = 'Family'; $IOCLASS = "IO::Socket::IP"; # if we have IO::Socket::INET6 we will use this not IO::Socket::INET # because it can handle both IPv4 and IPv6 # require at least 2.62 because of several problems before that version } elsif( eval { require IO::Socket::INET6; IO::Socket::INET6->VERSION(2.62) } ) { @ISA = qw(IO::Socket::INET6); constant->import( CAN_IPV6 => "IO::Socket::INET6" ); $IOCLASS = "IO::Socket::INET6"; } else { $ip6 = '' } } # fall back to IO::Socket::INET for IPv4 only if (!$ip6) { @ISA = qw(IO::Socket::INET); $IOCLASS = "IO::Socket::INET"; constant->import(CAN_IPV6 => ''); if (!defined $ip6) { constant->import(NI_NUMERICHOST => 1); constant->import(NI_NUMERICSERV => 2); } } #Make $DEBUG another name for $Net::SSLeay::trace *DEBUG = \$Net::SSLeay::trace; #Compatibility *ERROR = \$SSL_ERROR; } sub DEBUG { $DEBUG or return; my (undef,$file,$line,$sub) = caller(1); if ($sub =~m{^IO::Socket::SSL::(?:error|(_internal_error))$}) { (undef,$file,$line) = caller(2) if $1; } else { (undef,$file,$line) = caller; } my $msg = shift; $file = '...'.substr( $file,-17 ) if length($file)>20; $msg = sprintf $msg,@_ if @_; print STDERR "DEBUG: $file:$line: $msg\n"; } BEGIN { # import some constants from Net::SSLeay or use hard-coded defaults # if Net::SSLeay isn't recent enough to provide the constants my %const = ( NID_CommonName => 13, GEN_DNS => 2, GEN_IPADD => 7, ); while ( my ($name,$value) = each %const ) { no strict 'refs'; *{$name} = UNIVERSAL::can( 'Net::SSLeay', $name ) || sub { $value }; } *idn_to_ascii = \&IO::Socket::SSL::PublicSuffix::idn_to_ascii; *idn_to_unicode = \&IO::Socket::SSL::PublicSuffix::idn_to_unicode; } my $OPENSSL_LIST_SEPARATOR = $^O =~m{^(?:(dos|os2|mswin32|netware)|vms)$}i ? $1 ? ';' : ',' : ':'; my $CHECK_SSL_PATH = sub { my %args = (@_ == 1) ? ('',@_) : @_; for my $type (keys %args) { my $path = $args{$type}; if (!$type) { delete $args{$type}; $type = (ref($path) || -d $path) ? 'SSL_ca_path' : 'SSL_ca_file'; $args{$type} = $path; } next if ref($path) eq 'SCALAR' && ! $$path; if ($type eq 'SSL_ca_file') { die "SSL_ca_file $path can't be used: $!" if ! open(my $fh,'<',$path); } elsif ($type eq 'SSL_ca_path') { $path = [ split($OPENSSL_LIST_SEPARATOR,$path) ] if !ref($path); my @err; for my $d (ref($path) ? @$path : $path) { if (! -d $d) { push @err, "SSL_ca_path $d does not exist"; } elsif (! opendir(my $dh,$d)) { push @err, "SSL_ca_path $d is not accessible: $!" } else { @err = (); last } } die "@err" if @err; } } return %args; }; { my %default_ca; my $ca_detected; # 0: never detect, undef: need to (re)detect my $openssldir; sub default_ca { if (@_) { # user defined default CA or reset if ( @_ > 1 ) { %default_ca = @_; $ca_detected = 0; } elsif ( my $path = shift ) { %default_ca = $CHECK_SSL_PATH->($path); $ca_detected = 0; } else { $ca_detected = undef; } } return %default_ca if defined $ca_detected; # SSLEAY_DIR was 5 up to OpenSSL 1.1, then switched to 4 and got # renamed to OPENSSL_DIR. Unfortunately it is not exported as constant # by Net::SSLeay so we use the fixed number. $openssldir ||= Net::SSLeay::SSLeay_version(5) =~m{^OPENSSLDIR: "(.+)"$} ? $1 : Net::SSLeay::SSLeay_version(4) =~m{^OPENSSLDIR: "(.+)"$} ? $1 : 'cannot-determine-openssldir-from-ssleay-version'; # (re)detect according to openssl crypto/cryptlib.h my $dir = $ENV{SSL_CERT_DIR} || ( $^O =~m{vms}i ? "SSLCERTS:":"$openssldir/certs" ); if ( opendir(my $dh,$dir)) { FILES: for my $f ( grep { m{^[a-f\d]{8}(\.\d+)?$} } readdir($dh) ) { open( my $fh,'<',"$dir/$f") or next; while (my $line = <$fh>) { $line =~m{^-+BEGIN (X509 |TRUSTED |)CERTIFICATE-} or next; $default_ca{SSL_ca_path} = $dir; last FILES; } } } my $file = $ENV{SSL_CERT_FILE} || ( $^O =~m{vms}i ? "SSLCERTS:cert.pem":"$openssldir/cert.pem" ); if ( open(my $fh,'<',$file)) { while (my $line = <$fh>) { $line =~m{^-+BEGIN (X509 |TRUSTED |)CERTIFICATE-} or next; $default_ca{SSL_ca_file} = $file; last; } } $default_ca{SSL_ca_file} = Mozilla::CA::SSL_ca_file() if ! %default_ca && do { local $SIG{__DIE__}; eval { require Mozilla::CA; 1 }; }; $ca_detected = 1; return %default_ca; } } # Export some stuff # inet4|inet6|debug will be handled by myself, everything # else will be handled the Exporter way sub import { my $class = shift; my @export; foreach (@_) { if ( /^inet4$/i ) { # explicitly fall back to inet4 @ISA = 'IO::Socket::INET'; @caller_force_inet4 = caller(); # save for warnings for 'inet6' case } elsif ( /^inet6$/i ) { # check if we have already ipv6 as base if ( ! UNIVERSAL::isa( $class, 'IO::Socket::INET6') and ! UNIVERSAL::isa( $class, 'IO::Socket::IP' )) { # either we don't support it or we disabled it by explicitly # loading it with 'inet4'. In this case re-enable but warn # because this is probably an error if ( CAN_IPV6 ) { @ISA = ( CAN_IPV6 ); warn "IPv6 support re-enabled in __PACKAGE__, got disabled in file $caller_force_inet4[1] line $caller_force_inet4[2]"; } else { die "INET6 is not supported, install IO::Socket::IP"; } } } elsif ( /^:?debug(\d+)/ ) { $DEBUG=$1; } else { push @export,$_ } } @_ = ( $class,@export ); goto &Exporter::import; } my %SSL_OBJECT; my %CREATED_IN_THIS_THREAD; sub CLONE { %CREATED_IN_THIS_THREAD = (); } # all keys used internally, these should be cleaned up at end my @all_my_keys = qw( _SSL_arguments _SSL_certificate _SSL_ctx _SSL_fileno _SSL_in_DESTROY _SSL_ioclass_downgrade _SSL_ioclass_upgraded _SSL_last_err _SSL_object _SSL_ocsp_verify _SSL_opened _SSL_opening _SSL_servername ); # we have callbacks associated with contexts, but have no way to access the # current SSL object from these callbacks. To work around this # CURRENT_SSL_OBJECT will be set before calling Net::SSLeay::{connect,accept} # and reset afterwards, so we have access to it inside _internal_error. my $CURRENT_SSL_OBJECT; # You might be expecting to find a new() subroutine here, but that is # not how IO::Socket::INET works. All configuration gets performed in # the calls to configure() and either connect() or accept(). #Call to configure occurs when a new socket is made using #IO::Socket::INET. Returns false (empty list) on failure. sub configure { my ($self, $arg_hash) = @_; return _invalid_object() unless($self); # force initial blocking # otherwise IO::Socket::SSL->new might return undef if the # socket is nonblocking and it fails to connect immediately # for real nonblocking behavior one should create a nonblocking # socket and later call connect explicitly my $blocking = delete $arg_hash->{Blocking}; # because Net::HTTPS simple redefines blocking() to {} (e.g. # return undef) and IO::Socket::INET does not like this we # set Blocking only explicitly if it was set $arg_hash->{Blocking} = 1 if defined ($blocking); $self->configure_SSL($arg_hash) || return; if ($arg_hash->{$family_key} ||= $arg_hash->{Domain} || $arg_hash->{Family}) { # Hack to work around the problem that IO::Socket::IP defaults to # AI_ADDRCONFIG which creates problems if we have only the loopback # interface. If we already know the family this flag is more harmful # then useful. $arg_hash->{GetAddrInfoFlags} = 0 if $IOCLASS eq 'IO::Socket::IP' && ! defined $arg_hash->{GetAddrInfoFlags}; } return $self->_internal_error("@ISA configuration failed",0) if ! $self->SUPER::configure($arg_hash); $self->blocking(0) if defined $blocking && !$blocking; return $self; } sub configure_SSL { my ($self, $arg_hash) = @_; $arg_hash->{Proto} ||= 'tcp'; my $is_server = $arg_hash->{SSL_server}; if ( ! defined $is_server ) { $is_server = $arg_hash->{SSL_server} = $arg_hash->{Listen} || 0; } # add user defined defaults, maybe after filtering $FILTER_SSL_ARGS->($is_server,$arg_hash) if $FILTER_SSL_ARGS; delete @{*$self}{@all_my_keys}; ${*$self}{_SSL_opened} = $is_server; ${*$self}{_SSL_arguments} = $arg_hash; # this adds defaults to $arg_hash as a side effect! ${*$self}{'_SSL_ctx'} = IO::Socket::SSL::SSL_Context->new($arg_hash) or return; return $self; } sub _skip_rw_error { my ($self,$ssl,$rv) = @_; my $err = Net::SSLeay::get_error($ssl,$rv); if ( $err == $Net_SSLeay_ERROR_WANT_READ) { $SSL_ERROR = SSL_WANT_READ; } elsif ( $err == $Net_SSLeay_ERROR_WANT_WRITE) { $SSL_ERROR = SSL_WANT_WRITE; } else { return $err; } $! ||= EWOULDBLOCK; ${*$self}{_SSL_last_err} = [$SSL_ERROR,4] if ref($self); Net::SSLeay::ERR_clear_error(); return 0; } # Call to connect occurs when a new client socket is made using IO::Socket::* sub connect { my $self = shift || return _invalid_object(); return $self if ${*$self}{'_SSL_opened'}; # already connected if ( ! ${*$self}{'_SSL_opening'} ) { # call SUPER::connect if the underlying socket is not connected # if this fails this might not be an error (e.g. if $! = EINPROGRESS # and socket is nonblocking this is normal), so keep any error # handling to the client $DEBUG>=2 && DEBUG('socket not yet connected' ); $self->SUPER::connect(@_) || return; $DEBUG>=2 && DEBUG('socket connected' ); # IO::Socket works around systems, which return EISCONN or similar # on non-blocking re-connect by returning true, even if $! is set # but it does not clear $!, so do it here $! = undef; # don't continue with connect_SSL if SSL_startHandshake is set to 0 my $sh = ${*$self}{_SSL_arguments}{SSL_startHandshake}; return $self if defined $sh && ! $sh; } return $self->connect_SSL; } sub connect_SSL { my $self = shift; my $args = @_>1 ? {@_}: $_[0]||{}; return $self if ${*$self}{'_SSL_opened'}; # already connected my ($ssl,$ctx); if ( ! ${*$self}{'_SSL_opening'} ) { # start ssl connection $DEBUG>=2 && DEBUG('ssl handshake not started' ); ${*$self}{'_SSL_opening'} = 1; my $arg_hash = ${*$self}{'_SSL_arguments'}; my $fileno = ${*$self}{'_SSL_fileno'} = fileno($self); return $self->_internal_error("Socket has no fileno",9) if ! defined $fileno; $ctx = ${*$self}{'_SSL_ctx'}; # Reference to real context $ssl = ${*$self}{'_SSL_object'} = Net::SSLeay::new($ctx->{context}) || return $self->error("SSL structure creation failed"); $CREATED_IN_THIS_THREAD{$ssl} = 1 if $use_threads; $SSL_OBJECT{$ssl} = [$self,0]; weaken($SSL_OBJECT{$ssl}[0]); if ($ctx->{session_cache}) { $arg_hash->{SSL_session_key} ||= do { my $host = $arg_hash->{PeerAddr} || $arg_hash->{PeerHost} || $self->_update_peer; my $port = $arg_hash->{PeerPort} || $arg_hash->{PeerService}; $port ? "$host:$port" : $host; } } Net::SSLeay::set_fd($ssl, $fileno) || return $self->error("SSL filehandle association failed"); if ( $can_client_sni ) { my $host; if ( exists $arg_hash->{SSL_hostname} ) { # explicitly given # can be set to undef/'' to not use extension $host = $arg_hash->{SSL_hostname} } elsif ( $host = $arg_hash->{PeerAddr} || $arg_hash->{PeerHost} ) { # implicitly given $host =~s{:[a-zA-Z0-9_\-]+$}{}; # should be hostname, not IPv4/6 $host = undef if $host !~m{[a-z_]}i or $host =~m{:}; } # define SSL_CTRL_SET_TLSEXT_HOSTNAME 55 # define TLSEXT_NAMETYPE_host_name 0 if ($host) { $DEBUG>=2 && DEBUG("using SNI with hostname $host"); Net::SSLeay::ctrl($ssl,55,0,$host); } else { $DEBUG>=2 && DEBUG("not using SNI because hostname is unknown"); } } elsif ( $arg_hash->{SSL_hostname} ) { return $self->_internal_error( "Client side SNI not supported for this openssl",9); } else { $DEBUG>=2 && DEBUG("not using SNI because openssl is too old"); } $arg_hash->{PeerAddr} || $arg_hash->{PeerHost} || $self->_update_peer; if ( $ctx->{verify_name_ref} ) { # need target name for update my $host = $arg_hash->{SSL_verifycn_name} || $arg_hash->{SSL_hostname}; if ( ! defined $host ) { if ( $host = $arg_hash->{PeerAddr} || $arg_hash->{PeerHost} ) { $host =~s{:[a-zA-Z0-9_\-]+$}{}; } } ${$ctx->{verify_name_ref}} = $host; } my $ocsp = $ctx->{ocsp_mode}; if ( $ocsp & SSL_OCSP_NO_STAPLE ) { # don't try stapling } elsif ( ! $can_ocsp_staple ) { croak("OCSP stapling not support") if $ocsp & SSL_OCSP_MUST_STAPLE; } elsif ( $ocsp & (SSL_OCSP_TRY_STAPLE|SSL_OCSP_MUST_STAPLE)) { # staple by default if verification enabled ${*$self}{_SSL_ocsp_verify} = undef; Net::SSLeay::set_tlsext_status_type($ssl, Net::SSLeay::TLSEXT_STATUSTYPE_ocsp()); $DEBUG>=2 && DEBUG("request OCSP stapling"); } if ($ctx->{session_cache} and my $session = $ctx->{session_cache}->get_session($arg_hash->{SSL_session_key}) ) { Net::SSLeay::set_session($ssl, $session); } } $ssl ||= ${*$self}{'_SSL_object'}; $SSL_ERROR = $! = undef; my $timeout = exists $args->{Timeout} ? $args->{Timeout} : ${*$self}{io_socket_timeout}; # from IO::Socket if ( defined($timeout) && $timeout>0 && $self->blocking(0) ) { $DEBUG>=2 && DEBUG( "set socket to non-blocking to enforce timeout=$timeout" ); # timeout was given and socket was blocking # enforce timeout with now non-blocking socket } else { # timeout does not apply because invalid or socket non-blocking $timeout = undef; } my $start = defined($timeout) && time(); { $SSL_ERROR = undef; $CURRENT_SSL_OBJECT = $self; $DEBUG>=3 && DEBUG("call Net::SSLeay::connect" ); my $rv = Net::SSLeay::connect($ssl); $CURRENT_SSL_OBJECT = undef; $DEBUG>=3 && DEBUG("done Net::SSLeay::connect -> $rv" ); if ( $rv < 0 ) { if ( my $err = $self->_skip_rw_error( $ssl,$rv )) { $self->error("SSL connect attempt failed"); delete ${*$self}{'_SSL_opening'}; ${*$self}{'_SSL_opened'} = -1; $DEBUG>=1 && DEBUG( "fatal SSL error: $SSL_ERROR" ); return $self->fatal_ssl_error(); } $DEBUG>=2 && DEBUG('ssl handshake in progress' ); # connect failed because handshake needs to be completed # if socket was non-blocking or no timeout was given return with this error return if ! defined($timeout); # wait until socket is readable or writable my $rv; if ( $timeout>0 ) { my $vec = ''; vec($vec,$self->fileno,1) = 1; $DEBUG>=2 && DEBUG( "waiting for fd to become ready: $SSL_ERROR" ); $rv = $SSL_ERROR == SSL_WANT_READ ? select( $vec,undef,undef,$timeout) : $SSL_ERROR == SSL_WANT_WRITE ? select( undef,$vec,undef,$timeout) : undef; } else { $DEBUG>=2 && DEBUG("handshake failed because no more time" ); $! = ETIMEDOUT } if ( ! $rv ) { $DEBUG>=2 && DEBUG("handshake failed because socket did not became ready" ); # failed because of timeout, return $! ||= ETIMEDOUT; delete ${*$self}{'_SSL_opening'}; ${*$self}{'_SSL_opened'} = -1; $self->blocking(1); # was blocking before return } # socket is ready, try non-blocking connect again after recomputing timeout $DEBUG>=2 && DEBUG("socket ready, retrying connect" ); my $now = time(); $timeout -= $now - $start; $start = $now; redo; } elsif ( $rv == 0 ) { delete ${*$self}{'_SSL_opening'}; $DEBUG>=2 && DEBUG("connection failed - connect returned 0" ); $self->error("SSL connect attempt failed because of handshake problems" ); ${*$self}{'_SSL_opened'} = -1; return $self->fatal_ssl_error(); } } $DEBUG>=2 && DEBUG('ssl handshake done' ); # ssl connect successful delete ${*$self}{'_SSL_opening'}; ${*$self}{'_SSL_opened'}=1; if (defined($timeout)) { $self->blocking(1); # reset back to blocking $! = undef; # reset errors from non-blocking } $ctx ||= ${*$self}{'_SSL_ctx'}; if ( my $ocsp_result = ${*$self}{_SSL_ocsp_verify} ) { # got result from OCSP stapling if ( $ocsp_result->[0] > 0 ) { $DEBUG>=3 && DEBUG("got OCSP success with stapling"); # successful validated } elsif ( $ocsp_result->[0] < 0 ) { # Permanent problem with validation because certificate # is either self-signed or the issuer cannot be found. # Ignore here, because this will cause other errors too. $DEBUG>=3 && DEBUG("got OCSP failure with stapling: %s", $ocsp_result->[1]); } else { # definitely revoked $DEBUG>=3 && DEBUG("got OCSP revocation with stapling: %s", $ocsp_result->[1]); $self->_internal_error($ocsp_result->[1],5); return $self->fatal_ssl_error(); } } elsif ( $ctx->{ocsp_mode} & SSL_OCSP_MUST_STAPLE ) { $self->_internal_error("did not receive the required stapled OCSP response",5); return $self->fatal_ssl_error(); } if (!%sess_cb and $ctx->{session_cache} and my $session = Net::SSLeay::get1_session($ssl)) { $ctx->{session_cache}->add_session( ${*$self}{_SSL_arguments}{SSL_session_key}, $session ); } tie *{$self}, "IO::Socket::SSL::SSL_HANDLE", $self; return $self; } # called if PeerAddr is not set in ${*$self}{'_SSL_arguments'} # this can be the case if start_SSL is called with a normal IO::Socket::INET # so that PeerAddr|PeerPort are not set from args # returns PeerAddr sub _update_peer { my $self = shift; my $arg_hash = ${*$self}{'_SSL_arguments'}; eval { my $sockaddr = getpeername( $self ); my $af = sockaddr_family($sockaddr); if( CAN_IPV6 && $af == AF_INET6 ) { my (undef, $host, $port) = _getnameinfo($sockaddr, NI_NUMERICHOST | NI_NUMERICSERV); $arg_hash->{PeerPort} = $port; $arg_hash->{PeerAddr} = $host; } else { my ($port,$addr) = sockaddr_in( $sockaddr); $arg_hash->{PeerPort} = $port; $arg_hash->{PeerAddr} = inet_ntoa( $addr ); } } } #Call to accept occurs when a new client connects to a server using #IO::Socket::SSL sub accept { my $self = shift || return _invalid_object(); my $class = shift || 'IO::Socket::SSL'; my $socket = ${*$self}{'_SSL_opening'}; if ( ! $socket ) { # underlying socket not done $DEBUG>=2 && DEBUG('no socket yet' ); $socket = $self->SUPER::accept($class) || return; $DEBUG>=2 && DEBUG('accept created normal socket '.$socket ); # don't continue with accept_SSL if SSL_startHandshake is set to 0 my $sh = ${*$self}{_SSL_arguments}{SSL_startHandshake}; if (defined $sh && ! $sh) { ${*$socket}{_SSL_ctx} = ${*$self}{_SSL_ctx}; ${*$socket}{_SSL_arguments} = { %{${*$self}{_SSL_arguments}}, SSL_server => 0, }; $DEBUG>=2 && DEBUG('will not start SSL handshake yet'); return wantarray ? ($socket, getpeername($socket) ) : $socket } } $self->accept_SSL($socket) || return; $DEBUG>=2 && DEBUG('accept_SSL ok' ); return wantarray ? ($socket, getpeername($socket) ) : $socket; } sub accept_SSL { my $self = shift; my $socket = ( @_ && UNIVERSAL::isa( $_[0], 'IO::Handle' )) ? shift : $self; my $args = @_>1 ? {@_}: $_[0]||{}; my $ssl; if ( ! ${*$self}{'_SSL_opening'} ) { $DEBUG>=2 && DEBUG('starting sslifying' ); ${*$self}{'_SSL_opening'} = $socket; if ($socket != $self) { ${*$socket}{_SSL_ctx} = ${*$self}{_SSL_ctx}; ${*$socket}{_SSL_arguments} = { %{${*$self}{_SSL_arguments}}, SSL_server => 0 }; } my $fileno = ${*$socket}{'_SSL_fileno'} = fileno($socket); return $socket->_internal_error("Socket has no fileno",9) if ! defined $fileno; $ssl = ${*$socket}{_SSL_object} = Net::SSLeay::new(${*$socket}{_SSL_ctx}{context}) || return $socket->error("SSL structure creation failed"); $CREATED_IN_THIS_THREAD{$ssl} = 1 if $use_threads; $SSL_OBJECT{$ssl} = [$socket,1]; weaken($SSL_OBJECT{$ssl}[0]); Net::SSLeay::set_fd($ssl, $fileno) || return $socket->error("SSL filehandle association failed"); } $ssl ||= ${*$socket}{'_SSL_object'}; $SSL_ERROR = $! = undef; #$DEBUG>=2 && DEBUG('calling ssleay::accept' ); my $timeout = exists $args->{Timeout} ? $args->{Timeout} : ${*$self}{io_socket_timeout}; # from IO::Socket if ( defined($timeout) && $timeout>0 && $socket->blocking(0) ) { # timeout was given and socket was blocking # enforce timeout with now non-blocking socket } else { # timeout does not apply because invalid or socket non-blocking $timeout = undef; } my $start = defined($timeout) && time(); { $SSL_ERROR = undef; $CURRENT_SSL_OBJECT = $self; my $rv = Net::SSLeay::accept($ssl); $CURRENT_SSL_OBJECT = undef; $DEBUG>=3 && DEBUG( "Net::SSLeay::accept -> $rv" ); if ( $rv < 0 ) { if ( my $err = $socket->_skip_rw_error( $ssl,$rv )) { $socket->error("SSL accept attempt failed"); delete ${*$self}{'_SSL_opening'}; ${*$socket}{'_SSL_opened'} = -1; return $socket->fatal_ssl_error(); } # accept failed because handshake needs to be completed # if socket was non-blocking or no timeout was given return with this error return if ! defined($timeout); # wait until socket is readable or writable my $rv; if ( $timeout>0 ) { my $vec = ''; vec($vec,$socket->fileno,1) = 1; $rv = $SSL_ERROR == SSL_WANT_READ ? select( $vec,undef,undef,$timeout) : $SSL_ERROR == SSL_WANT_WRITE ? select( undef,$vec,undef,$timeout) : undef; } else { $! = ETIMEDOUT } if ( ! $rv ) { # failed because of timeout, return $! ||= ETIMEDOUT; delete ${*$self}{'_SSL_opening'}; ${*$socket}{'_SSL_opened'} = -1; $socket->blocking(1); # was blocking before return } # socket is ready, try non-blocking accept again after recomputing timeout my $now = time(); $timeout -= $now - $start; $start = $now; redo; } elsif ( $rv == 0 ) { $socket->error("SSL accept attempt failed because of handshake problems" ); delete ${*$self}{'_SSL_opening'}; ${*$socket}{'_SSL_opened'} = -1; return $socket->fatal_ssl_error(); } } $DEBUG>=2 && DEBUG('handshake done, socket ready' ); # socket opened delete ${*$self}{'_SSL_opening'}; ${*$socket}{'_SSL_opened'} = 1; if (defined($timeout)) { $socket->blocking(1); # reset back to blocking $! = undef; # reset errors from non-blocking } tie *{$socket}, "IO::Socket::SSL::SSL_HANDLE", $socket; return $socket; } ####### I/O subroutines ######################## sub _generic_read { my ($self, $read_func, undef, $length, $offset) = @_; my $ssl = ${*$self}{_SSL_object} || return; my $buffer=\$_[2]; $SSL_ERROR = $! = undef; my ($data,$rwerr) = $read_func->($ssl, $length); while ( ! defined($data)) { if ( my $err = $self->_skip_rw_error( $ssl, defined($rwerr) ? $rwerr:-1 )) { if ($err == $Net_SSLeay_ERROR_SYSCALL) { # OpenSSL 1.1.0c+ : EOF can now result in SSL_read returning -1 if (not $!) { # SSL_ERROR_SYSCALL but not errno -> treat as EOF $data = ''; last; } } $self->error("SSL read error"); } return; } $length = length($data); $$buffer = '' if !defined $$buffer; $offset ||= 0; if ($offset>length($$buffer)) { $$buffer.="\0" x ($offset-length($$buffer)); #mimic behavior of read } substr($$buffer, $offset, length($$buffer), $data); return $length; } sub read { my $self = shift; ${*$self}{_SSL_object} && return _generic_read($self, $self->blocking ? \&Net::SSLeay::ssl_read_all : \&Net::SSLeay::read, @_ ); # fall back to plain read if we are not required to use SSL yet return $self->SUPER::read(@_); } # contrary to the behavior of read sysread can read partial data sub sysread { my $self = shift; ${*$self}{_SSL_object} && return _generic_read( $self, \&Net::SSLeay::read, @_ ); # fall back to plain sysread if we are not required to use SSL yet my $rv = $self->SUPER::sysread(@_); return $rv; } sub peek { my $self = shift; ${*$self}{_SSL_object} && return _generic_read( $self, \&Net::SSLeay::peek, @_ ); # fall back to plain peek if we are not required to use SSL yet # emulate peek with recv(...,MS_PEEK) - peek(buf,len,offset) return if ! defined recv($self,my $buf,$_[1],MSG_PEEK); $_[0] = $_[2] ? substr($_[0],0,$_[2]).$buf : $buf; return length($buf); } sub _generic_write { my ($self, $write_all, undef, $length, $offset) = @_; my $ssl = ${*$self}{_SSL_object} || return; my $buffer = \$_[2]; my $buf_len = length($$buffer); $length ||= $buf_len; $offset ||= 0; return $self->_internal_error("Invalid offset for SSL write",9) if $offset>$buf_len; return 0 if ($offset == $buf_len); $SSL_ERROR = $! = undef; my $written; if ( $write_all ) { my $data = $length < $buf_len-$offset ? substr($$buffer, $offset, $length) : $$buffer; ($written, my $errs) = Net::SSLeay::ssl_write_all($ssl, $data); # ssl_write_all returns number of bytes written $written = undef if ! $written && $errs; } else { $written = Net::SSLeay::write_partial( $ssl,$offset,$length,$$buffer ); # write_partial does SSL_write which returns -1 on error $written = undef if $written < 0; } if ( !defined($written) ) { if ( my $err = $self->_skip_rw_error( $ssl,-1 )) { # if $! is not set with ERROR_SYSCALL then report as EPIPE $! ||= EPIPE if $err == $Net_SSLeay_ERROR_SYSCALL; $self->error("SSL write error ($err)"); } return; } return $written; } # if socket is blocking write() should return only on error or # if all data are written sub write { my $self = shift; ${*$self}{_SSL_object} && return _generic_write( $self, scalar($self->blocking),@_ ); # fall back to plain write if we are not required to use SSL yet return $self->SUPER::write(@_); } # contrary to write syswrite() returns already if only # a part of the data is written sub syswrite { my $self = shift; ${*$self}{_SSL_object} && return _generic_write($self,0,@_); # fall back to plain syswrite if we are not required to use SSL yet return $self->SUPER::syswrite(@_); } sub print { my $self = shift; my $string = join(($, or ''), @_, ($\ or '')); return $self->write( $string ); } sub printf { my ($self,$format) = (shift,shift); return $self->write(sprintf($format, @_)); } sub getc { my ($self, $buffer) = (shift, undef); return $buffer if $self->read($buffer, 1, 0); } sub readline { my $self = shift; ${*$self}{_SSL_object} or return $self->SUPER::getline; if ( not defined $/ or wantarray) { # read all and split my $buf = ''; while (1) { my $rv = $self->sysread($buf,2**16,length($buf)); if ( ! defined $rv ) { next if $! == EINTR; # retry last if $! == EWOULDBLOCK || $! == EAGAIN; # use everything so far return; # return error } elsif ( ! $rv ) { last } } if ( ! defined $/ ) { return $buf } elsif ( ref($/)) { my $size = ${$/}; die "bad value in ref \$/: $size" unless $size>0; return $buf=~m{\G(.{1,$size})}g; } elsif ( $/ eq '' ) { return $buf =~m{\G(.*\n\n+|.+)}g; } else { return $buf =~m{\G(.*$/|.+)}g; } } # read only one line if ( ref($/) ) { my $size = ${$/}; # read record of $size bytes die "bad value in ref \$/: $size" unless $size>0; my $buf = ''; while ( $size>length($buf)) { my $rv = $self->sysread($buf,$size-length($buf),length($buf)); if ( ! defined $rv ) { next if $! == EINTR; # retry last if $! == EWOULDBLOCK || $! == EAGAIN; # use everything so far return; # return error } elsif ( ! $rv ) { last } } return $buf; } my ($delim0,$delim1) = $/ eq '' ? ("\n\n","\n"):($/,''); # find first occurrence of $delim0 followed by as much as possible $delim1 my $buf = ''; my $eod = 0; # pointer into $buf after $delim0 $delim1* my $ssl = $self->_get_ssl_object or return; while (1) { # wait until we have more data or eof my $poke = Net::SSLeay::peek($ssl,1); if ( ! defined $poke or $poke eq '' ) { next if $! == EINTR; } my $skip = 0; # peek into available data w/o reading my $pending = Net::SSLeay::pending($ssl); if ( $pending and ( my $pb = Net::SSLeay::peek( $ssl,$pending )) ne '' ) { $buf .= $pb } else { return $buf eq '' ? ():$buf; } if ( !$eod ) { my $pos = index( $buf,$delim0 ); if ( $pos<0 ) { $skip = $pending } else { $eod = $pos + length($delim0); # pos after delim0 } } if ( $eod ) { if ( $delim1 ne '' ) { # delim0 found, check for as much delim1 as possible while ( index( $buf,$delim1,$eod ) == $eod ) { $eod+= length($delim1); } } $skip = $pending - ( length($buf) - $eod ); } # remove data from $self which I already have in buf while ( $skip>0 ) { if ($self->sysread(my $p,$skip,0)) { $skip -= length($p); next; } $! == EINTR or last; } if ( $eod and ( $delim1 eq '' or $eod < length($buf))) { # delim0 found and there can be no more delim1 pending last } } return substr($buf,0,$eod); } sub close { my $self = shift || return _invalid_object(); my $close_args = (ref($_[0]) eq 'HASH') ? $_[0] : {@_}; return if ! $self->stop_SSL( SSL_fast_shutdown => 1, %$close_args, _SSL_ioclass_downgrade => 0, ); if ( ! $close_args->{_SSL_in_DESTROY} ) { untie( *$self ); undef ${*$self}{_SSL_fileno}; return $self->SUPER::close; } return 1; } sub is_SSL { my $self = pop; return ${*$self}{_SSL_object} && 1 } sub stop_SSL { my $self = shift || return _invalid_object(); my $stop_args = (ref($_[0]) eq 'HASH') ? $_[0] : {@_}; $stop_args->{SSL_no_shutdown} = 1 if ! ${*$self}{_SSL_opened}; if (my $ssl = ${*$self}{'_SSL_object'}) { if ( ! $stop_args->{SSL_no_shutdown} ) { my $status = Net::SSLeay::get_shutdown($ssl); my $timeout = not($self->blocking) ? undef : exists $stop_args->{Timeout} ? $stop_args->{Timeout} : ${*$self}{io_socket_timeout}; # from IO::Socket if ($timeout) { $self->blocking(0); $timeout += time(); } while (1) { if ( $status & SSL_SENT_SHUTDOWN and # don't care for received if fast shutdown $status & SSL_RECEIVED_SHUTDOWN || $stop_args->{SSL_fast_shutdown}) { # shutdown complete last; } if ((${*$self}{'_SSL_opened'}||0) <= 0) { # not really open, thus don't expect shutdown to return # something meaningful last; } # initiate or complete shutdown local $SIG{PIPE} = 'IGNORE'; my $rv = Net::SSLeay::shutdown($ssl); if ( $rv < 0 ) { # non-blocking socket? if ( ! $timeout ) { $self->_skip_rw_error( $ssl,$rv ); # need to try again return; } # don't use _skip_rw_error so that existing error does # not get cleared my $wait = $timeout - time(); last if $wait<=0; vec(my $vec = '',fileno($self),1) = 1; my $err = Net::SSLeay::get_error($ssl,$rv); if ( $err == $Net_SSLeay_ERROR_WANT_READ) { select($vec,undef,undef,$wait) } elsif ( $err == $Net_SSLeay_ERROR_WANT_READ) { select(undef,$vec,undef,$wait) } else { last; } } $status |= SSL_SENT_SHUTDOWN; $status |= SSL_RECEIVED_SHUTDOWN if $rv>0; } $self->blocking(1) if $timeout; } # destroy allocated objects for SSL and untie # do not destroy CTX unless explicitly specified Net::SSLeay::free($ssl); if (my $cert = delete ${*$self}{'_SSL_certificate'}) { Net::SSLeay::X509_free($cert); } delete ${*$self}{_SSL_object}; ${*$self}{'_SSL_opened'} = 0; delete $SSL_OBJECT{$ssl}; delete $CREATED_IN_THIS_THREAD{$ssl}; untie(*$self); } if ($stop_args->{'SSL_ctx_free'}) { my $ctx = delete ${*$self}{'_SSL_ctx'}; $ctx && $ctx->DESTROY(); } if ( ! $stop_args->{_SSL_in_DESTROY} ) { my $downgrade = $stop_args->{_SSL_ioclass_downgrade}; if ( $downgrade || ! defined $downgrade ) { # rebless to original class from start_SSL if ( my $orig_class = delete ${*$self}{'_SSL_ioclass_upgraded'} ) { bless $self,$orig_class; # FIXME: if original class was tied too we need to restore the tie # remove all _SSL related from *$self my @sslkeys = grep { m{^_?SSL_} } keys %{*$self}; delete @{*$self}{@sslkeys} if @sslkeys; } } } return 1; } sub fileno { my $self = shift; my $fn = ${*$self}{'_SSL_fileno'}; return defined($fn) ? $fn : $self->SUPER::fileno(); } ####### IO::Socket::SSL specific functions ####### # _get_ssl_object is for internal use ONLY! sub _get_ssl_object { my $self = shift; return ${*$self}{'_SSL_object'} || IO::Socket::SSL->_internal_error("Undefined SSL object",9); } # _get_ctx_object is for internal use ONLY! sub _get_ctx_object { my $self = shift; my $ctx_object = ${*$self}{_SSL_ctx}; return $ctx_object && $ctx_object->{context}; } # default error for undefined arguments sub _invalid_object { return IO::Socket::SSL->_internal_error("Undefined IO::Socket::SSL object",9); } sub pending { my $ssl = shift()->_get_ssl_object || return; return Net::SSLeay::pending($ssl); } sub start_SSL { my ($class,$socket) = (shift,shift); return $class->_internal_error("Not a socket",9) if ! ref($socket); my $arg_hash = @_ == 1 ? $_[0] : {@_}; my %to = exists $arg_hash->{Timeout} ? ( Timeout => delete $arg_hash->{Timeout} ) :(); my $original_class = ref($socket); if ( ! $original_class ) { $socket = ($original_class = $ISA[0])->new_from_fd($socket,'<+') or return $class->_internal_error( "creating $original_class from file handle failed",9); } my $original_fileno = (UNIVERSAL::can($socket, "fileno")) ? $socket->fileno : CORE::fileno($socket); return $class->_internal_error("Socket has no fileno",9) if ! defined $original_fileno; bless $socket, $class; $socket->configure_SSL($arg_hash) or bless($socket, $original_class) && return; ${*$socket}{'_SSL_fileno'} = $original_fileno; ${*$socket}{'_SSL_ioclass_upgraded'} = $original_class if $class ne $original_class; my $start_handshake = $arg_hash->{SSL_startHandshake}; if ( ! defined($start_handshake) || $start_handshake ) { # if we have no callback force blocking mode $DEBUG>=2 && DEBUG( "start handshake" ); my $was_blocking = $socket->blocking(1); my $result = ${*$socket}{'_SSL_arguments'}{SSL_server} ? $socket->accept_SSL(%to) : $socket->connect_SSL(%to); if ( $result ) { $socket->blocking(0) if ! $was_blocking; return $socket; } else { # upgrade to SSL failed, downgrade socket to original class if ( $original_class ) { bless($socket,$original_class); $socket->blocking(0) if ! $was_blocking && $socket->can('blocking'); } return; } } else { $DEBUG>=2 && DEBUG( "don't start handshake: $socket" ); return $socket; # just return upgraded socket } } sub new_from_fd { my ($class, $fd) = (shift,shift); # Check for accidental inclusion of MODE in the argument list if (length($_[0]) < 4) { (my $mode = $_[0]) =~ tr/+<>//d; shift unless length($mode); } my $handle = $ISA[0]->new_from_fd($fd, '+<') || return($class->error("Could not create socket from file descriptor.")); # Annoying workaround for Perl 5.6.1 and below: $handle = $ISA[0]->new_from_fd($handle, '+<'); return $class->start_SSL($handle, @_); } sub dump_peer_certificate { my $ssl = shift()->_get_ssl_object || return; return Net::SSLeay::dump_peer_certificate($ssl); } if ( defined &Net::SSLeay::get_peer_cert_chain && $netssleay_version >= 1.58 ) { *peer_certificates = sub { my $self = shift; my $ssl = $self->_get_ssl_object || return; my @chain = Net::SSLeay::get_peer_cert_chain($ssl); @chain = () if @chain && !$self->peer_certificate; # work around #96013 if ( ${*$self}{_SSL_arguments}{SSL_server} ) { # in the client case the chain contains the peer certificate, # in the server case not # this one has an increased reference counter, the other not if ( my $peer = Net::SSLeay::get_peer_certificate($ssl)) { Net::SSLeay::X509_free($peer); unshift @chain, $peer; } } return @chain; } } else { *peer_certificates = sub { die "peer_certificates needs Net::SSLeay>=1.58"; } } { my %dispatcher = ( issuer => sub { Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_issuer_name( shift )) }, subject => sub { Net::SSLeay::X509_NAME_oneline( Net::SSLeay::X509_get_subject_name( shift )) }, commonName => sub { my $cn = Net::SSLeay::X509_NAME_get_text_by_NID( Net::SSLeay::X509_get_subject_name( shift ), NID_CommonName); $cn; }, subjectAltNames => sub { Net::SSLeay::X509_get_subjectAltNames( shift ) }, ); # alternative names $dispatcher{authority} = $dispatcher{issuer}; $dispatcher{owner} = $dispatcher{subject}; $dispatcher{cn} = $dispatcher{commonName}; sub peer_certificate { my ($self,$field,$reload) = @_; my $ssl = $self->_get_ssl_object or return; Net::SSLeay::X509_free(delete ${*$self}{_SSL_certificate}) if $reload && ${*$self}{_SSL_certificate}; my $cert = ${*$self}{_SSL_certificate} ||= Net::SSLeay::get_peer_certificate($ssl) or return $self->error("Could not retrieve peer certificate"); if ($field) { my $sub = $dispatcher{$field} or croak "invalid argument for peer_certificate, valid are: ".join( " ",keys %dispatcher ). "\nMaybe you need to upgrade your Net::SSLeay"; return $sub->($cert); } else { return $cert } } sub sock_certificate { my ($self,$field) = @_; my $ssl = $self->_get_ssl_object || return; my $cert = Net::SSLeay::get_certificate( $ssl ) || return; if ($field) { my $sub = $dispatcher{$field} or croak "invalid argument for sock_certificate, valid are: ".join( " ",keys %dispatcher ). "\nMaybe you need to upgrade your Net::SSLeay"; return $sub->($cert); } else { return $cert } } # known schemes, possible attributes are: # - wildcards_in_alt (0, 'full_label', 'anywhere') # - wildcards_in_cn (0, 'full_label', 'anywhere') # - check_cn (0, 'always', 'when_only') # unfortunately there are a lot of different schemes used, see RFC 6125 for a # summary, which references all of the following except RFC4217/ftp my %scheme = ( none => {}, # do not check # default set is a superset of all the others and thus worse than a more # specific set, but much better than not verifying name at all default => { wildcards_in_cn => 'anywhere', wildcards_in_alt => 'anywhere', check_cn => 'always', ip_in_cn => 1, }, ); for(qw( rfc2818 rfc3920 xmpp rfc4217 ftp )) { $scheme{$_} = { wildcards_in_cn => 'anywhere', wildcards_in_alt => 'anywhere', check_cn => 'when_only', } } for(qw(www http)) { $scheme{$_} = { wildcards_in_cn => 'anywhere', wildcards_in_alt => 'anywhere', check_cn => 'when_only', ip_in_cn => 4, } } for(qw( rfc4513 ldap )) { $scheme{$_} = { wildcards_in_cn => 0, wildcards_in_alt => 'full_label', check_cn => 'always', }; } for(qw( rfc2595 smtp rfc4642 imap pop3 acap rfc5539 nntp rfc5538 netconf rfc5425 syslog rfc5953 snmp )) { $scheme{$_} = { wildcards_in_cn => 'full_label', wildcards_in_alt => 'full_label', check_cn => 'always' }; } for(qw( rfc5971 gist )) { $scheme{$_} = { wildcards_in_cn => 'full_label', wildcards_in_alt => 'full_label', check_cn => 'when_only', }; } for(qw( rfc5922 sip )) { $scheme{$_} = { wildcards_in_cn => 0, wildcards_in_alt => 0, check_cn => 'always', }; } # function to verify the hostname # # as every application protocol has its own rules to do this # we provide some default rules as well as a user-defined # callback sub verify_hostname_of_cert { my $identity = shift; my $cert = shift; my $scheme = shift || 'default'; my $publicsuffix = shift; if ( ! ref($scheme) ) { $DEBUG>=3 && DEBUG( "scheme=$scheme cert=$cert" ); $scheme = $scheme{$scheme} || croak("scheme $scheme not defined"); } return 1 if ! %$scheme; # 'none' $identity =~s{\.+$}{}; # ignore absolutism # get data from certificate my $commonName = $dispatcher{cn}->($cert); my @altNames = $dispatcher{subjectAltNames}->($cert); $DEBUG>=3 && DEBUG("identity=$identity cn=$commonName alt=@altNames" ); if ( my $sub = $scheme->{callback} ) { # use custom callback return $sub->($identity,$commonName,@altNames); } # is the given hostname an IP address? Then we have to convert to network byte order [RFC791][RFC2460] my $ipn; if ( CAN_IPV6 and $identity =~m{:} ) { # no IPv4 or hostname have ':' in it, try IPv6. $identity =~m{[^\da-fA-F:\.]} and return; # invalid characters in name $ipn = inet_pton(AF_INET6,$identity) or return; # invalid name } elsif ( my @ip = $identity =~m{^(\d+)(?:\.(\d+)\.(\d+)\.(\d+)|[\d\.]*)$} ) { # check for invalid IP/hostname return if 4 != @ip or 4 != grep { defined($_) && $_<256 } @ip; $ipn = pack("CCCC",@ip); } else { # assume hostname, check for umlauts etc if ( $identity =~m{[^a-zA-Z0-9_.\-]} ) { $identity =~m{\0} and return; # $identity has \\0 byte $identity = idn_to_ascii($identity) or return; # conversation to IDNA failed $identity =~m{[^a-zA-Z0-9_.\-]} and return; # still junk inside } } # do the actual verification my $check_name = sub { my ($name,$identity,$wtyp,$publicsuffix) = @_; $name =~s{\.+$}{}; # ignore absolutism $name eq '' and return; $wtyp ||= ''; my $pattern; ### IMPORTANT! # We accept only a single wildcard and only for a single part of the FQDN # e.g. *.example.org does match www.example.org but not bla.www.example.org # The RFCs are in this regard unspecific but we don't want to have to # deal with certificates like *.com, *.co.uk or even * # see also http://nils.toedtmann.net/pub/subjectAltName.txt . # Also, we fall back to full_label matches if the identity is an IDNA # name, see RFC6125 and the discussion at # http://bugs.python.org/issue17997#msg194950 if ( $wtyp eq 'anywhere' and $name =~m{^([a-zA-Z0-9_\-]*)\*(.+)} ) { return if $1 ne '' and substr($identity,0,4) eq 'xn--'; # IDNA $pattern = qr{^\Q$1\E[a-zA-Z0-9_\-]+\Q$2\E$}i; } elsif ( $wtyp =~ m{^(?:full_label|leftmost)$} and $name =~m{^\*(\..+)$} ) { $pattern = qr{^[a-zA-Z0-9_\-]+\Q$1\E$}i; } else { return lc($identity) eq lc($name); } if ( $identity =~ $pattern ) { $publicsuffix = IO::Socket::SSL::PublicSuffix->default if ! defined $publicsuffix; return 1 if $publicsuffix eq ''; my @labels = split( m{\.+}, $identity ); my $tld = $publicsuffix->public_suffix(\@labels,+1); return 1 if @labels > ( $tld ? 0+@$tld : 1 ); } return; }; my $alt_dnsNames = 0; while (@altNames) { my ($type, $name) = splice (@altNames, 0, 2); if ( $ipn and $type == GEN_IPADD ) { # exact match needed for IP # $name is already packed format (inet_xton) return 1 if $ipn eq $name; } elsif ( ! $ipn and $type == GEN_DNS ) { $name =~s/\s+$//; $name =~s/^\s+//; $alt_dnsNames++; $check_name->($name,$identity,$scheme->{wildcards_in_alt},$publicsuffix) and return 1; } } if ( $scheme->{check_cn} eq 'always' or $scheme->{check_cn} eq 'when_only' and !$alt_dnsNames ) { if ( ! $ipn ) { $check_name->($commonName,$identity,$scheme->{wildcards_in_cn},$publicsuffix) and return 1; } elsif ( $scheme->{ip_in_cn} ) { if ( $identity eq $commonName ) { return 1 if $scheme->{ip_in_cn} == 4 ? length($ipn) == 4 : $scheme->{ip_in_cn} == 6 ? length($ipn) == 8 : 1; } } } return 0; # no match } } sub verify_hostname { my $self = shift; my $host = shift; my $cert = $self->peer_certificate; return verify_hostname_of_cert( $host,$cert,@_ ); } sub get_servername { my $self = shift; return ${*$self}{_SSL_servername} ||= do { my $ssl = $self->_get_ssl_object or return; Net::SSLeay::get_servername($ssl); }; } sub get_fingerprint_bin { my ($self,$algo,$cert,$key_only) = @_; $cert ||= $self->peer_certificate; return $key_only ? Net::SSLeay::X509_pubkey_digest($cert, $algo2digest->($algo || 'sha256')) : Net::SSLeay::X509_digest($cert, $algo2digest->($algo || 'sha256')); } sub get_fingerprint { my ($self,$algo,$cert,$key_only) = @_; $algo ||= 'sha256'; my $fp = get_fingerprint_bin($self,$algo,$cert,$key_only) or return; return $algo.'$'.($key_only ? 'pub$':'').unpack('H*',$fp); } sub get_cipher { my $ssl = shift()->_get_ssl_object || return; return Net::SSLeay::get_cipher($ssl); } sub get_sslversion { my $ssl = shift()->_get_ssl_object || return; my $version = Net::SSLeay::version($ssl) or return; return $version == 0x0304 ? 'TLSv1_3' : $version == 0x0303 ? 'TLSv1_2' : $version == 0x0302 ? 'TLSv1_1' : $version == 0x0301 ? 'TLSv1' : $version == 0x0300 ? 'SSLv3' : $version == 0x0002 ? 'SSLv2' : $version == 0xfeff ? 'DTLS1' : undef; } sub get_sslversion_int { my $ssl = shift()->_get_ssl_object || return; return Net::SSLeay::version($ssl); } sub get_session_reused { return Net::SSLeay::session_reused( shift()->_get_ssl_object || return); } if ($can_ocsp) { no warnings 'once'; *ocsp_resolver = sub { my $self = shift; my $ssl = $self->_get_ssl_object || return; my $ctx = ${*$self}{_SSL_ctx}; return IO::Socket::SSL::OCSP_Resolver->new( $ssl, $ctx->{ocsp_cache} ||= IO::Socket::SSL::OCSP_Cache->new, $ctx->{ocsp_mode} & SSL_OCSP_FAIL_HARD, @_ ? \@_ : $ctx->{ocsp_mode} & SSL_OCSP_FULL_CHAIN ? [ $self->peer_certificates ]: [ $self->peer_certificate ] ); }; } sub errstr { my $self = shift; my $oe = ref($self) && ${*$self}{_SSL_last_err}; return $oe ? $oe->[0] : $SSL_ERROR || ''; } sub fatal_ssl_error { my $self = shift; my $error_trap = ${*$self}{'_SSL_arguments'}->{'SSL_error_trap'}; $@ = $self->errstr; if (defined $error_trap and ref($error_trap) eq 'CODE') { $error_trap->($self, $self->errstr()."\n".$self->get_ssleay_error()); } elsif ( ${*$self}{'_SSL_ioclass_upgraded'} || ${*$self}{_SSL_arguments}{SSL_keepSocketOnError}) { # downgrade only $DEBUG>=3 && DEBUG('downgrading SSL only, not closing socket' ); $self->stop_SSL; } else { # kill socket $self->close } return; } sub get_ssleay_error { #Net::SSLeay will print out the errors itself unless we explicitly #undefine $Net::SSLeay::trace while running print_errs() local $Net::SSLeay::trace; return Net::SSLeay::print_errs('SSL error: ') || ''; } # internal errors, e.g. unsupported features, hostname check failed etc # _SSL_last_err contains severity so that on error chains we can decide if one # error should replace the previous one or if this is just a less specific # follow-up error, e.g. configuration failed because certificate failed because # hostname check went wrong: # 0 - fallback errors # 4 - errors bubbled up from OpenSSL (sub error, r/w error) # 5 - hostname or OCSP verification failed # 9 - fatal problems, e.g. missing feature, no fileno... # _SSL_last_err and SSL_ERROR are only replaced if the error has a higher # severity than the previous one sub _internal_error { my ($self, $error, $severity) = @_; $error = dualvar( -1, $error ); $self = $CURRENT_SSL_OBJECT if !ref($self) && $CURRENT_SSL_OBJECT; if (ref($self)) { my $oe = ${*$self}{_SSL_last_err}; if (!$oe || $oe->[1] <= $severity) { ${*$self}{_SSL_last_err} = [$error,$severity]; $SSL_ERROR = $error; $DEBUG && DEBUG("local error: $error"); } else { $DEBUG && DEBUG("ignoring less severe local error '$error', keep '$oe->[0]'"); } } else { $SSL_ERROR = $error; $DEBUG && DEBUG("global error: $error"); } return; } # OpenSSL errors sub error { my ($self, $error) = @_; my @err; while ( my $err = Net::SSLeay::ERR_get_error()) { push @err, Net::SSLeay::ERR_error_string($err); $DEBUG>=2 && DEBUG( $error."\n".$self->get_ssleay_error()); } $error .= ' '.join(' ',@err) if @err; return $self->_internal_error($error,4) if $error; return; } sub can_client_sni { return $can_client_sni } sub can_server_sni { return $can_server_sni } sub can_multi_cert { return $can_multi_cert } sub can_npn { return $can_npn } sub can_alpn { return $can_alpn } sub can_ecdh { return $can_ecdh } sub can_ipv6 { return CAN_IPV6 } sub can_ocsp { return $can_ocsp } sub can_ticket_keycb { return $can_tckt_keycb } sub can_pha { return $can_pha } sub can_partial_chain { return $check_partial_chain && 1 } sub DESTROY { my $self = shift or return; if (my $ssl = ${*$self}{_SSL_object}) { delete $SSL_OBJECT{$ssl}; if (!$use_threads or delete $CREATED_IN_THIS_THREAD{$ssl}) { $self->close(_SSL_in_DESTROY => 1, SSL_no_shutdown => 1) if ${*$self}{'_SSL_opened'}; } } delete @{*$self}{@all_my_keys}; } #######Extra Backwards Compatibility Functionality####### sub socket_to_SSL { IO::Socket::SSL->start_SSL(@_); } sub socketToSSL { IO::Socket::SSL->start_SSL(@_); } sub kill_socket { shift->close } sub issuer_name { return(shift()->peer_certificate("issuer")) } sub subject_name { return(shift()->peer_certificate("subject")) } sub get_peer_certificate { return shift() } sub context_init { return($GLOBAL_SSL_ARGS = (ref($_[0]) eq 'HASH') ? $_[0] : {@_}); } sub set_default_context { $GLOBAL_SSL_ARGS->{'SSL_reuse_ctx'} = shift; } sub set_default_session_cache { $GLOBAL_SSL_ARGS->{SSL_session_cache} = shift; } { my $set_defaults = sub { my $args = shift; for(my $i=0;$i<@$args;$i+=2 ) { my ($k,$v) = @{$args}[$i,$i+1]; if ( $k =~m{^SSL_} ) { $_->{$k} = $v for(@_); } elsif ( $k =~m{^(name|scheme)$} ) { $_->{"SSL_verifycn_$k"} = $v for (@_); } elsif ( $k =~m{^(callback|mode)$} ) { $_->{"SSL_verify_$k"} = $v for(@_); } else { $_->{"SSL_$k"} = $v for(@_); } } }; sub set_defaults { my %args = @_; $set_defaults->(\@_, $GLOBAL_SSL_ARGS, $GLOBAL_SSL_CLIENT_ARGS, $GLOBAL_SSL_SERVER_ARGS ); } { # deprecated API no warnings; *set_ctx_defaults = \&set_defaults; } sub set_client_defaults { my %args = @_; $set_defaults->(\@_, $GLOBAL_SSL_CLIENT_ARGS ); } sub set_server_defaults { my %args = @_; $set_defaults->(\@_, $GLOBAL_SSL_SERVER_ARGS ); } } sub set_args_filter_hack { my $sub = shift; if ( ref $sub ) { $FILTER_SSL_ARGS = $sub; } elsif ( $sub eq 'use_defaults' ) { # override args with defaults $FILTER_SSL_ARGS = sub { my ($is_server,$args) = @_; %$args = ( %$args, $is_server ? ( %DEFAULT_SSL_SERVER_ARGS, %$GLOBAL_SSL_SERVER_ARGS ) : ( %DEFAULT_SSL_CLIENT_ARGS, %$GLOBAL_SSL_CLIENT_ARGS ) ); } } } sub next_proto_negotiated { my $self = shift; return $self->_internal_error("NPN not supported in Net::SSLeay",9) if ! $can_npn; my $ssl = $self->_get_ssl_object || return; return Net::SSLeay::P_next_proto_negotiated($ssl); } sub alpn_selected { my $self = shift; return $self->_internal_error("ALPN not supported in Net::SSLeay",9) if ! $can_alpn; my $ssl = $self->_get_ssl_object || return; return Net::SSLeay::P_alpn_selected($ssl); } sub opened { my $self = shift; return IO::Handle::opened($self) && ${*$self}{'_SSL_opened'}; } sub opening { my $self = shift; return ${*$self}{'_SSL_opening'}; } sub want_read { shift->errstr == SSL_WANT_READ } sub want_write { shift->errstr == SSL_WANT_WRITE } #Redundant IO::Handle functionality sub getline { return(scalar shift->readline()) } sub getlines { return(shift->readline()) if wantarray(); croak("Use of getlines() not allowed in scalar context"); } #Useless IO::Handle functionality sub truncate { croak("Use of truncate() not allowed with SSL") } sub stat { croak("Use of stat() not allowed with SSL" ) } sub setbuf { croak("Use of setbuf() not allowed with SSL" ) } sub setvbuf { croak("Use of setvbuf() not allowed with SSL" ) } sub fdopen { croak("Use of fdopen() not allowed with SSL" ) } #Unsupported socket functionality sub ungetc { croak("Use of ungetc() not implemented in IO::Socket::SSL") } sub send { croak("Use of send() not implemented in IO::Socket::SSL; use print/printf/syswrite instead") } sub recv { croak("Use of recv() not implemented in IO::Socket::SSL; use read/sysread instead") } package IO::Socket::SSL::SSL_HANDLE; use strict; use Errno 'EBADF'; *weaken = *IO::Socket::SSL::weaken; sub TIEHANDLE { my ($class, $handle) = @_; weaken($handle); bless \$handle, $class; } sub READ { ${shift()}->sysread(@_) } sub READLINE { ${shift()}->readline(@_) } sub GETC { ${shift()}->getc(@_) } sub PRINT { ${shift()}->print(@_) } sub PRINTF { ${shift()}->printf(@_) } sub WRITE { ${shift()}->syswrite(@_) } sub FILENO { ${shift()}->fileno(@_) } sub TELL { $! = EBADF; return -1 } sub BINMODE { return 0 } # not perfect, but better than not implementing the method sub CLOSE { #<---- Do not change this function! my $ssl = ${$_[0]}; local @_; $ssl->close(); } package IO::Socket::SSL::SSL_Context; use Carp; use strict; my %CTX_CREATED_IN_THIS_THREAD; *DEBUG = *IO::Socket::SSL::DEBUG; use constant SSL_MODE_ENABLE_PARTIAL_WRITE => 1; use constant SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER => 2; use constant FILETYPE_PEM => Net::SSLeay::FILETYPE_PEM(); use constant FILETYPE_ASN1 => Net::SSLeay::FILETYPE_ASN1(); my $DEFAULT_SSL_OP = &Net::SSLeay::OP_ALL | &Net::SSLeay::OP_SINGLE_DH_USE | ($can_ecdh && &Net::SSLeay::OP_SINGLE_ECDH_USE); # Note that the final object will actually be a reference to the scalar # (C-style pointer) returned by Net::SSLeay::CTX_*_new() so that # it can be blessed. sub new { my $class = shift; #DEBUG( "$class @_" ); my $arg_hash = (ref($_[0]) eq 'HASH') ? $_[0] : {@_}; my $is_server = $arg_hash->{SSL_server}; my %defaults = $is_server ? (%DEFAULT_SSL_SERVER_ARGS, %$GLOBAL_SSL_ARGS, %$GLOBAL_SSL_SERVER_ARGS) : (%DEFAULT_SSL_CLIENT_ARGS, %$GLOBAL_SSL_ARGS, %$GLOBAL_SSL_CLIENT_ARGS); if ( $defaults{SSL_reuse_ctx} ) { # ignore default context if there are args to override it delete $defaults{SSL_reuse_ctx} if grep { m{^SSL_(?!verifycn_name|hostname)$} } keys %$arg_hash; } %$arg_hash = ( %defaults, %$arg_hash ) if %defaults; if (my $ctx = $arg_hash->{'SSL_reuse_ctx'}) { if ($ctx->isa('IO::Socket::SSL::SSL_Context') and $ctx->{context}) { # valid context } elsif ( $ctx = ${*$ctx}{_SSL_ctx} ) { # reuse context from existing SSL object } return $ctx } # common problem forgetting to set SSL_use_cert # if client cert is given by user but SSL_use_cert is undef, assume that it # should be set if ( ! $is_server && ! defined $arg_hash->{SSL_use_cert} && ( grep { $arg_hash->{$_} } qw(SSL_cert SSL_cert_file)) && ( grep { $arg_hash->{$_} } qw(SSL_key SSL_key_file)) ) { $arg_hash->{SSL_use_cert} = 1 } # if any of SSL_ca* is set don't set the other SSL_ca* # from defaults if ( $arg_hash->{SSL_ca} ) { $arg_hash->{SSL_ca_file} ||= undef $arg_hash->{SSL_ca_path} ||= undef } elsif ( $arg_hash->{SSL_ca_path} ) { $arg_hash->{SSL_ca_file} ||= undef } elsif ( $arg_hash->{SSL_ca_file} ) { $arg_hash->{SSL_ca_path} ||= undef; } # add library defaults $arg_hash->{SSL_use_cert} = $is_server if ! defined $arg_hash->{SSL_use_cert}; # Avoid passing undef arguments to Net::SSLeay defined($arg_hash->{$_}) or delete($arg_hash->{$_}) for(keys %$arg_hash); # check SSL CA, cert etc arguments # some apps set keys '' to signal that it is not set, replace with undef for (qw( SSL_cert SSL_cert_file SSL_key SSL_key_file SSL_ca SSL_ca_file SSL_ca_path SSL_fingerprint )) { $arg_hash->{$_} = undef if defined $arg_hash->{$_} and $arg_hash->{$_} eq ''; } for(qw(SSL_cert_file SSL_key_file)) { defined( my $file = $arg_hash->{$_} ) or next; for my $f (ref($file) eq 'HASH' ? values(%$file):$file ) { die "$_ $f can't be used: $!" if ! open(my $fh,'<',$f) } } my $verify_mode = $arg_hash->{SSL_verify_mode} || 0; if ( $verify_mode != $Net_SSLeay_VERIFY_NONE) { for (qw(SSL_ca_file SSL_ca_path)) { $CHECK_SSL_PATH->($_ => $arg_hash->{$_} || next); } } elsif ( $verify_mode ne '0' ) { # some users use the string 'SSL_VERIFY_PEER' instead of the constant die "SSL_verify_mode must be a number and not a string"; } my $self = bless {},$class; my $vcn_scheme = delete $arg_hash->{SSL_verifycn_scheme}; my $vcn_publicsuffix = delete $arg_hash->{SSL_verifycn_publicsuffix}; if ( ! $is_server and $verify_mode & 0x01 and ! $vcn_scheme || $vcn_scheme ne 'none' ) { # gets updated during configure_SSL my $verify_name; $self->{verify_name_ref} = \$verify_name; my $vcb = $arg_hash->{SSL_verify_callback}; $arg_hash->{SSL_verify_callback} = sub { my ($ok,$ctx_store,$certname,$error,$cert,$depth) = @_; $ok = $vcb->($ok,$ctx_store,$certname,$error,$cert,$depth) if $vcb; $ok or return 0; return $ok if $depth != 0; my $host = $verify_name || ref($vcn_scheme) && $vcn_scheme->{callback} && 'unknown'; if ( ! $host ) { if ( $vcn_scheme ) { IO::Socket::SSL->_internal_error( "Cannot determine peer hostname for verification",8); return 0; } warn "Cannot determine hostname of peer for verification. ". "Disabling default hostname verification for now. ". "Please specify hostname with SSL_verifycn_name and better set SSL_verifycn_scheme too.\n"; return $ok; } elsif ( ! $vcn_scheme && $host =~m{^[\d.]+$|:} ) { # don't try to verify IP by default return $ok; } # verify name my $rv = IO::Socket::SSL::verify_hostname_of_cert( $host,$cert,$vcn_scheme,$vcn_publicsuffix ); if ( ! $rv ) { IO::Socket::SSL->_internal_error( "hostname verification failed",5); } return $rv; }; } if ($is_server) { if ($arg_hash->{SSL_ticket_keycb} && !$can_tckt_keycb) { warn "Ticket Key Callback is not supported - ignoring option SSL_ticket_keycb\n"; delete $arg_hash->{SSL_ticket_keycb}; } } my $ssl_op = $DEFAULT_SSL_OP; my $ver = ''; for (split(/\s*:\s*/,$arg_hash->{SSL_version})) { m{^(!?)(?:(SSL(?:v2|v3|v23|v2/3))|(TLSv1(?:_?[123])?))$}i or croak("invalid SSL_version specified"); my $not = $1; ( my $v = lc($2||$3) ) =~s{^(...)}{\U$1}; if ( $not ) { $ssl_op |= $SSL_OP_NO{$v}; } else { croak("cannot set multiple SSL protocols in SSL_version") if $ver && $v ne $ver; $ver = $v; $ver =~s{/}{}; # interpret SSLv2/3 as SSLv23 $ver =~s{(TLSv1)(\d)}{$1\_$2}; # TLSv1_1 } } my $ctx_new_sub = $ver eq 'TLSv1_3' ? $CTX_tlsv1_3_new : UNIVERSAL::can( 'Net::SSLeay', $ver eq 'SSLv2' ? 'CTX_v2_new' : $ver eq 'SSLv3' ? 'CTX_v3_new' : $ver eq 'TLSv1' ? 'CTX_tlsv1_new' : $ver eq 'TLSv1_1' ? 'CTX_tlsv1_1_new' : $ver eq 'TLSv1_2' ? 'CTX_tlsv1_2_new' : 'CTX_new' ) or return IO::Socket::SSL->_internal_error("SSL Version $ver not supported",9); # For SNI in server mode we need a separate context for each certificate. my %ctx; if ($is_server) { my %sni; for my $opt (qw(SSL_key SSL_key_file SSL_cert SSL_cert_file)) { my $val = $arg_hash->{$opt} or next; if ( ref($val) eq 'HASH' ) { while ( my ($host,$v) = each %$val ) { $sni{lc($host)}{$opt} = $v; } } } while (my ($host,$v) = each %sni) { $ctx{$host} = $host =~m{%} ? $v : { %$arg_hash, %$v }; } } $ctx{''} = $arg_hash if ! %ctx; for my $host (sort keys %ctx) { my $arg_hash = delete $ctx{$host}; my $ctx; if ($host =~m{^([^%]*)%}) { $ctx = $ctx{$1} or return IO::Socket::SSL->error( "SSL Context init for $host failed - no config for $1"); if (my @k = grep { !m{^SSL_(?:cert|key)(?:_file)?$} } keys %$arg_hash) { return IO::Socket::SSL->error( "invalid keys @k in configuration '$host' of additional certs"); } $can_multi_cert or return IO::Socket::SSL->error( "no support for both RSA and ECC certificate in same context"); $host = $1; goto just_configure_certs; } $ctx = $ctx_new_sub->() or return IO::Socket::SSL->error("SSL Context init failed"); $CTX_CREATED_IN_THIS_THREAD{$ctx} = 1 if $use_threads; $ctx{$host} = $ctx; # replace value in %ctx with real context # SSL_OP_CIPHER_SERVER_PREFERENCE $ssl_op |= 0x00400000 if $arg_hash->{SSL_honor_cipher_order}; if ($ver eq 'SSLv23' && !($ssl_op & $SSL_OP_NO{SSLv3})) { # At least LibreSSL disables SSLv3 by default in SSL_CTX_new. # If we really want SSL3.0 we need to explicitly allow it with # SSL_CTX_clear_options. Net::SSLeay::CTX_clear_options($ctx,$SSL_OP_NO{SSLv3}); } Net::SSLeay::CTX_set_options($ctx,$ssl_op); # enable X509_V_FLAG_PARTIAL_CHAIN if possible (OpenSSL 1.1.0+) $check_partial_chain && $check_partial_chain->($ctx); # if we don't set session_id_context if client certificate is expected # client session caching will fail # if user does not provide explicit id just use the stringification # of the context if($arg_hash->{SSL_server} and my $id = $arg_hash->{SSL_session_id_context} || ( $arg_hash->{SSL_verify_mode} & 0x01 ) && "$ctx" ) { Net::SSLeay::CTX_set_session_id_context($ctx,$id,length($id)); } # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER makes syswrite return if at least one # buffer was written and not block for the rest # SSL_MODE_ENABLE_PARTIAL_WRITE can be necessary for non-blocking because we # cannot guarantee, that the location of the buffer stays constant Net::SSLeay::CTX_set_mode( $ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|SSL_MODE_ENABLE_PARTIAL_WRITE); if ( my $proto_list = $arg_hash->{SSL_npn_protocols} ) { return IO::Socket::SSL->_internal_error("NPN not supported in Net::SSLeay",9) if ! $can_npn; if($arg_hash->{SSL_server}) { # on server side SSL_npn_protocols means a list of advertised protocols Net::SSLeay::CTX_set_next_protos_advertised_cb($ctx, $proto_list); } else { # on client side SSL_npn_protocols means a list of preferred protocols # negotiation algorithm used is "as-openssl-implements-it" Net::SSLeay::CTX_set_next_proto_select_cb($ctx, $proto_list); } } if ( my $proto_list = $arg_hash->{SSL_alpn_protocols} ) { return IO::Socket::SSL->_internal_error("ALPN not supported in Net::SSLeay",9) if ! $can_alpn; if($arg_hash->{SSL_server}) { Net::SSLeay::CTX_set_alpn_select_cb($ctx, $proto_list); } else { Net::SSLeay::CTX_set_alpn_protos($ctx, $proto_list); } } if ($arg_hash->{SSL_ticket_keycb}) { my $cb = $arg_hash->{SSL_ticket_keycb}; ($cb,my $arg) = ref($cb) eq 'CODE' ? ($cb):@$cb; Net::SSLeay::CTX_set_tlsext_ticket_getkey_cb($ctx,$cb,$arg); } # Try to apply SSL_ca even if SSL_verify_mode is 0, so that they can be # used to verify OCSP responses. # If applying fails complain only if verify_mode != VERIFY_NONE. if ( $arg_hash->{SSL_ca} || defined $arg_hash->{SSL_ca_file} || defined $arg_hash->{SSL_ca_path} ) { my $file = $arg_hash->{SSL_ca_file}; $file = undef if ref($file) eq 'SCALAR' && ! $$file; my $dir = $arg_hash->{SSL_ca_path}; $dir = undef if ref($dir) eq 'SCALAR' && ! $$dir; if ( $arg_hash->{SSL_ca} ) { my $store = Net::SSLeay::CTX_get_cert_store($ctx); for (@{$arg_hash->{SSL_ca}}) { Net::SSLeay::X509_STORE_add_cert($store,$_) or return IO::Socket::SSL->error( "Failed to add certificate to CA store"); } } $dir = join($OPENSSL_LIST_SEPARATOR,@$dir) if ref($dir); if ( $file || $dir and ! Net::SSLeay::CTX_load_verify_locations( $ctx, $file || '', $dir || '')) { return IO::Socket::SSL->error( "Invalid certificate authority locations") if $verify_mode != $Net_SSLeay_VERIFY_NONE; } } elsif ( my %ca = IO::Socket::SSL::default_ca()) { # no CA path given, continue with system defaults my $dir = $ca{SSL_ca_path}; $dir = join($OPENSSL_LIST_SEPARATOR,@$dir) if ref($dir); if (! Net::SSLeay::CTX_load_verify_locations( $ctx, $ca{SSL_ca_file} || '',$dir || '') && $verify_mode != $Net_SSLeay_VERIFY_NONE) { return IO::Socket::SSL->error( "Invalid default certificate authority locations") } } if ($is_server && ($verify_mode & $Net_SSLeay_VERIFY_PEER)) { if ($arg_hash->{SSL_client_ca}) { for (@{$arg_hash->{SSL_client_ca}}) { return IO::Socket::SSL->error( "Failed to add certificate to client CA list") if ! Net::SSLeay::CTX_add_client_CA($ctx,$_); } } if ($arg_hash->{SSL_client_ca_file}) { my $list = Net::SSLeay::load_client_CA_file( $arg_hash->{SSL_client_ca_file}) or return IO::Socket::SSL->error( "Failed to load certificate to client CA list"); Net::SSLeay::CTX_set_client_CA_list($ctx,$list); } } my $X509_STORE_flags = $DEFAULT_X509_STORE_flags; if ($arg_hash->{'SSL_check_crl'}) { $X509_STORE_flags |= Net::SSLeay::X509_V_FLAG_CRL_CHECK(); if ($arg_hash->{'SSL_crl_file'}) { my $bio = Net::SSLeay::BIO_new_file($arg_hash->{'SSL_crl_file'}, 'r'); my $crl = Net::SSLeay::PEM_read_bio_X509_CRL($bio); Net::SSLeay::BIO_free($bio); if ( $crl ) { Net::SSLeay::X509_STORE_add_crl(Net::SSLeay::CTX_get_cert_store($ctx), $crl); Net::SSLeay::X509_CRL_free($crl); } else { return IO::Socket::SSL->error("Invalid certificate revocation list"); } } } Net::SSLeay::X509_STORE_set_flags( Net::SSLeay::CTX_get_cert_store($ctx), $X509_STORE_flags ) if $X509_STORE_flags; Net::SSLeay::CTX_set_default_passwd_cb($ctx,$arg_hash->{SSL_passwd_cb}) if $arg_hash->{SSL_passwd_cb}; just_configure_certs: my ($havekey,$havecert); if ( my $x509 = $arg_hash->{SSL_cert} ) { # binary, e.g. X509* # we have either a single certificate or a list with # a chain of certificates my @x509 = ref($x509) eq 'ARRAY' ? @$x509: ($x509); my $cert = shift @x509; Net::SSLeay::CTX_use_certificate( $ctx,$cert ) || return IO::Socket::SSL->error("Failed to use Certificate"); foreach my $ca (@x509) { Net::SSLeay::CTX_add_extra_chain_cert( $ctx,$ca ) || return IO::Socket::SSL->error("Failed to use Certificate"); } $havecert = 'OBJ'; } elsif ( my $f = $arg_hash->{SSL_cert_file} ) { # try to load chain from PEM or certificate from ASN1 if (Net::SSLeay::CTX_use_certificate_chain_file($ctx,$f)) { $havecert = 'PEM'; } elsif (Net::SSLeay::CTX_use_certificate_file($ctx,$f,FILETYPE_ASN1)) { $havecert = 'DER'; } else { # try to load certificate, key and chain from PKCS12 file my ($key,$cert,@chain) = Net::SSLeay::P_PKCS12_load_file($f,1); if (!$cert and $arg_hash->{SSL_passwd_cb} and defined( my $pw = $arg_hash->{SSL_passwd_cb}->(0))) { ($key,$cert,@chain) = Net::SSLeay::P_PKCS12_load_file($f,1,$pw); } PKCS12: while ($cert) { Net::SSLeay::CTX_use_certificate($ctx,$cert) or last; # Net::SSLeay::P_PKCS12_load_file is implemented using # OpenSSL PKCS12_parse which according to the source code # returns the chain with the last CA certificate first (i.e. # reverse order as in the PKCS12 file). This is not # documented but given the age of this function we'll assume # that this will stay this way in the future. while (my $ca = pop @chain) { Net::SSLeay::CTX_add_extra_chain_cert($ctx,$ca) or last PKCS12; } last if $key && ! Net::SSLeay::CTX_use_PrivateKey($ctx,$key); $havecert = 'PKCS12'; last; } $havekey = 'PKCS12' if $key; Net::SSLeay::X509_free($cert) if $cert; Net::SSLeay::EVP_PKEY_free($key) if $key; # don't free @chain, because CTX_add_extra_chain_cert # did not duplicate the certificates } $havecert or return IO::Socket::SSL->error( "Failed to load certificate from file (no PEM, DER or PKCS12)"); } if (!$havecert || $havekey) { # skip SSL_key_* } elsif ( my $pkey = $arg_hash->{SSL_key} ) { # binary, e.g. EVP_PKEY* Net::SSLeay::CTX_use_PrivateKey($ctx, $pkey) || return IO::Socket::SSL->error("Failed to use Private Key"); $havekey = 'MEM'; } elsif ( my $f = $arg_hash->{SSL_key_file} || (($havecert eq 'PEM') ? $arg_hash->{SSL_cert_file}:undef) ) { for my $ft ( FILETYPE_PEM, FILETYPE_ASN1 ) { if (Net::SSLeay::CTX_use_PrivateKey_file($ctx,$f,$ft)) { $havekey = ($ft == FILETYPE_PEM) ? 'PEM':'DER'; last; } } $havekey or return IO::Socket::SSL->error( "Failed to load key from file (no PEM or DER)"); } Net::SSLeay::CTX_set_post_handshake_auth($ctx,1) if (!$is_server && $can_pha && $havecert && $havekey); } if ($arg_hash->{SSL_server}) { if ( my $f = $arg_hash->{SSL_dh_file} ) { my $bio = Net::SSLeay::BIO_new_file( $f,'r' ) || return IO::Socket::SSL->error( "Failed to open DH file $f" ); my $dh = Net::SSLeay::PEM_read_bio_DHparams($bio); Net::SSLeay::BIO_free($bio); $dh || return IO::Socket::SSL->error( "Failed to read PEM for DH from $f - wrong format?" ); my $rv; for (values (%ctx)) { $rv = Net::SSLeay::CTX_set_tmp_dh( $_,$dh ) or last; } Net::SSLeay::DH_free( $dh ); $rv || return IO::Socket::SSL->error( "Failed to set DH from $f" ); } elsif ( my $dh = $arg_hash->{SSL_dh} ) { # binary, e.g. DH* for( values %ctx ) { Net::SSLeay::CTX_set_tmp_dh( $_,$dh ) || return IO::Socket::SSL->error( "Failed to set DH from SSL_dh" ); } } } if ( my $curve = $arg_hash->{SSL_ecdh_curve} ) { return IO::Socket::SSL->_internal_error( "ECDH curve needs Net::SSLeay>=1.56 and OpenSSL>=1.0",9) if ! $can_ecdh; for(values %ctx) { if ($arg_hash->{SSL_server} and $curve eq 'auto') { if ($can_ecdh eq 'can_auto') { Net::SSLeay::CTX_set_ecdh_auto($_,1) or return IO::Socket::SSL->error( "failed to set ECDH curve context"); } elsif ($can_ecdh eq 'auto') { # automatically enabled anyway } else { return IO::Socket::SSL->error( "SSL_CTX_set_ecdh_auto not implemented"); } } elsif ($set_groups_list) { $set_groups_list->($_,$curve) or return IO::Socket::SSL->error( "failed to set ECDH groups/curves on context"); # needed for OpenSSL 1.0.2 if ($can_ecdh eq 'can_auto') { Net::SSLeay::CTX_set_ecdh_auto($_,1) if $can_ecdh eq 'can_auto'; } elsif ($curve =~m{:}) { return IO::Socket::SSL->error( "SSL_CTX_groups_list or SSL_CTX_curves_list not implemented"); } elsif ($arg_hash->{SSL_server}) { if ( $curve !~ /^\d+$/ ) { # name of curve, find NID $curve = Net::SSLeay::OBJ_txt2nid($curve) || return IO::Socket::SSL->error( "cannot find NID for curve name '$curve'"); } my $ecdh = Net::SSLeay::EC_KEY_new_by_curve_name($curve) or return IO::Socket::SSL->error( "cannot create curve for NID $curve"); for( values %ctx ) { Net::SSLeay::CTX_set_tmp_ecdh($_,$ecdh) or return IO::Socket::SSL->error( "failed to set ECDH curve context"); } Net::SSLeay::EC_KEY_free($ecdh); } } } my $verify_cb = $arg_hash->{SSL_verify_callback}; my @accept_fp; if ( my $fp = $arg_hash->{SSL_fingerprint} ) { for( ref($fp) ? @$fp : $fp) { my ($algo,$pubkey,$digest) = m{^(?:([\w-]+)\$)?(pub\$)?([a-f\d:]+)$}i or return IO::Socket::SSL->_internal_error("invalid fingerprint '$_'",9); ( $digest = lc($digest) ) =~s{:}{}g; $algo ||= length($digest) == 32 ? 'md5' : length($digest) == 40 ? 'sha1' : length($digest) == 64 ? 'sha256' : return IO::Socket::SSL->_internal_error( "cannot detect hash algorithem from fingerprint '$_'",9); $algo = lc($algo); push @accept_fp,[ $algo, $pubkey || '', pack('H*',$digest) ] } } my $verify_fingerprint = @accept_fp && do { my $fail; sub { my ($ok,$cert,$depth) = @_; $fail = 1 if ! $ok; return 1 if $depth>0; # to let us continue with verification # Check fingerprint only from top certificate. my %fp; for(@accept_fp) { my $fp = $fp{$_->[0],$_->[1]} ||= $_->[1] ? Net::SSLeay::X509_pubkey_digest($cert,$algo2digest->($_->[0])) : Net::SSLeay::X509_digest($cert,$algo2digest->($_->[0])); next if $fp ne $_->[2]; return 1; } return ! $fail; } }; my $verify_callback = ( $verify_cb || @accept_fp ) && sub { my ($ok, $ctx_store) = @_; my ($certname,$cert,$error,$depth); if ($ctx_store) { $cert = Net::SSLeay::X509_STORE_CTX_get_current_cert($ctx_store); $error = Net::SSLeay::X509_STORE_CTX_get_error($ctx_store); $depth = Net::SSLeay::X509_STORE_CTX_get_error_depth($ctx_store); $certname = Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_issuer_name($cert)). Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_subject_name($cert)); $error &&= Net::SSLeay::ERR_error_string($error); } $DEBUG>=3 && DEBUG( "ok=$ok [$depth] $certname" ); $ok = $verify_cb->($ok,$ctx_store,$certname,$error,$cert,$depth) if $verify_cb; $ok = $verify_fingerprint->($ok,$cert,$depth) if $verify_fingerprint && $cert; return $ok; }; if ( $^O eq 'darwin' ) { # explicitly set error code to disable use of apples TEA patch # https://hynek.me/articles/apple-openssl-verification-surprises/ my $vcb = $verify_callback; $verify_callback = sub { my $rv = $vcb ? &$vcb : $_[0]; if ( $rv != 1 ) { # 50 - X509_V_ERR_APPLICATION_VERIFICATION: application verification failure Net::SSLeay::X509_STORE_CTX_set_error($_[1], 50); } return $rv; }; } Net::SSLeay::CTX_set_verify($_, $verify_mode, $verify_callback) for (values %ctx); my $staple_callback = $arg_hash->{SSL_ocsp_staple_callback}; if ( !$is_server && $can_ocsp_staple && ! $verify_fingerprint) { $self->{ocsp_cache} = $arg_hash->{SSL_ocsp_cache}; my $status_cb = sub { my ($ssl,$resp) = @_; my $iossl = $SSL_OBJECT{$ssl} or die "no IO::Socket::SSL object found for SSL $ssl"; $iossl->[1] and do { # we must return with 1 or it will be called again # and because we have no SSL object we must make the error global Carp::cluck($IO::Socket::SSL::SSL_ERROR = "OCSP callback on server side"); return 1; }; $iossl = $iossl->[0]; # if we have a callback use this # callback must not free or copy $resp !! if ( $staple_callback ) { $staple_callback->($iossl,$resp); return 1; } # default callback does verification if ( ! $resp ) { $DEBUG>=3 && DEBUG("did not get stapled OCSP response"); return 1; } $DEBUG>=3 && DEBUG("got stapled OCSP response"); my $status = Net::SSLeay::OCSP_response_status($resp); if ($status != Net::SSLeay::OCSP_RESPONSE_STATUS_SUCCESSFUL()) { $DEBUG>=3 && DEBUG("bad status of stapled OCSP response: ". Net::SSLeay::OCSP_response_status_str($status)); return 1; } if (!eval { Net::SSLeay::OCSP_response_verify($ssl,$resp) }) { $DEBUG>=3 && DEBUG("verify of stapled OCSP response failed"); return 1; } my (@results,$hard_error); my @chain = $iossl->peer_certificates; for my $cert (@chain) { my $certid = eval { Net::SSLeay::OCSP_cert2ids($ssl,$cert) }; if (!$certid) { $DEBUG>=3 && DEBUG("cannot create OCSP_CERTID: $@"); push @results,[-1,$@]; last; } ($status) = Net::SSLeay::OCSP_response_results($resp,$certid); if ($status && $status->[2]) { my $cache = ${*$iossl}{_SSL_ctx}{ocsp_cache}; if (!$status->[1]) { push @results,[1,$status->[2]{nextUpdate}]; $cache && $cache->put($certid,$status->[2]); } elsif ( $status->[2]{statusType} == Net::SSLeay::V_OCSP_CERTSTATUS_GOOD()) { push @results,[1,$status->[2]{nextUpdate}]; $cache && $cache->put($certid,{ %{$status->[2]}, expire => time()+120, soft_error => $status->[1], }); } else { push @results,($hard_error = [0,$status->[1]]); $cache && $cache->put($certid,{ %{$status->[2]}, hard_error => $status->[1], }); } } } # return result of lead certificate, this should be in chain[0] and # thus result[0], but we better check. But if we had any hard_error # return this instead if ($hard_error) { ${*$iossl}{_SSL_ocsp_verify} = $hard_error; } elsif (@results and $chain[0] == $iossl->peer_certificate) { ${*$iossl}{_SSL_ocsp_verify} = $results[0]; } return 1; }; Net::SSLeay::CTX_set_tlsext_status_cb($_,$status_cb) for (values %ctx); } if ( my $cl = $arg_hash->{SSL_cipher_list} ) { for (keys %ctx) { Net::SSLeay::CTX_set_cipher_list($ctx{$_}, ref($cl) ? $cl->{$_} || $cl->{''} || $DEFAULT_SSL_ARGS{SSL_cipher_list} || next : $cl ) || return IO::Socket::SSL->error("Failed to set SSL cipher list"); } } # Main context is default context or any other if no default context. my $ctx = $ctx{''} || (values %ctx)[0]; if (keys(%ctx) > 1 || ! exists $ctx{''}) { $can_server_sni or return IO::Socket::SSL->_internal_error( "Server side SNI not supported for this openssl/Net::SSLeay",9); Net::SSLeay::CTX_set_tlsext_servername_callback($ctx, sub { my $ssl = shift; my $host = Net::SSLeay::get_servername($ssl); $host = '' if ! defined $host; my $snictx = $ctx{lc($host)} || $ctx{''} or do { $DEBUG>1 and DEBUG( "cannot get context from servername '$host'"); return 0; }; $DEBUG>1 and DEBUG("set context from servername $host"); Net::SSLeay::set_SSL_CTX($ssl,$snictx) if $snictx != $ctx; return 1; }); } if ( my $cb = $arg_hash->{SSL_create_ctx_callback} ) { $cb->($_) for values (%ctx); } $self->{context} = $ctx; $self->{verify_mode} = $arg_hash->{SSL_verify_mode}; $self->{ocsp_mode} = defined($arg_hash->{SSL_ocsp_mode}) ? $arg_hash->{SSL_ocsp_mode} : $self->{verify_mode} ? IO::Socket::SSL::SSL_OCSP_TRY_STAPLE() : 0; $DEBUG>=3 && DEBUG( "new ctx $ctx" ); if ( my $cache = $arg_hash->{SSL_session_cache} ) { # use predefined cache $self->{session_cache} = $cache } elsif ( my $size = $arg_hash->{SSL_session_cache_size}) { $self->{session_cache} = IO::Socket::SSL::Session_Cache->new( $size ); } if ($self->{session_cache} and %sess_cb) { Net::SSLeay::CTX_set_session_cache_mode($ctx, Net::SSLeay::SESS_CACHE_CLIENT()); my $cache = $self->{session_cache}; $sess_cb{new}($ctx, sub { my ($ssl,$session) = @_; my $self = ($SSL_OBJECT{$ssl} || do { warn "callback session new: no known SSL object for $ssl"; return; })->[0]; my $args = ${*$self}{_SSL_arguments}; my $key = $args->{SSL_session_key} or do { warn "callback session new: no known SSL_session_key for $ssl"; return; }; $DEBUG>=3 && DEBUG("callback session new <$key> $session"); Net::SSLeay::SESSION_up_ref($session); $cache->add_session($key,$session); }); $sess_cb{remove}($ctx, sub { my ($ctx,$session) = @_; $DEBUG>=3 && DEBUG("callback session remove $session"); $cache->del_session(undef,$session); }); } return $self; } sub has_session_cache { return defined shift->{session_cache}; } sub CLONE { %CTX_CREATED_IN_THIS_THREAD = (); } sub DESTROY { my $self = shift; if ( my $ctx = $self->{context} ) { $DEBUG>=3 && DEBUG("free ctx $ctx open=".join( " ",keys %CTX_CREATED_IN_THIS_THREAD )); if (!$use_threads or delete $CTX_CREATED_IN_THIS_THREAD{$ctx} ) { # remove any verify callback for this context if ( $self->{verify_mode}) { $DEBUG>=3 && DEBUG("free ctx $ctx callback" ); Net::SSLeay::CTX_set_verify($ctx, 0,undef); } if ( $self->{ocsp_error_ref}) { $DEBUG>=3 && DEBUG("free ctx $ctx tlsext_status_cb" ); Net::SSLeay::CTX_set_tlsext_status_cb($ctx,undef); } $DEBUG>=3 && DEBUG("OK free ctx $ctx" ); Net::SSLeay::CTX_free($ctx); } } delete(@{$self}{'context','session_cache'}); } package IO::Socket::SSL::Session_Cache; *DEBUG = *IO::Socket::SSL::DEBUG; use constant { SESSION => 0, KEY => 1, GNEXT => 2, GPREV => 3, SNEXT => 4, SPREV => 5, }; sub new { my ($class, $size) = @_; $size>0 or return; return bless { room => $size, ghead => undef, shead => {}, }, $class; } sub add_session { my ($self, $key, $session) = @_; # create new my $v = []; $v->[SESSION] = $session; $v->[KEY] = $key; $DEBUG>=3 && DEBUG("add_session($key,$session)"); _add_entry($self,$v); } sub replace_session { my ($self, $key, $session) = @_; $self->del_session($key); $self->add_session($key, $session); } sub del_session { my ($self, $key, $session) = @_; my ($head,$inext) = $key ? ($self->{shead}{$key},SNEXT) : ($self->{ghead},GNEXT); my $v = $head; my @del; while ($v) { if (!$session) { push @del,$v } elsif ($v->[SESSION] == $session) { push @del, $v; last; } $v = $v->[$inext]; last if $v == $head; } $DEBUG>=3 && DEBUG("del_session(" . ($key ? $key : "undef") . ($session ? ",$session) -> " : ") -> ") . (~~@del || 'none')); for (@del) { _del_entry($self,$_); Net::SSLeay::SESSION_free($_->[SESSION]) if $_->[SESSION]; } return ~~@del; } sub get_session { my ($self, $key, $session) = @_; my $v = $self->{shead}{$key}; if ($session) { my $shead = $v; while ($v) { $DEBUG>=3 && DEBUG("check $session - $v->[SESSION]"); last if $v->[SESSION] == $session; $v = $v->[SNEXT]; $v = undef if $v == $shead; # session not found } } if ($v) { _del_entry($self, $v); # remove _add_entry($self, $v); # and add back on top } $DEBUG>=3 && DEBUG("get_session($key" . ( $session ? ",$session) -> " : ") -> ") . ($v? $v->[SESSION]:"none")); return $v && $v->[SESSION]; } sub _add_entry { my ($self,$v) = @_; for( [ SNEXT, SPREV, \$self->{shead}{$v->[KEY]} ], [ GNEXT, GPREV, \$self->{ghead} ], ) { my ($inext,$iprev,$rhead) = @$_; if ($$rhead) { $v->[$inext] = $$rhead; $v->[$iprev] = ${$rhead}->[$iprev]; ${$rhead}->[$iprev][$inext] = $v; ${$rhead}->[$iprev] = $v; } else { $v->[$inext] = $v->[$iprev] = $v; } $$rhead = $v; } $self->{room}--; # drop old entries if necessary if ($self->{room}<0) { my $l = $self->{ghead}[GPREV]; _del_entry($self,$l); Net::SSLeay::SESSION_free($l->[SESSION]) if $l->[SESSION]; } } sub _del_entry { my ($self,$v) = @_; for( [ SNEXT, SPREV, \$self->{shead}{$v->[KEY]} ], [ GNEXT, GPREV, \$self->{ghead} ], ) { my ($inext,$iprev,$rhead) = @$_; $$rhead or return; $v->[$inext][$iprev] = $v->[$iprev]; $v->[$iprev][$inext] = $v->[$inext]; if ($v != $$rhead) { # not removed from top of list } elsif ($v->[$inext] == $v) { # was only element on list, drop list if ($inext == SNEXT) { delete $self->{shead}{$v->[KEY]}; } else { $$rhead = undef; } } else { # was top element, keep others $$rhead = $v->[$inext]; } } $self->{room}++; } sub _dump { my $self = shift; my %v2i; my $v = $self->{ghead}; while ($v) { exists $v2i{$v} and die; $v2i{$v} = int(keys %v2i); $v = $v->[GNEXT]; last if $v == $self->{ghead}; } my $out = "room: $self->{room}\nghead:\n"; $v = $self->{ghead}; while ($v) { $out .= sprintf(" - [%d] <%d,%d> '%s' <%s>\n", $v2i{$v}, $v2i{$v->[GPREV]}, $v2i{$v->[GNEXT]}, $v->[KEY], $v->[SESSION]); $v = $v->[GNEXT]; last if $v == $self->{ghead}; } $out .= "shead:\n"; for my $key (sort keys %{$self->{shead}}) { $out .= " - '$key'\n"; my $shead = $self->{shead}{$key}; my $v = $shead; while ($v) { $out .= sprintf(" - [%d] <%d,%d> '%s' <%s>\n", $v2i{$v}, $v2i{$v->[SPREV]}, $v2i{$v->[SNEXT]}, $v->[KEY], $v->[SESSION]); $v = $v->[SNEXT]; last if $v == $shead; } } return $out; } sub DESTROY { my $self = shift; delete $self->{shead}; my $v = delete $self->{ghead}; while ($v) { Net::SSLeay::SESSION_free($v->[SESSION]) if $v->[SESSION]; my $next = $v->[GNEXT]; @$v = (); $v = $next; } } package IO::Socket::SSL::OCSP_Cache; sub new { my ($class,$size) = @_; return bless { '' => { _lru => 0, size => $size || 100 } },$class; } sub get { my ($self,$id) = @_; my $e = $self->{$id} or return; $e->{_lru} = $self->{''}{_lru}++; if ( $e->{expire} && time()<$e->{expire}) { delete $self->{$id}; return; } if ( $e->{nextUpdate} && time()<$e->{nextUpdate} ) { delete $self->{$id}; return; } return $e; } sub put { my ($self,$id,$e) = @_; $self->{$id} = $e; $e->{_lru} = $self->{''}{_lru}++; my $del = keys(%$self) - $self->{''}{size}; if ($del>0) { my @k = sort { $self->{$a}{_lru} <=> $self->{$b}{_lru} } keys %$self; delete @{$self}{ splice(@k,0,$del) }; } return $e; } package IO::Socket::SSL::OCSP_Resolver; *DEBUG = *IO::Socket::SSL::DEBUG; # create a new resolver # $ssl - the ssl object # $cache - OCSP_Cache object (put,get) # $failhard - flag if we should fail hard on OCSP problems # $certs - list of certs to verify sub new { my ($class,$ssl,$cache,$failhard,$certs) = @_; my (%todo,$done,$hard_error,@soft_error); for my $cert (@$certs) { # skip entries which have no OCSP uri or where we cannot get a certid # (e.g. self-signed or where we don't have the issuer) my $subj = Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_subject_name($cert)); my $uri = Net::SSLeay::P_X509_get_ocsp_uri($cert) or do { $DEBUG>2 && DEBUG("no URI for certificate $subj"); push @soft_error,"no ocsp_uri for $subj"; next; }; my $certid = eval { Net::SSLeay::OCSP_cert2ids($ssl,$cert) } or do { $DEBUG>2 && DEBUG("no OCSP_CERTID for certificate $subj: $@"); push @soft_error,"no certid for $subj: $@"; next; }; if (!($done = $cache->get($certid))) { push @{ $todo{$uri}{ids} }, $certid; push @{ $todo{$uri}{subj} }, $subj; } elsif ( $done->{hard_error} ) { # one error is enough to fail validation $hard_error = $done->{hard_error}; %todo = (); last; } elsif ( $done->{soft_error} ) { push @soft_error,$done->{soft_error}; } } while ( my($uri,$v) = each %todo) { my $ids = $v->{ids}; $v->{req} = Net::SSLeay::i2d_OCSP_REQUEST( Net::SSLeay::OCSP_ids2req(@$ids)); } $hard_error ||= '' if ! %todo; return bless { ssl => $ssl, cache => $cache, failhard => $failhard, hard_error => $hard_error, soft_error => @soft_error ? join("; ",@soft_error) : undef, todo => \%todo, },$class; } # return current result, e.g. '' for no error, else error # if undef we have no final result yet sub hard_error { return shift->{hard_error} } sub soft_error { return shift->{soft_error} } # return hash with uri => ocsp_request_data for open requests sub requests { my $todo = shift()->{todo}; return map { ($_,$todo->{$_}{req}) } keys %$todo; } # add new response sub add_response { my ($self,$uri,$resp) = @_; my $todo = delete $self->{todo}{$uri}; return $self->{error} if ! $todo || $self->{error}; my ($req,@soft_error,@hard_error); # do we have a response if (!$resp) { @soft_error = "http request for OCSP failed; subject: ". join("; ",@{$todo->{subj}}); # is it a valid OCSP_RESPONSE } elsif ( ! eval { $resp = Net::SSLeay::d2i_OCSP_RESPONSE($resp) }) { @soft_error = "invalid response (no OCSP_RESPONSE); subject: ". join("; ",@{$todo->{subj}}); # hopefully short-time error $self->{cache}->put($_,{ soft_error => "@soft_error", expire => time()+10, }) for (@{$todo->{ids}}); # is the OCSP response status success } elsif ( ( my $status = Net::SSLeay::OCSP_response_status($resp)) != Net::SSLeay::OCSP_RESPONSE_STATUS_SUCCESSFUL() ){ @soft_error = "OCSP response failed: ". Net::SSLeay::OCSP_response_status_str($status). "; subject: ".join("; ",@{$todo->{subj}}); # hopefully short-time error $self->{cache}->put($_,{ soft_error => "@soft_error", expire => time()+10, }) for (@{$todo->{ids}}); # does nonce match the request and can the signature be verified } elsif ( ! eval { $req = Net::SSLeay::d2i_OCSP_REQUEST($todo->{req}); Net::SSLeay::OCSP_response_verify($self->{ssl},$resp,$req); }) { if ($@) { @soft_error = $@ } else { my @err; while ( my $err = Net::SSLeay::ERR_get_error()) { push @soft_error, Net::SSLeay::ERR_error_string($err); } @soft_error = 'failed to verify OCSP response; subject: '. join("; ",@{$todo->{subj}}) if ! @soft_error; } # configuration problem or we don't know the signer $self->{cache}->put($_,{ soft_error => "@soft_error", expire => time()+120, }) for (@{$todo->{ids}}); # extract results from response } elsif ( my @result = Net::SSLeay::OCSP_response_results($resp,@{$todo->{ids}})) { my (@found,@miss); for my $rv (@result) { if ($rv->[2]) { push @found,$rv->[0]; if (!$rv->[1]) { # no error $self->{cache}->put($rv->[0],$rv->[2]); } elsif ( $rv->[2]{statusType} == Net::SSLeay::V_OCSP_CERTSTATUS_GOOD()) { # soft error, like response after nextUpdate push @soft_error,$rv->[1]."; subject: ". join("; ",@{$todo->{subj}}); $self->{cache}->put($rv->[0],{ %{$rv->[2]}, soft_error => "@soft_error", expire => time()+120, }); } else { # hard error $self->{cache}->put($rv->[0],$rv->[2]); push @hard_error, $rv->[1]."; subject: ". join("; ",@{$todo->{subj}}); } } else { push @miss,$rv->[0]; } } if (@miss && @found) { # we sent multiple responses, but server answered only to one # try again $self->{todo}{$uri} = $todo; $todo->{ids} = \@miss; $todo->{req} = Net::SSLeay::i2d_OCSP_REQUEST( Net::SSLeay::OCSP_ids2req(@miss)); $DEBUG>=2 && DEBUG("$uri just answered ".@found." of ".(@found+@miss)." requests"); } } else { @soft_error = "no data in response; subject: ". join("; ",@{$todo->{subj}}); # probably configuration problem $self->{cache}->put($_,{ soft_error => "@soft_error", expire => time()+120, }) for (@{$todo->{ids}}); } Net::SSLeay::OCSP_REQUEST_free($req) if $req; if ($self->{failhard}) { push @hard_error,@soft_error; @soft_error = (); } if (@soft_error) { $self->{soft_error} .= "; " if $self->{soft_error}; $self->{soft_error} .= "$uri: ".join('; ',@soft_error); } if (@hard_error) { $self->{hard_error} = "$uri: ".join('; ',@hard_error); %{$self->{todo}} = (); } elsif ( ! %{$self->{todo}} ) { $self->{hard_error} = '' } return $self->{hard_error}; } # make all necessary requests to get OCSP responses blocking sub resolve_blocking { my ($self,%args) = @_; while ( my %todo = $self->requests ) { eval { require HTTP::Tiny } or die "need HTTP::Tiny installed"; # OCSP responses have their own signature, so we don't need SSL verification my $ua = HTTP::Tiny->new(verify_SSL => 0,%args); while (my ($uri,$reqdata) = each %todo) { $DEBUG && DEBUG("sending OCSP request to $uri"); my $resp = $ua->request('POST',$uri, { headers => { 'Content-type' => 'application/ocsp-request' }, content => $reqdata }); $DEBUG && DEBUG("got OCSP response from $uri code=$resp->{status}"); defined ($self->add_response($uri, $resp->{success} && $resp->{content})) && last; } } $DEBUG>=2 && DEBUG("no more open OCSP requests"); return $self->{hard_error}; } 1; __END__ PKH]^?#SLSLSocket/SSL.podnu[ =head1 NAME IO::Socket::SSL - SSL sockets with IO::Socket interface =head1 SYNOPSIS use strict; use IO::Socket::SSL; # simple client my $cl = IO::Socket::SSL->new('www.google.com:443'); print $cl "GET / HTTP/1.0\r\n\r\n"; print <$cl>; # simple server my $srv = IO::Socket::SSL->new( LocalAddr => '0.0.0.0:1234', Listen => 10, SSL_cert_file => 'server-cert.pem', SSL_key_file => 'server-key.pem', ); $srv->accept; =head1 DESCRIPTION IO::Socket::SSL makes using SSL/TLS much easier by wrapping the necessary functionality into the familiar L interface and providing secure defaults whenever possible. This way, existing applications can be made SSL-aware without much effort, at least if you do blocking I/O and don't use select or poll. But, under the hood, SSL is a complex beast. So there are lots of methods to make it do what you need if the default behavior is not adequate. Because it is easy to inadvertently introduce critical security bugs or just hard to debug problems, I would recommend studying the following documentation carefully. The documentation consists of the following parts: =over 4 =item * L =item * L =item * L =item * L =item * L =item * L =item * L =item * L =item * L =back Additional documentation can be found in =over 4 =item * L - Doing Man-In-The-Middle with SSL =item * L - Useful functions for certificates etc =back =head1 Essential Information About SSL/TLS SSL (Secure Socket Layer) or its successor TLS (Transport Layer Security) are protocols to facilitate end-to-end security. These protocols are used when accessing web sites (https), delivering or retrieving email, and in lots of other use cases. In the following documentation we will refer to both SSL and TLS as simply 'SSL'. SSL enables end-to-end security by providing two essential functions: =over 4 =item Encryption This part encrypts the data for transit between the communicating parties, so that nobody in between can read them. It also provides tamper resistance so that nobody in between can manipulate the data. =item Identification This part makes sure that you talk to the right peer. If the identification is done incorrectly it is easy to mount man-in-the-middle attacks, e.g. if Alice wants to talk to Bob it would be possible for Mallory to put itself in the middle, so that Alice talks to Mallory and Mallory to Bob. All the data would still be encrypted, but not end-to-end between Alice and Bob, but only between Alice and Mallory and then between Mallory and Bob. Thus Mallory would be able to read and modify all traffic between Alice and Bob. =back Identification is the part which is the hardest to understand and the easiest to get wrong. With SSL, the Identification is usually done with B inside a B (Public Key Infrastructure). These Certificates are comparable to an identity card, which contains information about the owner of the card. The card then is somehow B by the B of the card, the B (Certificate Agency). To verify the identity of the peer the following must be done inside SSL: =over 4 =item * Get the certificate from the peer. If the peer does not present a certificate we cannot verify it. =item * Check if we trust the certificate, e.g. make sure it's not a forgery. We believe that a certificate is not a fake if we either know the certificate already or if we B the issuer (the CA) and can verify the issuers signature on the certificate. In reality there is often a hierarchy of certificate agencies and we only directly trust the root of this hierarchy. In this case the peer not only sends his own certificate, but also all B. Verification will be done by building a B from the trusted root up to the peers certificate and checking in each step if the we can verify the issuer's signature. This step often causes problems because the client does not know the necessary trusted root certificates. These are usually stored in a system dependent CA store, but often the browsers have their own CA store. =item * Check if the certificate is still valid. Each certificate has a lifetime and should not be used after that time because it might be compromised or the underlying cryptography got broken in the mean time. =item * Check if the subject of the certificate matches the peer. This is like comparing the picture on the identity card against the person representing the identity card. When connecting to a server this is usually done by comparing the hostname used for connecting against the names represented in the certificate. A certificate might contain multiple names or wildcards, so that it can be used for multiple hosts (e.g. *.example.com and *.example.org). Although nobody sane would accept an identity card where the picture does not match the person we see, it is a common implementation error with SSL to omit this check or get it wrong. =item * Check if the certificate was revoked by the issuer. This might be the case if the certificate was compromised somehow and now somebody else might use it to claim the wrong identity. Such revocations happened a lot after the heartbleed attack. For SSL there are two ways to verify a revocation, CRL and OCSP. With CRLs (Certificate Revocation List) the CA provides a list of serial numbers for revoked certificates. The client somehow has to download the list (which can be huge) and keep it up to date. With OCSP (Online Certificate Status Protocol) the client can check a single certificate directly by asking the issuer. Revocation is the hardest part of the verification and none of today's browsers get it fully correct. But, they are still better than most other implementations which don't implement revocation checks or leave the hard parts to the developer. =back When accessing a web site with SSL or delivering mail in a secure way the identity is usually only checked one way, e.g. the client wants to make sure it talks to the right server, but the server usually does not care which client it talks to. But, sometimes the server wants to identify the client too and will request a certificate from the client which the server must verify in a similar way. =head1 Basic SSL Client A basic SSL client is simple: my $client = IO::Socket::SSL->new('www.example.com:443') or die "error=$!, ssl_error=$SSL_ERROR"; This will take the OpenSSL default CA store as the store for the trusted CA. This usually works on UNIX systems. If there are no certificates in the store it will try use L which provides the default CAs of Firefox. In the default settings, L will use a safer cipher set and SSL version, do a proper hostname check against the certificate, and use SNI (server name indication) to send the hostname inside the SSL handshake. This is necessary to work with servers which have different certificates behind the same IP address. It will also check the revocation of the certificate with OCSP, but currently only if the server provides OCSP stapling (for deeper checks see C method). Lots of options can be used to change ciphers, SSL version, location of CA and much more. See documentation of methods for details. With protocols like SMTP it is necessary to upgrade an existing socket to SSL. This can be done like this: my $client = IO::Socket::INET->new('mx.example.com:25') or die $!; # .. read greeting from server # .. send EHLO and read response # .. send STARTTLS command and read response # .. if response was successful we can upgrade the socket to SSL now: IO::Socket::SSL->start_SSL($client, # explicitly set hostname we should use for SNI SSL_hostname => 'mx.example.com' ) or die $SSL_ERROR; A more complete example for a simple HTTP client: my $client = IO::Socket::SSL->new( # where to connect PeerHost => "www.example.com", PeerPort => "https", # certificate verification - VERIFY_PEER is default SSL_verify_mode => SSL_VERIFY_PEER, # location of CA store # need only be given if default store should not be used SSL_ca_path => '/etc/ssl/certs', # typical CA path on Linux SSL_ca_file => '/etc/ssl/cert.pem', # typical CA file on BSD # or just use default path on system: IO::Socket::SSL::default_ca(), # either explicitly # or implicitly by not giving SSL_ca_* # easy hostname verification # It will use PeerHost as default name a verification # scheme as default, which is safe enough for most purposes. SSL_verifycn_name => 'foo.bar', SSL_verifycn_scheme => 'http', # SNI support - defaults to PeerHost SSL_hostname => 'foo.bar', ) or die "failed connect or ssl handshake: $!,$SSL_ERROR"; # send and receive over SSL connection print $client "GET / HTTP/1.0\r\n\r\n"; print <$client>; And to do revocation checks with OCSP (only available with OpenSSL 1.0.0 or higher and L 1.59 or higher): # default will try OCSP stapling and check only leaf certificate my $client = IO::Socket::SSL->new($dst); # better yet: require checking of full chain my $client = IO::Socket::SSL->new( PeerAddr => $dst, SSL_ocsp_mode => SSL_OCSP_FULL_CHAIN, ); # even better: make OCSP errors fatal # (this will probably fail with lots of sites because of bad OCSP setups) # also use common OCSP response cache my $ocsp_cache = IO::Socket::SSL::OCSP_Cache->new; my $client = IO::Socket::SSL->new( PeerAddr => $dst, SSL_ocsp_mode => SSL_OCSP_FULL_CHAIN|SSL_OCSP_FAIL_HARD, SSL_ocsp_cache => $ocsp_cache, ); # disable OCSP stapling in case server has problems with it my $client = IO::Socket::SSL->new( PeerAddr => $dst, SSL_ocsp_mode => SSL_OCSP_NO_STAPLE, ); # check any certificates which are not yet checked by OCSP stapling or # where we have already cached results. For your own resolving combine # $ocsp->requests with $ocsp->add_response(uri,response). my $ocsp = $client->ocsp_resolver(); my $errors = $ocsp->resolve_blocking(); if ($errors) { warn "OCSP verification failed: $errors"; close($client); } =head1 Basic SSL Server A basic SSL server looks similar to other L servers, only that it also contains settings for certificate and key: # simple server my $server = IO::Socket::SSL->new( # where to listen LocalAddr => '127.0.0.1', LocalPort => 8080, Listen => 10, # which certificate to offer # with SNI support there can be different certificates per hostname SSL_cert_file => 'cert.pem', SSL_key_file => 'key.pem', ) or die "failed to listen: $!"; # accept client my $client = $server->accept or die "failed to accept or ssl handshake: $!,$SSL_ERROR"; This will automatically use a secure set of ciphers and SSL version and also supports Forward Secrecy with (Elliptic-Curve) Diffie-Hellmann Key Exchange. If you are doing a forking or threading server, we recommend that you do the SSL handshake inside the new process/thread so that the master is free for new connections. We recommend this because a client with improper or slow SSL handshake could make the server block in the handshake which would be bad to do on the listening socket: # inet server my $server = IO::Socket::INET->new( # where to listen LocalAddr => '127.0.0.1', LocalPort => 8080, Listen => 10, ); # accept client my $client = $server->accept or die; # SSL upgrade client (in new process/thread) IO::Socket::SSL->start_SSL($client, SSL_server => 1, SSL_cert_file => 'cert.pem', SSL_key_file => 'key.pem', ) or die "failed to ssl handshake: $SSL_ERROR"; Like with normal sockets, neither forking nor threading servers scale well. It is recommended to use non-blocking sockets instead, see L =head1 Common Usage Errors This is a list of typical errors seen with the use of L: =over 4 =item * Disabling verification with C. As described in L, a proper identification of the peer is essential and failing to verify makes Man-In-The-Middle attacks possible. Nevertheless, lots of scripts and even public modules or applications disable verification, because it is probably the easiest way to make the thing work and usually nobody notices any security problems anyway. If the verification does not succeed with the default settings, one can do the following: =over 8 =item * Make sure the needed CAs are in the store, maybe use C or C to specify a different CA store. =item * If the validation fails because the certificate is self-signed and that's what you expect, you can use the C option to accept specific leaf certificates by their certificate or pubkey fingerprint. =item * If the validation failed because the hostname does not match and you cannot access the host with the name given in the certificate, you can use C to specify the hostname you expect in the certificate. =back A common error pattern is also to disable verification if they found no CA store (different modules look at different "default" places). Because L is now able to provide a usable CA store on most platforms (UNIX, Mac OSX and Windows) it is better to use the defaults provided by L. If necessary these can be checked with the C method. =item * Polling of SSL sockets (e.g. select, poll and other event loops). If you sysread one byte on a normal socket it will result in a syscall to read one byte. Thus, if more than one byte is available on the socket it will be kept in the network stack of your OS and the next select or poll call will return the socket as readable. But, with SSL you don't deliver single bytes. Multiple data bytes are packaged and encrypted together in an SSL frame. Decryption can only be done on the whole frame, so a sysread for one byte actually reads the complete SSL frame from the socket, decrypts it and returns the first decrypted byte. Further sysreads will return more bytes from the same frame until all bytes are returned and the next SSL frame will be read from the socket. Thus, in order to decide if you can read more data (e.g. if sysread will block) you must check if there are still data in the current SSL frame by calling C and if there are no data pending you might check the underlying socket with select or poll. Another way might be if you try to sysread at least 16kByte all the time. 16kByte is the maximum size of an SSL frame and because sysread returns data from only a single SSL frame you can guarantee that there are no pending data. See also L. =item * Expecting exactly the same behavior as plain sockets. IO::Socket::SSL tries to emulate the usual socket behavior as good as possible, but full emulation can not be done. Specifically a read on the SSL socket might also result in a write on the TCP socket or a write on the SSL socket might result in a read on the TCP socket. Also C and B on the SSL socket will result in writing and reading data to the TCP socket too. Especially the hidden writes might result in a connection reset if the underlying TCP socket is already closed by the peer. Unless signal PIPE is explicitly handled by the application this will ususally result in the application crashing. It is thus recommended to explicitly IGNORE signal PIPE so that the errors get propagated as EPIPE instead of causing a crash of the application. =item * Set 'SSL_version' or 'SSL_cipher_list' to a "better" value. L tries to set these values to reasonable, secure values which are compatible with the rest of the world. But, there are some scripts or modules out there which tried to be smart and get more secure or compatible settings. Unfortunately, they did this years ago and never updated these values, so they are still forced to do only 'TLSv1' (instead of also using TLSv12 or TLSv11). Or they set 'HIGH' as the cipher list and thought they were secure, but did not notice that 'HIGH' includes anonymous ciphers, e.g. without identification of the peer. So it is recommended to leave the settings at the secure defaults which L sets and which get updated from time to time to better fit the real world. =item * Make SSL settings inaccessible by the user, together with bad builtin settings. Some modules use L, but don't make the SSL settings available to the user. This is often combined with bad builtin settings or defaults (like switching verification off). Thus the user needs to hack around these restrictions by using C or similar. =item * Use of constants as strings. Constants like C or C should be used as constants and not be put inside quotes, because they represent numerical values. =item * Forking and handling the socket in parent and child. A B of the process will duplicate the internal user space SSL state of the socket. If both master and child interact with the socket by using their own SSL state strange error messages will happen. Such interaction includes explicit or implicit B of the SSL socket. To avoid this the socket should be explicitly closed with B. =item * Forking and executing a new process. Since the SSL state is stored in user space it will be duplicated by a B but it will be lost when doing B. This means it is not possible to simply redirect stdin and stdout for the new process to the SSL socket by duplicating the relevant file handles. Instead explicitly exchanging plain data between child-process and SSL socket are needed. =back =head1 Common Problems with SSL SSL is a complex protocol with multiple implementations and each of these has their own quirks. While most of these implementations work together, it often gets problematic with older versions, minimal versions in load balancers, or plain wrong setups. Unfortunately these problems are hard to debug. Helpful for debugging are a knowledge of SSL internals, wireshark and the use of the debug settings of L and L, which can both be set with C<$IO::Socket::SSL::DEBUG>. The following debugs levels are defined, but used not in any consistent way: =over 4 =item * 0 - No debugging (default). =item * 1 - Print out errors from L and ciphers from L. =item * 2 - Print also information about call flow from L and progress information from L. =item * 3 - Print also some data dumps from L and from L. =back Also, C from the ssl-tools repository at L might be a helpful tool when debugging SSL problems, as do the C command line tool and a check with a different SSL implementation (e.g. a web browser). The following problems are not uncommon: =over 4 =item * Bad server setup: missing intermediate certificates. It is a regular problem that administrators fail to include all necessary certificates into their server setup, e.g. everything needed to build the trust chain from the trusted root. If they check the setup with the browser everything looks ok, because browsers work around these problems by caching any intermediate certificates and apply them to new connections if certificates are missing. But, fresh browser profiles which have never seen these intermediates cannot fill in the missing certificates and fail to verify; the same is true with L. =item * Old versions of servers or load balancers which do not understand specific TLS versions or croak on specific data. From time to time one encounters an SSL peer, which just closes the connection inside the SSL handshake. This can usually be worked around by downgrading the SSL version, e.g. by setting C. Modern Browsers usually deal with such servers by automatically downgrading the SSL version and repeat the connection attempt until they succeed. Worse servers do not close the underlying TCP connection but instead just drop the relevant packet. This is harder to detect because it looks like a stalled connection. But downgrading the SSL version often works here too. A cause of such problems are often load balancers or security devices, which have hardware acceleration and only a minimal (and less robust) SSL stack. They can often be detected because they support much fewer ciphers than other implementations. =item * Bad or old OpenSSL versions. L uses OpenSSL with the help of the L library. It is recommend to have a recent version of this library, because it has more features and usually fewer known bugs. =item * Validation of client certificates fail. Make sure that the purpose of the certificate allows use as ssl client (check with C<< openssl x509 -purpose >>, that the necessary root certificate is in the path specified by C (or the default path) and that any intermediate certificates needed to build the trust chain are sent by the client. =item * Validation of self-signed certificate fails even if it is given with C argument. The C arguments do not give a general trust store for arbitrary certificates but only specify a store for CA certificates which then can be used to verify other certificates. This especially means that certificates which are not a CA get simply ignored, notably self-signed certificates which do not also have the CA-flag set. This behavior of OpenSSL differs from the more general trust-store concept which can be found in browsers and where it is possible to simply added arbitrary certificates (CA or not) as trusted. =back =head1 Using Non-Blocking Sockets If you have a non-blocking socket, the expected behavior on read, write, accept or connect is to set C<$!> to EWOULDBLOCK if the operation cannot be completed immediately. Note that EWOULDBLOCK is the same as EAGAIN on UNIX systems, but is different on Windows. With SSL, handshakes might occur at any time, even within an established connection. In these cases it is necessary to finish the handshake before you can read or write data. This might result in situations where you want to read but must first finish the write of a handshake or where you want to write but must first finish a read. In these cases C<$!> is set to EAGAIN like expected, and additionally C<$SSL_ERROR> is set to either SSL_WANT_READ or SSL_WANT_WRITE. Thus if you get EWOULDBLOCK on a SSL socket you must check C<$SSL_ERROR> for SSL_WANT_* and adapt your event mask accordingly. Using readline on non-blocking sockets does not make much sense and I would advise against using it. And, while the behavior is not documented for other L classes, it will try to emulate the behavior seen there, e.g. to return the received data instead of blocking, even if the line is not complete. If an unrecoverable error occurs it will return nothing, even if it already received some data. Also, I would advise against using C with a non-blocking SSL object because it might block and this is not what most would expect. The reason for this is that C on a non-blocking TCP socket (e.g. L, L..) results in a new TCP socket which does not inherit the non-blocking behavior of the master socket. And thus, the initial SSL handshake on the new socket inside C will be done in a blocking way. To work around this you are safer by doing a TCP accept and later upgrade the TCP socket in a non-blocking way with C and C. my $cl = IO::Socket::SSL->new($dst); $cl->blocking(0); my $sel = IO::Select->new($cl); while (1) { # with SSL a call for reading n bytes does not result in reading of n # bytes from the socket, but instead it must read at least one full SSL # frame. If the socket has no new bytes, but there are unprocessed data # from the SSL frame can_read will block! # wait for data on socket $sel->can_read(); # new data on socket or eof READ: # this does not read only 1 byte from socket, but reads the complete SSL # frame and then just returns one byte. On subsequent calls it than # returns more byte of the same SSL frame until it needs to read the # next frame. my $n = sysread( $cl,my $buf,1); if ( ! defined $n ) { die $! if not ${EWOULDBLOCK}; next if $SSL_ERROR == SSL_WANT_READ; if ( $SSL_ERROR == SSL_WANT_WRITE ) { # need to write data on renegotiation $sel->can_write; next; } die "something went wrong: $SSL_ERROR"; } elsif ( ! $n ) { last; # eof } else { # read next bytes # we might have still data within the current SSL frame # thus first process these data instead of waiting on the underlying # socket object goto READ if $cl->pending; # goto sysread next; # goto $sel->can_read } } Additionally there are differences to plain sockets when using select, poll, kqueue or similar technologies to get notified if data are available. Relying only on these calls is not sufficient in all cases since unread data might be internally buffered in the SSL stack. To detect such buffering B need to be used. Alternatively the buffering can be avoided by using B with the maximum size of an SSL frame. See L for details. =head1 Advanced Usage =head2 SNI Support Newer extensions to SSL can distinguish between multiple hostnames on the same IP address using Server Name Indication (SNI). Support for SNI on the client side was added somewhere in the OpenSSL 0.9.8 series, but with 1.0 a bug was fixed when the server could not decide about its hostname. Therefore client side SNI is only supported with OpenSSL 1.0 or higher in L. With a supported version, SNI is used automatically on the client side, if it can determine the hostname from C or C (which are synonyms in the underlying IO::Socket:: classes and thus should never be set both or at least not to different values). On unsupported OpenSSL versions it will silently not use SNI. The hostname can also be given explicitly given with C, but in this case it will throw in error, if SNI is not supported. To check for support you might call C<< IO::Socket::SSL->can_client_sni() >>. On the server side, earlier versions of OpenSSL are supported, but only together with L version >= 1.50. To check for support you might call C<< IO::Socket::SSL->can_server_sni() >>. If server side SNI is supported, you might specify different certificates per host with C and C, and check the requested name using C. =head2 Talk Plain and SSL With The Same Socket It is often required to first exchange some plain data and then upgrade the socket to SSL after some kind of STARTTLS command. Protocols like FTPS even need a way to downgrade the socket again back to plain. The common way to do this would be to create a normal socket and use C to upgrade and stop_SSL to downgrade: my $sock = IO::Socket::INET->new(...) or die $!; ... exchange plain data on $sock until starttls command ... IO::Socket::SSL->start_SSL($sock,%sslargs) or die $SSL_ERROR; ... now $sock is an IO::Socket::SSL object ... ... exchange data with SSL on $sock until stoptls command ... $sock->stop_SSL or die $SSL_ERROR; ... now $sock is again an IO::Socket::INET object ... But, lots of modules just derive directly from L. While this base class can be replaced with L, these modules cannot easily support different base classes for SSL and plain data and switch between these classes on a starttls command. To help in this case, L can be reduced to a plain socket on startup, and connect_SSL/accept_SSL/start_SSL can be used to enable SSL and C to talk plain again: my $sock = IO::Socket::SSL->new( PeerAddr => ... SSL_startHandshake => 0, %sslargs ) or die $!; ... exchange plain data on $sock until starttls command ... $sock->connect_SSL or die $SSL_ERROR; ... now $sock is an IO::Socket::SSL object ... ... exchange data with SSL on $sock until stoptls command ... $sock->stop_SSL or die $SSL_ERROR; ... $sock is still an IO::Socket::SSL object ... ... but data exchanged again in plain ... =head1 Integration Into Own Modules L behaves similarly to other L modules and thus could be integrated in the same way, but you have to take special care when using non-blocking I/O (like for handling timeouts) or using select or poll. Please study the documentation on how to deal with these differences. Also, it is recommended to not set or touch most of the C options, so that they keep their secure defaults. It is also recommended to let the user override these SSL specific settings without the need of global settings or hacks like C. The notable exception is C. This should be set to the hostname verification scheme required by the module or protocol. =head1 Description Of Methods L inherits from another L module. The choice of the super class depends on the installed modules: =over 4 =item * If L with at least version 0.20 is installed it will use this module as super class, transparently providing IPv6 and IPv4 support. =item * If L is installed it will use this module as super class, transparently providing IPv6 and IPv4 support. =item * Otherwise it will fall back to L, which is a perl core module. With L you only get IPv4 support. =back Please be aware that with the IPv6 capable super classes, it will look first for the IPv6 address of a given hostname. If the resolver provides an IPv6 address, but the host cannot be reached by IPv6, there will be no automatic fallback to IPv4. To avoid these problems you can enforce IPv4 for a specific socket by using the C or C option with the value AF_INET as described in L. Alternatively you can enforce IPv4 globally by loading L with the option 'inet4', in which case it will use the IPv4 only class L as the super class. L will provide all of the methods of its super class, but sometimes it will override them to match the behavior expected from SSL or to provide additional arguments. The new or changed methods are described below, but please also read the section about SSL specific error handling. =over 4 =item Error Handling If an SSL specific error occurs, the global variable C<$SSL_ERROR> will be set. If the error occurred on an existing SSL socket, the method C will give access to the latest socket specific error. Both C<$SSL_ERROR> and the C method give a dualvar similar to C<$!>, e.g. providing an error number in numeric context or an error description in string context. =item B Creates a new L object. You may use all the friendly options that came bundled with the super class (e.g. L, L, ...) plus (optionally) the ones described below. If you don't specify any SSL related options it will do its best in using secure defaults, e.g. choosing good ciphers, enabling proper verification, etc. =over 2 =item SSL_server Set this option to a true value if the socket should be used as a server. If this is not explicitly set it is assumed if the C parameter is given when creating the socket. =item SSL_hostname This can be given to specify the hostname used for SNI, which is needed if you have multiple SSL hostnames on the same IP address. If not given it will try to determine the hostname from C, which will fail if only an IP was given or if this argument is used within C. If you want to disable SNI, set this argument to ''. Currently only supported for the client side and will be ignored for the server side. See section "SNI Support" for details of SNI the support. =item SSL_startHandshake If this option is set to false (defaults to true) it will not start the SSL handshake yet. This has to be done later with C or C. Before the handshake is started read/write/etc. can be used to exchange plain data. =item SSL_keepSocketOnError If this option is set to true (defaults to false) it will not close the underlying TCP socket on errors. In most cases there is no real use for this behavior since both sides of the TCP connection will probably have a different idea of the current state of the connection. =item SSL_ca | SSL_ca_file | SSL_ca_path Usually you want to verify that the peer certificate has been signed by a trusted certificate authority. In this case you should use this option to specify the file (C) or directory (C) containing the certificateZ<>(s) of the trusted certificate authorities. C can also be an array or a string containing multiple path, where the path are separated by the platform specific separator. This separator is C<;> on DOS, Windows, Netware, C<,> on VMS and C<:> for all the other systems. If multiple path are given at least one of these must be accessible. You can also give a list of X509* certificate handles (like you get from L or L) with C. These will be added to the CA store before path and file and thus take precedence. If neither SSL_ca, nor SSL_ca_file or SSL_ca_path are set it will use C to determine the user-set or system defaults. If you really don't want to set a CA set SSL_ca_file or SSL_ca_path to C<\undef> or SSL_ca to an empty list. (unfortunately C<''> is used by some modules using L when CA is not explicitly given). =item SSL_client_ca | SSL_client_ca_file If verify_mode is VERIFY_PEER on the server side these options can be used to set the list of acceptable CAs for the client. This way the client can select they required certificate from a list of certificates. The value for these options is similar to C and C. =item SSL_fingerprint Sometimes you have a self-signed certificate or a certificate issued by an unknown CA and you really want to accept it, but don't want to disable verification at all. In this case you can specify the fingerprint of the certificate as C<'algo$hex_fingerprint'>. C is a fingerprint algorithm supported by OpenSSL, e.g. 'sha1','sha256'... and C is the hexadecimal representation of the binary fingerprint. Any colons inside the hex string will be ignored. If you want to use the fingerprint of the pubkey inside the certificate instead of the certificate use the syntax C<'algo$pub$hex_fingerprint'> instead. To get the fingerprint of an established connection you can use C. It is also possible to skip C, i.e. only specifiy the fingerprint. In this case the likely algorithms will be automatically detected based on the length of the digest string. You can specify a list of fingerprints in case you have several acceptable certificates. If a fingerprint matches the topmost (i.e. leaf) certificate no additional validations can make the verification fail. =item SSL_cert_file | SSL_cert | SSL_key_file | SSL_key If you create a server you usually need to specify a server certificate which should be verified by the client. Same is true for client certificates, which should be verified by the server. The certificate can be given as a file with SSL_cert_file or as an internal representation of an X509* object (like you get from L or L) with SSL_cert. If given as a file it will automatically detect the format. Supported file formats are PEM, DER and PKCS#12, where PEM and PKCS#12 can contain the certificate and the chain to use, while DER can only contain a single certificate. If given as a list of X509* please note, that the all the chain certificates (e.g. all except the first) will be "consumed" by openssl and will be freed if the SSL context gets destroyed - so you should never free them yourself. But the servers certificate (e.g. the first) will not be consumed by openssl and thus must be freed by the application. For each certificate a key is need, which can either be given as a file with SSL_key_file or as an internal representation of an EVP_PKEY* object with SSL_key (like you get from L or L). If a key was already given within the PKCS#12 file specified by SSL_cert_file it will ignore any SSL_key or SSL_key_file. If no SSL_key or SSL_key_file was given it will try to use the PEM file given with SSL_cert_file again, maybe it contains the key too. If your SSL server should be able to use different certificates on the same IP address, depending on the name given by SNI, you can use a hash reference instead of a file with C< cert_file>>. If your SSL server should be able to use both RSA and ECDSA certificates for the same domain/IP a similar hash reference like with SNI is given. The domain names used to specify the additional certificates should be C, i.e. C or similar. This needs at least OpenSSL 1.0.2. To let the server pick the certificate based on the clients cipher preference C should be set to false. In case certs and keys are needed but not given it might fall back to builtin defaults, see "Defaults for Cert, Key and CA". Examples: SSL_cert_file => 'mycert.pem', SSL_key_file => 'mykey.pem', SSL_cert_file => { "foo.example.org" => 'foo-cert.pem', "foo.example.org%ecc" => 'foo-ecc-cert.pem', "bar.example.org" => 'bar-cert.pem', # used when nothing matches or client does not support SNI '' => 'default-cert.pem', '%ecc' => 'default-ecc-cert.pem', }, SSL_key_file => { "foo.example.org" => 'foo-key.pem', "foo.example.org%ecc" => 'foo-ecc-key.pem', "bar.example.org" => 'bar-key.pem', # used when nothing matches or client does not support SNI '' => 'default-key.pem', '%ecc' => 'default-ecc-key.pem', } =item SSL_passwd_cb If your private key is encrypted, you might not want the default password prompt from Net::SSLeay. This option takes a reference to a subroutine that should return the password required to decrypt your private key. =item SSL_use_cert If this is true, it forces IO::Socket::SSL to use a certificate and key, even if you are setting up an SSL client. If this is set to 0 (the default), then you will only need a certificate and key if you are setting up a server. SSL_use_cert will implicitly be set if SSL_server is set. For convenience it is also set if it was not given but a cert was given for use (SSL_cert_file or similar). =item SSL_version Sets the version of the SSL protocol used to transmit data. 'SSLv23' uses a handshake compatible with SSL2.0, SSL3.0 and TLS1.x, while 'SSLv2', 'SSLv3', 'TLSv1', 'TLSv1_1', 'TLSv1_2', or 'TLSv1_3' restrict handshake and protocol to the specified version. All values are case-insensitive. Instead of 'TLSv1_1', 'TLSv1_2', and 'TLSv1_3' one can also use 'TLSv11', 'TLSv12', and 'TLSv13'. Support for 'TLSv1_1', 'TLSv1_2', and 'TLSv1_3' requires recent versions of Net::SSLeay and openssl. The default SSL_version is defined by the underlying cryptographic library. Independent from the handshake format you can limit to set of accepted SSL versions by adding !version separated by ':'. For example, 'SSLv23:!SSLv3:!SSLv2' means that the handshake format is compatible to SSL2.0 and higher, but that the successful handshake is limited to TLS1.0 and higher, that is no SSL2.0 or SSL3.0 because both of these versions have serious security issues and should not be used anymore. You can also use !TLSv1_1 and !TLSv1_2 to disable TLS versions 1.1 and 1.2 while still allowing TLS version 1.0. Setting the version instead to 'TLSv1' might break interaction with older clients, which need and SSL2.0 compatible handshake. On the other side some clients just close the connection when they receive a TLS version 1.1 request. In this case setting the version to 'SSLv23:!SSLv2:!SSLv3:!TLSv1_1:!TLSv1_2' might help. =item SSL_cipher_list If this option is set the cipher list for the connection will be set to the given value, e.g. something like 'ALL:!LOW:!EXP:!aNULL'. Look into the OpenSSL documentation (L) for more details. Unless you fail to contact your peer because of no shared ciphers it is recommended to leave this option at the default setting, which honors the system-wide PROFILE=SYSTEM cipher list. In case different cipher lists are needed for different SNI hosts a hash can be given with the host as key and the cipher suite as value, similar to B. =item SSL_honor_cipher_order If this option is true the cipher order the server specified is used instead of the order proposed by the client. This option defaults to true to make use of our secure cipher list setting. =item SSL_dh_file To create a server which provides forward secrecy you need to either give the DH parameters or (better, because faster) the ECDH curve. This setting cares about DH parameters. To support non-elliptic Diffie-Hellman key exchange a suitable file needs to be given here or the SSL_dh should be used with a appropriate value. See dhparam command in openssl for more information. If neither C nor C are set a builtin DH parameter with a length of 2048 bit is used to offer DH key exchange by default. If you don't want this (e.g. disable DH key exchange) explicitly set this or the C parameter to undef. =item SSL_dh Like SSL_dh_file, but instead of giving a file you use a preloaded or generated DH*. =item SSL_ecdh_curve To create a server which provides forward secrecy you need to either give the DH parameters or (better, because faster) the ECDH curve. This setting cares about the ECDH curve(s). To support Elliptic Curve Diffie-Hellmann key exchange the OID or NID of at least one suitable curve needs to be provided here. With OpenSSL 1.1.0+ this parameter defaults to C, which means that it lets OpenSSL pick the best settings. If support for CTX_set_ecdh_auto is implemented in Net::SSLeay (needs at least version 1.86) it will use this to implement the same default. Otherwise it will default to C (builtin of OpenSSL) in order to offer ECDH key exchange by default. If setting groups or curves is supported by Net::SSLeay (needs at least version 1.86) then multiple curves can be given here in the order of the preference, i.e. C. When used at the client side this will include the supported curves as extension in the TLS handshake. If you don't want to have ECDH key exchange this could be set to undef or set C to exclude all of these ciphers. You can check if ECDH support is available by calling C<< IO::Socket::SSL->can_ecdh >>. =item SSL_verify_mode This option sets the verification mode for the peer certificate. You may combine SSL_VERIFY_PEER (verify_peer), SSL_VERIFY_FAIL_IF_NO_PEER_CERT (fail verification if no peer certificate exists; ignored for clients), SSL_VERIFY_CLIENT_ONCE (verify client once; ignored for clients). See OpenSSL man page for SSL_CTX_set_verify for more information. The default is SSL_VERIFY_NONE for server (e.g. no check for client certificate) and SSL_VERIFY_PEER for client (check server certificate). =item SSL_verify_callback If you want to verify certificates yourself, you can pass a sub reference along with this parameter to do so. When the callback is called, it will be passed: =over 4 =item 1. a true/false value that indicates what OpenSSL thinks of the certificate, =item 2. a C-style memory address of the certificate store, =item 3. a string containing the certificate's issuer attributes and owner attributes, and =item 4. a string containing any errors encountered (0 if no errors). =item 5. a C-style memory address of the peer's own certificate (convertible to PEM form with Net::SSLeay::PEM_get_string_X509()). =item 6. The depth of the certificate in the chain. Depth 0 is the leaf certificate. =back The function should return 1 or 0, depending on whether it thinks the certificate is valid or invalid. The default is to let OpenSSL do all of the busy work. The callback will be called for each element in the certificate chain. See the OpenSSL documentation for SSL_CTX_set_verify for more information. =item SSL_verifycn_scheme The scheme is used to correctly verify the identity inside the certificate by using the hostname of the peer. See the information about the verification schemes in B. If you don't specify a scheme it will use 'default', but only complain loudly if the name verification fails instead of letting the whole certificate verification fail. THIS WILL CHANGE, e.g. it will let the certificate verification fail in the future if the hostname does not match the certificate !!!! To override the name used in verification use B. The scheme 'default' is a superset of the usual schemes, which will accept the hostname in common name and subjectAltName and allow wildcards everywhere. While using this scheme is way more secure than no name verification at all you better should use the scheme specific to your application protocol, e.g. 'http', 'ftp'... If you are really sure, that you don't want to verify the identity using the hostname you can use 'none' as a scheme. In this case you'd better have alternative forms of verification, like a certificate fingerprint or do a manual verification later by calling B yourself. =item SSL_verifycn_publicsuffix This option is used to specify the behavior when checking wildcards certificates for public suffixes, e.g. no wildcard certificates for *.com or *.co.uk should be accepted, while *.example.com or *.example.co.uk is ok. If not specified it will simply use the builtin default of L, you can create another object with from_string or from_file of this module. To disable verification of public suffix set this option to C<''>. =item SSL_verifycn_name Set the name which is used in verification of hostname. If SSL_verifycn_scheme is set and no SSL_verifycn_name is given it will try to use SSL_hostname or PeerHost and PeerAddr settings and fail if no name can be determined. If SSL_verifycn_scheme is not set it will use a default scheme and warn if it cannot determine a hostname, but it will not fail. Using PeerHost or PeerAddr works only if you create the connection directly with C<< IO::Socket::SSL->new >>, if an IO::Socket::INET object is upgraded with B the name has to be given in B or B. =item SSL_check_crl If you want to verify that the peer certificate has not been revoked by the signing authority, set this value to true. OpenSSL will search for the CRL in your SSL_ca_path, or use the file specified by SSL_crl_file. See the Net::SSLeay documentation for more details. Note that this functionality appears to be broken with OpenSSL < v0.9.7b, so its use with lower versions will result in an error. =item SSL_crl_file If you want to specify the CRL file to be used, set this value to the pathname to be used. This must be used in addition to setting SSL_check_crl. =item SSL_ocsp_mode Defines how certificate revocation is done using OCSP (Online Status Revocation Protocol). The default is to send a request for OCSP stapling to the server and if the server sends an OCSP response back the result will be used. Any other OCSP checking needs to be done manually with C. The following flags can be combined with C<|>: =over 8 =item SSL_OCSP_NO_STAPLE Don't ask for OCSP stapling. This is the default if SSL_verify_mode is VERIFY_NONE. =item SSL_OCSP_TRY_STAPLE Try OCSP stapling, but don't complain if it gets no stapled response back. This is the default if SSL_verify_mode is VERIFY_PEER (the default). =item SSL_OCSP_MUST_STAPLE Consider it a hard error, if the server does not send a stapled OCSP response back. Most servers currently send no stapled OCSP response back. =item SSL_OCSP_FAIL_HARD Fail hard on response errors, default is to fail soft like the browsers do. Soft errors mean, that the OCSP response is not usable, e.g. no response, error response, no valid signature etc. Certificate revocations inside a verified response are considered hard errors in any case. Soft errors inside a stapled response are never considered hard, e.g. it is expected that in this case an OCSP request will be send to the responsible OCSP responder. =item SSL_OCSP_FULL_CHAIN This will set up the C so that all certificates from the peer chain will be checked, otherwise only the leaf certificate will be checked against revocation. =back =item SSL_ocsp_staple_callback If this callback is defined, it will be called with the SSL object and the OCSP response handle obtained from the peer, e.g. C<<$cb->($ssl,$resp)>>. If the peer did not provide a stapled OCSP response the function will be called with C<$resp=undef>. Because the OCSP response handle is no longer valid after leaving this function it should not by copied or freed. If access to the response is necessary after leaving this function it can be serialized with C. If no such callback is provided, it will use the default one, which verifies the response and uses it to check if the certificate(s) of the connection got revoked. =item SSL_ocsp_cache With this option a cache can be given for caching OCSP responses, which could be shared between different SSL contexts. If not given a cache specific to the SSL context only will be used. You can either create a new cache with C<< IO::Socket::SSL::OCSP_Cache->new([size]) >> or implement your own cache, which needs to have methods C and C (returning C<\%entry>) where entry is the hash representation of the OCSP response with fields like C. The default implementation of the cache will consider responses valid as long as C is less then the current time. =item SSL_reuse_ctx If you have already set the above options for a previous instance of IO::Socket::SSL, then you can reuse the SSL context of that instance by passing it as the value for the SSL_reuse_ctx parameter. You may also create a new instance of the IO::Socket::SSL::SSL_Context class, using any context options that you desire without specifying connection options, and pass that here instead. If you use this option, all other context-related options that you pass in the same call to new() will be ignored unless the context supplied was invalid. Note that, contrary to versions of IO::Socket::SSL below v0.90, a global SSL context will not be implicitly used unless you use the set_default_context() function. =item SSL_create_ctx_callback With this callback you can make individual settings to the context after it got created and the default setup was done. The callback will be called with the CTX object from Net::SSLeay as the single argument. Example for limiting the server session cache size: SSL_create_ctx_callback => sub { my $ctx = shift; Net::SSLeay::CTX_sess_set_cache_size($ctx,128); } =item SSL_session_cache_size If you make repeated connections to the same host/port and the SSL renegotiation time is an issue, you can turn on client-side session caching with this option by specifying a positive cache size. For successive connections, pass the SSL_reuse_ctx option to the new() calls (or use set_default_context()) to make use of the cached sessions. The session cache size refers to the number of unique host/port pairs that can be stored at one time; the oldest sessions in the cache will be removed if new ones are added. This option does not effect the session cache a server has for it's clients, e.g. it does not affect SSL objects with SSL_server set. Note that session caching with TLS 1.3 needs at least Net::SSLeay 1.86. =item SSL_session_cache Specifies session cache object which should be used instead of creating a new. Overrules SSL_session_cache_size. This option is useful if you want to reuse the cache, but not the rest of the context. A session cache object can be created using C<< IO::Socket::SSL::Session_Cache->new( cachesize ) >>. Use set_default_session_cache() to set a global cache object. =item SSL_session_key Specifies a key to use for lookups and inserts into client-side session cache. Per default ip:port of destination will be used, but sometimes you want to share the same session over multiple ports on the same server (like with FTPS). =item SSL_session_id_context This gives an id for the servers session cache. It's necessary if you want clients to connect with a client certificate. If not given but SSL_verify_mode specifies the need for client certificate a context unique id will be picked. =item SSL_error_trap When using the accept() or connect() methods, it may be the case that the actual socket connection works but the SSL negotiation fails, as in the case of an HTTP client connecting to an HTTPS server. Passing a subroutine ref attached to this parameter allows you to gain control of the orphaned socket instead of having it be closed forcibly. The subroutine, if called, will be passed two parameters: a reference to the socket on which the SSL negotiation failed and the full text of the error message. =item SSL_npn_protocols If used on the server side it specifies list of protocols advertised by SSL server as an array ref, e.g. ['spdy/2','http1.1']. On the client side it specifies the protocols offered by the client for NPN as an array ref. See also method C. Next Protocol Negotiation (NPN) is available with Net::SSLeay 1.46+ and openssl-1.0.1+. NPN is unavailable in TLSv1.3 protocol. To check support you might call C<< IO::Socket::SSL->can_npn() >>. If you use this option with an unsupported Net::SSLeay/OpenSSL it will throw an error. =item SSL_alpn_protocols If used on the server side it specifies list of protocols supported by the SSL server as an array ref, e.g. ['http/2.0', 'spdy/3.1','http/1.1']. On the client side it specifies the protocols advertised by the client for ALPN as an array ref. See also method C. Application-Layer Protocol Negotiation (ALPN) is available with Net::SSLeay 1.56+ and openssl-1.0.2+. More details about the extension are in RFC7301. To check support you might call C<< IO::Socket::SSL->can_alpn() >>. If you use this option with an unsupported Net::SSLeay/OpenSSL it will throw an error. Note that some client implementations may encounter problems if both NPN and ALPN are specified. Since ALPN is intended as a replacement for NPN, try providing ALPN protocols then fall back to NPN if that fails. =item SSL_ticket_keycb => [$sub,$data] | $sub This is a callback used for stateless session reuse (Session Tickets, RFC 5077). This callback will be called as C<< $sub->($data,[$key_name]) >> where C<$data> is the argument given to SSL_ticket_keycb (or undef) and C<$key_name> depends on the mode: =over 8 =item encrypt ticket If a ticket needs to be encrypted the callback will be called without C<$key_name>. In this case it should return C<($current_key,$current_key_name>) where C<$current_key> is the current key (32 byte random data) and C<$current_key_name> the name associated with this key (exactly 16 byte). This C<$current_key_name> will be incorporated into the ticket. =item decrypt ticket If a ticket needs to be decrypted the callback will be called with C<$key_name> as found in the ticket. It should return C<($key,$current_key_name>) where C<$key> is the key associated with the given C<$key_name> and C<$current_key_name> the name associated with the currently active key. If C<$current_key_name> is different from the given C<$key_name> the callback will be called again to re-encrypt the ticket with the currently active key. If no key can be found which matches the given C<$key_name> then this function should return nothing (empty list). This mechanism should be used to limit the life time for each key encrypting the ticket. Compromise of a ticket encryption key might lead to decryption of SSL sessions which used session tickets protected by this key. =back Example: Net::SSLeay::RAND_bytes(my $oldkey,32); Net::SSLeay::RAND_bytes(my $newkey,32); my $oldkey_name = pack("a16",'oldsecret'); my $newkey_name = pack("a16",'newsecret'); my @keys = ( [ $newkey_name, $newkey ], # current active key [ $oldkey_name, $oldkey ], # already expired ); my $keycb = [ sub { my ($mykeys,$name) = @_; # return (current_key, current_key_name) if no name given return ($mykeys->[0][1],$mykeys->[0][0]) if ! $name; # return (matching_key, current_key_name) if we find a key matching # the given name for(my $i = 0; $i<@$mykeys; $i++) { next if $name ne $mykeys->[$i][0]; return ($mykeys->[$i][1],$mykeys->[0][0]); } # no matching key found return; },\@keys ]; my $srv = IO::Socket::SSL->new(..., SSL_ticket_keycb => $keycb); =back =item B This behaves similar to the accept function of the underlying socket class, but additionally does the initial SSL handshake. But because the underlying socket class does return a blocking file handle even when accept is called on a non-blocking socket, the SSL handshake on the new file object will be done in a blocking way. Please see the section about non-blocking I/O for details. If you don't like this behavior you should do accept on the TCP socket and then upgrade it with C later. =item B This behaves similar to the connect function but also does an SSL handshake. Because you cannot give SSL specific arguments to this function, you should better either use C to create a connect SSL socket or C to upgrade an established TCP socket to SSL. =item B Contrary to a close for a simple INET socket a close in SSL also mandates a proper shutdown of the SSL part. This is done by sending a close notify message by both peers. A naive implementation would thus wait until it receives the close notify message from the peer - which conflicts with the commonly expected semantic that a close will not block. The default behavior is thus to only send a close notify but not wait for the close notify of the peer. If this is required C need to be explicitly set to false. There are also cases where a SSL shutdown should not be done at all. This is true for example when forking to let a child deal with the socket and closing the socket in the parent process. A naive explicit C or an implicit close when destroying the socket in the parent would send a close notify to the peer which would make the SSL socket in the client process unusable. In this case an explicit C with C set to true should be done in the parent process. For more details and other arguments see C which gets called from C to shutdown the SSL state of the socket. =item B This function behaves from the outside the same as B in other L objects, e.g. it returns at most LEN bytes of data. But in reality it reads not only LEN bytes from the underlying socket, but at a single SSL frame. It then returns up to LEN bytes it decrypted from this SSL frame. If the frame contained more data than requested it will return only LEN data, buffer the rest and return it on further read calls. This means, that it might be possible to read data, even if the underlying socket is not readable, so using poll or select might not be sufficient. sysread will only return data from a single SSL frame, e.g. either the pending data from the already buffered frame or it will read a frame from the underlying socket and return the decrypted data. It will not return data spanning several SSL frames in a single call. Also, calls to sysread might fail, because it must first finish an SSL handshake. To understand these behaviors is essential, if you write applications which use event loops and/or non-blocking sockets. Please read the specific sections in this documentation. =item B This functions behaves from the outside the same as B in other L objects, e.g. it will write at most LEN bytes to the socket, but there is no guarantee, that all LEN bytes are written. It will return the number of bytes written. Because it basically just calls SSL_write from OpenSSL syswrite will write at most a single SSL frame. This means, that no more than 16.384 bytes, which is the maximum size of an SSL frame, will be written at once. For non-blocking sockets SSL specific behavior applies. Pease read the specific section in this documentation. =item B This function has exactly the same syntax as B, and performs nearly the same task but will not advance the read position so that successive calls to peek() with the same arguments will return the same results. This function requires OpenSSL 0.9.6a or later to work. =item B This function gives you the number of bytes available without reading from the underlying socket object. This function is essential if you work with event loops, please see the section about polling SSL sockets. =item B This methods returns the fingerprint of the given certificate in the form C, where C is the used algorithm, default 'sha256'. If no certificate is given the peer certificate of the connection is used. If C is true it will not return the fingerprint of the certificate but instead the fingerprint of the pubkey inside the certificate as C. =item B This methods returns the binary fingerprint of the given certificate by using the algorithm C, default 'sha256'. If no certificate is given the peer certificate of the connection is used. If C is true it will not return the fingerprint of the certificate but instead the fingerprint of the pubkey inside the certificate. =item B Returns the string form of the cipher that the IO::Socket::SSL object is using. =item B Returns the string representation of the SSL version of an established connection. =item B Returns the integer representation of the SSL version of an established connection. =item B This returns true if the session got reused and false otherwise. Note that with a reused session no certificates are send within the handshake and no ciphers are offered and thus functions which rely on this might not work. =item B Returns a parsable string with select fields from the peer SSL certificate. This method directly returns the result of the dump_peer_certificate() method of Net::SSLeay. =item B If a peer certificate exists, this function can retrieve values from it. If no field is given the internal representation of certificate from Net::SSLeay is returned. If refresh is true it will not used a cached version, but check again in case the certificate of the connection has changed due to renegotiation. The following fields can be queried: =over 8 =item authority (alias issuer) The certificate authority which signed the certificate. =item owner (alias subject) The owner of the certificate. =item commonName (alias cn) - only for Net::SSLeay version >=1.30 The common name, usually the server name for SSL certificates. =item subjectAltNames - only for Net::SSLeay version >=1.33 Alternative names for the subject, usually different names for the same server, like example.org, example.com, *.example.com. It returns a list of (typ,value) with typ GEN_DNS, GEN_IPADD etc (these constants are exported from IO::Socket::SSL). See Net::SSLeay::X509_get_subjectAltNames. =back =item B This is similar to C but will return the sites own certificate. The same arguments for B<$field> can be used. If no B<$field> is given the certificate handle from the underlying OpenSSL will be returned. This handle will only be valid as long as the SSL connection exists and if used afterwards it might result in strange crashes of the application. =item B This returns all the certificates send by the peer, e.g. first the peers own certificate and then the rest of the chain. You might use B from L to inspect each of the certificates. This function depends on a version of Net::SSLeay >= 1.58 . =item B This gives the name requested by the client if Server Name Indication (SNI) was used. =item B This verifies the given hostname against the peer certificate using the given scheme. Hostname is usually what you specify within the PeerAddr. See the C parameter for an explanation of suffix checking and for the possible values. Verification of hostname against a certificate is different between various applications and RFCs. Some scheme allow wildcards for hostnames, some only in subjectAltNames, and even their different wildcard schemes are possible. RFC 6125 provides a good overview. To ease the verification the following schemes are predefined (both protocol name and rfcXXXX name can be used): =over 8 =item rfc2818, xmpp (rfc3920), ftp (rfc4217) Extended wildcards in subjectAltNames and common name are possible, e.g. *.example.org or even www*.example.org. The common name will be only checked if no DNS names are given in subjectAltNames. =item http (alias www) While name checking is defined in rfc2818 the current browsers usually accept also an IP address (w/o wildcards) within the common name as long as no subjectAltNames are defined. Thus this is rfc2818 extended with this feature. =item smtp (rfc2595), imap, pop3, acap (rfc4642), netconf (rfc5538), syslog (rfc5425), snmp (rfc5953) Simple wildcards in subjectAltNames are possible, e.g. *.example.org matches www.example.org but not lala.www.example.org. If nothing from subjectAltNames match it checks against the common name, where wildcards are also allowed to match the full leftmost label. =item ldap (rfc4513) Simple wildcards are allowed in subjectAltNames, but not in common name. Common name will be checked even if subjectAltNames exist. =item sip (rfc5922) No wildcards are allowed and common name is checked even if subjectAltNames exist. =item gist (rfc5971) Simple wildcards are allowed in subjectAltNames and common name, but common name will only be checked if their are no DNS names in subjectAltNames. =item default This is a superset of all the rules and is automatically used if no scheme is given but a hostname (instead of IP) is known. Extended wildcards are allowed in subjectAltNames and common name and common name is checked always. =item none No verification will be done. Actually is does not make any sense to call verify_hostname in this case. =back The scheme can be given either by specifying the name for one of the above predefined schemes, or by using a hash which can have the following keys and values: =over 8 =item check_cn: 0|'always'|'when_only' Determines if the common name gets checked. If 'always' it will always be checked (like in ldap), if 'when_only' it will only be checked if no names are given in subjectAltNames (like in http), for any other values the common name will not be checked. =item wildcards_in_alt: 0|'full_label'|'anywhere' Determines if and where wildcards in subjectAltNames are possible. If 'full_label' only cases like *.example.org will be possible (like in ldap), for 'anywhere' www*.example.org is possible too (like http), dangerous things like but www.*.org or even '*' will not be allowed. For compatibility with older versions 'leftmost' can be given instead of 'full_label'. =item wildcards_in_cn: 0|'full_label'|'anywhere' Similar to wildcards_in_alt, but checks the common name. There is no predefined scheme which allows wildcards in common names. =item ip_in_cn: 0|1|4|6 Determines if an IP address is allowed in the common name (no wildcards are allowed). If set to 4 or 6 it only allows IPv4 or IPv6 addresses, any other true value allows both. =item callback: \&coderef If you give a subroutine for verification it will be called with the arguments ($hostname,$commonName,@subjectAltNames), where hostname is the name given for verification, commonName is the result from peer_certificate('cn') and subjectAltNames is the result from peer_certificate('subjectAltNames'). All other arguments for the verification scheme will be ignored in this case. =back =item B This method returns the name of negotiated protocol - e.g. 'http/1.1'. It works for both client and server side of SSL connection. NPN support is available with Net::SSLeay 1.46+ and openssl-1.0.1+. To check support you might call C<< IO::Socket::SSL->can_npn() >>. =item B Returns the protocol negotiated via ALPN as a string, e.g. 'http/1.1', 'http/2.0' or 'spdy/3.1'. ALPN support is available with Net::SSLeay 1.56+ and openssl-1.0.2+. To check support, use C<< IO::Socket::SSL->can_alpn() >>. =item B Returns the last error (in string form) that occurred. If you do not have a real object to perform this method on, call IO::Socket::SSL::errstr() instead. For read and write errors on non-blocking sockets, this method may include the string C or C meaning that the other side is expecting to read from or write to the socket and wants to be satisfied before you get to do anything. But with version 0.98 you are better comparing the global exported variable $SSL_ERROR against the exported symbols SSL_WANT_READ and SSL_WANT_WRITE. =item B This returns false if the socket could not be opened, 1 if the socket could be opened and the SSL handshake was successful done and -1 if the underlying IO::Handle is open, but the SSL handshake failed. =item B<< IO::Socket::SSL->start_SSL($socket, ... ) >> This will convert a glob reference or a socket that you provide to an IO::Socket::SSL object. You may also pass parameters to specify context or connection options as with a call to new(). If you are using this function on an accept()ed socket, you must set the parameter "SSL_server" to 1, i.e. IO::Socket::SSL->start_SSL($socket, SSL_server => 1). If you have a class that inherits from IO::Socket::SSL and you want the $socket to be blessed into your own class instead, use MyClass->start_SSL($socket) to achieve the desired effect. Note that if start_SSL() fails in SSL negotiation, $socket will remain blessed in its original class. For non-blocking sockets you better just upgrade the socket to IO::Socket::SSL and call accept_SSL or connect_SSL and the upgraded object. To just upgrade the socket set B explicitly to 0. If you call start_SSL w/o this parameter it will revert to blocking behavior for accept_SSL and connect_SSL. If given the parameter "Timeout" it will stop if after the timeout no SSL connection was established. This parameter is only used for blocking sockets, if it is not given the default Timeout from the underlying IO::Socket will be used. =item B This is the opposite of start_SSL(), connect_SSL() and accept_SSL(), e.g. it will shutdown the SSL connection and return to the class before start_SSL(). It gets the same arguments as close(), in fact close() calls stop_SSL() (but without downgrading the class). Will return true if it succeeded and undef if failed. This might be the case for non-blocking sockets. In this case $! is set to EWOULDBLOCK and the ssl error to SSL_WANT_READ or SSL_WANT_WRITE. In this case the call should be retried again with the same arguments once the socket is ready. For calling from C C default to false, e.g. it waits for the close_notify of the peer. This is necessary in case you want to downgrade the socket and continue to use it as a plain socket. After stop_SSL the socket can again be used to exchange plain data. =item B, B These functions should be used to do the relevant handshake, if the socket got created with C or upgraded with C and C was set to false. They will return undef until the handshake succeeded or an error got thrown. As long as the function returns undef and $! is set to EWOULDBLOCK one could retry the call after the socket got readable (SSL_WANT_READ) or writeable (SSL_WANT_WRITE). =item B This will create an OCSP resolver object, which can be used to create OCSP requests for the certificates of the SSL connection. Which certificates are verified depends on the setting of C: by default only the leaf certificate will be checked, but with SSL_OCSP_FULL_CHAIN all chain certificates will be checked. Because to create an OCSP request the certificate and its issuer certificate need to be known it is not possible to check certificates when the trust chain is incomplete or if the certificate is self-signed. The OCSP resolver gets created by calling C<< $ssl->ocsp_resolver >> and provides the following methods: =over 8 =item hard_error This returns the hard error when checking the OCSP response. Hard errors are certificate revocations. With the C of SSL_OCSP_FAIL_HARD any soft error (e.g. failures to get signed information about the certificates) will be considered a hard error too. The OCSP resolving will stop on the first hard error. The method will return undef as long as no hard errors occurred and still requests to be resolved. If all requests got resolved and no hard errors occurred the method will return C<''>. =item soft_error This returns the soft error(s) which occurred when asking the OCSP responders. =item requests This will return a hash consisting of C<(url,request)>-tuples, e.g. which contain the OCSP request string and the URL where it should be sent too. The usual way to send such a request is as HTTP POST request with a content-type of C or as a GET request with the base64 and url-encoded request is added to the path of the URL. After you've handled all these requests and added the response with C you should better call this method again to make sure, that no more requests are outstanding. IO::Socket::SSL will combine multiple OCSP requests for the same server inside a single request, but some server don't give a response to all these requests, so that one has to ask again with the remaining requests. =item add_response($uri,$response) This method takes the HTTP body of the response which got received when sending the OCSP request to C<$uri>. If no response was received or an error occurred one should either retry or consider C<$response> as empty which will trigger a soft error. The method returns the current value of C, e.g. a defined value when no more requests need to be done. =item resolve_blocking(%args) This combines C and C which L to do all necessary requests in a blocking way. C<%args> will be given to L so that you can put proxy settings etc here. L will be called with C of false, because the OCSP responses have their own signatures so no extra SSL verification is needed. If you don't want to use blocking requests you need to roll your own user agent with C and C. =back =item B<< IO::Socket::SSL->new_from_fd($fd, [mode], %sslargs) >> This will convert a socket identified via a file descriptor into an SSL socket. Note that the argument list does not include a "MODE" argument; if you supply one, it will be thoughtfully ignored (for compatibility with IO::Socket::INET). Instead, a mode of '+<' is assumed, and the file descriptor passed must be able to handle such I/O because the initial SSL handshake requires bidirectional communication. Internally the given $fd will be upgraded to a socket object using the C method of the super class (L or similar) and then C will be called using the given C<%sslargs>. If C<$fd> is already an IO::Socket object you should better call C directly. =item B ..., SSL_ca_path => ... ])> Determines or sets the default CA path. If existing path or dir or a hash is given it will set the default CA path to this value and never try to detect it automatically. If C is given it will forget any stored defaults and continue with detection of system defaults. If no arguments are given it will start detection of system defaults, unless it has already stored user-set or previously detected values. The detection of system defaults works similar to OpenSSL, e.g. it will check the directory specified in environment variable SSL_CERT_DIR or the path OPENSSLDIR/certs (SSLCERTS: on VMS) and the file specified in environment variable SSL_CERT_FILE or the path OPENSSLDIR/cert.pem (SSLCERTS:cert.pem on VMS). Contrary to OpenSSL it will check if the SSL_ca_path contains PEM files with the hash as file name and if the SSL_ca_file looks like PEM. If no usable system default can be found it will try to load and use L and if not available give up detection. The result of the detection will be saved to speed up future calls. The function returns the saved default CA as hash with SSL_ca_file and SSL_ca_path. =item B You may use this to make IO::Socket::SSL automatically re-use a given context (unless specifically overridden in a call to new()). It accepts one argument, which should be either an IO::Socket::SSL object or an IO::Socket::SSL::SSL_Context object. See the SSL_reuse_ctx option of new() for more details. Note that this sets the default context globally, so use with caution (esp. in mod_perl scripts). =item B You may use this to make IO::Socket::SSL automatically re-use a given session cache (unless specifically overridden in a call to new()). It accepts one argument, which should be an IO::Socket::SSL::Session_Cache object or similar (e.g. something which implements get_session, add_session and del_session like IO::Socket::SSL::Session_Cache does). See the SSL_session_cache option of new() for more details. Note that this sets the default cache globally, so use with caution. =item B With this function one can set defaults for all SSL_* parameter used for creation of the context, like the SSL_verify* parameter. Any SSL_* parameter can be given or the following short versions: =over 8 =item mode - SSL_verify_mode =item callback - SSL_verify_callback =item scheme - SSL_verifycn_scheme =item name - SSL_verifycn_name =back =item B Similar to C, but only sets the defaults for client mode. =item B Similar to C, but only sets the defaults for server mode. =item B Sometimes one has to use code which uses unwanted or invalid arguments for SSL, typically disabling SSL verification or setting wrong ciphers or SSL versions. With this hack it is possible to override these settings and restore sanity. Example: IO::Socket::SSL::set_args_filter_hack( sub { my ($is_server,$args) = @_; if ( ! $is_server ) { # client settings - enable verification with default CA # and fallback hostname verification etc delete @{$args}{qw( SSL_verify_mode SSL_ca_file SSL_ca_path SSL_verifycn_scheme SSL_version )}; # and add some fingerprints for known certs which are signed by # unknown CAs or are self-signed $args->{SSL_fingerprint} = ... } }); With the short setting C it will prefer the default settings in all cases. These default settings can be modified with C, C and C. =back The following methods are unsupported (not to mention futile!) and IO::Socket::SSL will emit a large CROAK() if you are silly enough to use them: =over 4 =item truncate =item stat =item ungetc =item setbuf =item setvbuf =item fdopen =item send/recv Note that send() and recv() cannot be reliably trapped by a tied filehandle (such as that used by IO::Socket::SSL) and so may send unencrypted data over the socket. Object-oriented calls to these functions will fail, telling you to use the print/printf/syswrite and read/sysread families instead. =back =head1 DEPRECATIONS The following functions are deprecated and are only retained for compatibility: =over 2 =item context_init() use the SSL_reuse_ctx option if you want to re-use a context =item socketToSSL() and socket_to_SSL() use IO::Socket::SSL->start_SSL() instead =item kill_socket() use close() instead =item get_peer_certificate() use the peer_certificate() function instead. Used to return X509_Certificate with methods subject_name and issuer_name. Now simply returns $self which has these methods (although deprecated). =item issuer_name() use peer_certificate( 'issuer' ) instead =item subject_name() use peer_certificate( 'subject' ) instead =back =head1 EXAMPLES See the 'example' directory, the tests in 't' and also the tools in 'util'. =head1 BUGS If you use IO::Socket::SSL together with threads you should load it (e.g. use or require) inside the main thread before creating any other threads which use it. This way it is much faster because it will be initialized only once. Also there are reports that it might crash the other way. Creating an IO::Socket::SSL object in one thread and closing it in another thread will not work. IO::Socket::SSL does not work together with Storable::fd_retrieve/fd_store. See BUGS file for more information and how to work around the problem. Non-blocking and timeouts (which are based on non-blocking) are not supported on Win32, because the underlying IO::Socket::INET does not support non-blocking on this platform. If you have a server and it looks like you have a memory leak you might check the size of your session cache. Default for Net::SSLeay seems to be 20480, see the example for SSL_create_ctx_callback for how to limit it. TLS 1.3 support regarding session reuse is incomplete. =head1 SEE ALSO IO::Socket::INET, IO::Socket::INET6, IO::Socket::IP, Net::SSLeay. =head1 THANKS Many thanks to all who added patches or reported bugs or helped IO::Socket::SSL another way. Please keep reporting bugs and help with patches, even if they just fix the documentation. Special thanks to the team of Net::SSLeay for the good cooperation. =head1 AUTHORS Steffen Ullrich, is the current maintainer. Peter Behroozi, (Note the lack of an "i" at the end of "behrooz") Marko Asplund, , was the original author of IO::Socket::SSL. Patches incorporated from various people, see file Changes. =head1 COPYRIGHT The original versions of this module are Copyright (C) 1999-2002 Marko Asplund. The rewrite of this module is Copyright (C) 2002-2005 Peter Behroozi. Versions 0.98 and newer are Copyright (C) 2006-2014 Steffen Ullrich. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. PKH]',$file ) or croak("cannot write $file: $!"); print $fh $string; } sub PEM_string2cert { my $string = shift; my $bio = Net::SSLeay::BIO_new( Net::SSLeay::BIO_s_mem()); Net::SSLeay::BIO_write($bio,$string); my $cert = Net::SSLeay::PEM_read_bio_X509($bio); Net::SSLeay::BIO_free($bio); $cert or croak "cannot parse string as PEM X509 cert: ". Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error()); return $cert; } sub PEM_cert2string { my $cert = shift; return Net::SSLeay::PEM_get_string_X509($cert) || croak("cannot get string from cert"); } sub PEM_file2key { my $file = shift; my $bio = Net::SSLeay::BIO_new_file($file,'r') or croak "cannot read $file: $!"; my $key = Net::SSLeay::PEM_read_bio_PrivateKey($bio); Net::SSLeay::BIO_free($bio); $key or croak "cannot parse $file as PEM private key: ". Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error()); return $key; } sub PEM_key2file { my ($key,$file) = @_; my $string = Net::SSLeay::PEM_get_string_PrivateKey($key) or croak("cannot get string from key"); open( my $fh,'>',$file ) or croak("cannot write $file: $!"); print $fh $string; } sub PEM_string2key { my $string = shift; my $bio = Net::SSLeay::BIO_new( Net::SSLeay::BIO_s_mem()); Net::SSLeay::BIO_write($bio,$string); my $key = Net::SSLeay::PEM_read_bio_PrivateKey($bio); Net::SSLeay::BIO_free($bio); $key or croak "cannot parse string as PEM private key: ". Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error()); return $key; } sub PEM_key2string { my $key = shift; return Net::SSLeay::PEM_get_string_PrivateKey($key) || croak("cannot get string from key"); } sub CERT_free { my $cert = shift or return; Net::SSLeay::X509_free($cert); } sub KEY_free { my $key = shift or return; Net::SSLeay::EVP_PKEY_free($key); } sub KEY_create_rsa { my $bits = shift || 2048; my $key = Net::SSLeay::EVP_PKEY_new(); my $rsa = Net::SSLeay::RSA_generate_key($bits, 0x10001); # 0x10001 = RSA_F4 Net::SSLeay::EVP_PKEY_assign_RSA($key,$rsa); return $key; } if (defined &Net::SSLeay::EC_KEY_generate_key) { push @EXPORT,'KEY_create_ec'; *KEY_create_ec = sub { my $curve = shift || 'prime256v1'; my $key = Net::SSLeay::EVP_PKEY_new(); my $ec = Net::SSLeay::EC_KEY_generate_key($curve); Net::SSLeay::EVP_PKEY_assign_EC_KEY($key,$ec); return $key; } } # extract information from cert my %gen2i = qw( OTHERNAME 0 EMAIL 1 DNS 2 X400 3 DIRNAME 4 EDIPARTY 5 URI 6 IP 7 RID 8 ); my %i2gen = reverse %gen2i; sub CERT_asHash { my $cert = shift; my $digest_name = shift || 'sha256'; my %hash = ( version => Net::SSLeay::X509_get_version($cert), not_before => _asn1t2t(Net::SSLeay::X509_get_notBefore($cert)), not_after => _asn1t2t(Net::SSLeay::X509_get_notAfter($cert)), serial => Net::SSLeay::P_ASN1_INTEGER_get_dec( Net::SSLeay::X509_get_serialNumber($cert)), signature_alg => Net::SSLeay::OBJ_obj2txt ( Net::SSLeay::P_X509_get_signature_alg($cert)), crl_uri => [ Net::SSLeay::P_X509_get_crl_distribution_points($cert) ], keyusage => [ Net::SSLeay::P_X509_get_key_usage($cert) ], extkeyusage => { oid => [ Net::SSLeay::P_X509_get_ext_key_usage($cert,0) ], nid => [ Net::SSLeay::P_X509_get_ext_key_usage($cert,1) ], sn => [ Net::SSLeay::P_X509_get_ext_key_usage($cert,2) ], ln => [ Net::SSLeay::P_X509_get_ext_key_usage($cert,3) ], }, "pubkey_digest_$digest_name" => Net::SSLeay::X509_pubkey_digest( $cert,_digest($digest_name)), "x509_digest_$digest_name" => Net::SSLeay::X509_digest( $cert,_digest($digest_name)), "fingerprint_$digest_name" => Net::SSLeay::X509_get_fingerprint( $cert,$digest_name), ); my $subj = Net::SSLeay::X509_get_subject_name($cert); my %subj; for ( 0..Net::SSLeay::X509_NAME_entry_count($subj)-1 ) { my $e = Net::SSLeay::X509_NAME_get_entry($subj,$_); my $o = Net::SSLeay::X509_NAME_ENTRY_get_object($e); $subj{ Net::SSLeay::OBJ_obj2txt($o) } = Net::SSLeay::P_ASN1_STRING_get( Net::SSLeay::X509_NAME_ENTRY_get_data($e)); } $hash{subject} = \%subj; if ( my @names = Net::SSLeay::X509_get_subjectAltNames($cert) ) { my $alt = $hash{subjectAltNames} = []; while (my ($t,$v) = splice(@names,0,2)) { $t = $i2gen{$t} || die "unknown type $t in subjectAltName"; if ( $t eq 'IP' ) { if (length($v) == 4) { $v = join('.',unpack("CCCC",$v)); } elsif ( length($v) == 16 ) { my @v = unpack("nnnnnnnn",$v); my ($best0,$last0); for(my $i=0;$i<@v;$i++) { if ($v[$i] == 0) { if ($last0) { $last0->[1] = $i; $last0->[2]++; $best0 = $last0 if ++$last0->[2]>$best0->[2]; } else { $last0 = [ $i,$i,0 ]; $best0 ||= $last0; } } else { $last0 = undef; } } if ($best0) { $v = ''; $v .= join(':', map { sprintf( "%x",$_) } @v[0..$best0->[0]-1]) if $best0->[0]>0; $v .= '::'; $v .= join(':', map { sprintf( "%x",$_) } @v[$best0->[1]+1..$#v]) if $best0->[1]<$#v; } else { $v = join(':', map { sprintf( "%x",$_) } @v); } } } push @$alt,[$t,$v] } } my $issuer = Net::SSLeay::X509_get_issuer_name($cert); my %issuer; for ( 0..Net::SSLeay::X509_NAME_entry_count($issuer)-1 ) { my $e = Net::SSLeay::X509_NAME_get_entry($issuer,$_); my $o = Net::SSLeay::X509_NAME_ENTRY_get_object($e); $issuer{ Net::SSLeay::OBJ_obj2txt($o) } = Net::SSLeay::P_ASN1_STRING_get( Net::SSLeay::X509_NAME_ENTRY_get_data($e)); } $hash{issuer} = \%issuer; my @ext; for( 0..Net::SSLeay::X509_get_ext_count($cert)-1 ) { my $e = Net::SSLeay::X509_get_ext($cert,$_); my $o = Net::SSLeay::X509_EXTENSION_get_object($e); my $nid = Net::SSLeay::OBJ_obj2nid($o); push @ext, { oid => Net::SSLeay::OBJ_obj2txt($o), nid => ( $nid > 0 ) ? $nid : undef, sn => ( $nid > 0 ) ? Net::SSLeay::OBJ_nid2sn($nid) : undef, critical => Net::SSLeay::X509_EXTENSION_get_critical($e), data => Net::SSLeay::X509V3_EXT_print($e), } } $hash{ext} = \@ext; if ( defined(&Net::SSLeay::P_X509_get_ocsp_uri)) { $hash{ocsp_uri} = [ Net::SSLeay::P_X509_get_ocsp_uri($cert) ]; } else { $hash{ocsp_uri} = []; for( @ext ) { $_->{sn} or next; $_->{sn} eq 'authorityInfoAccess' or next; push @{ $hash{ocsp_uri}}, $_->{data} =~m{\bOCSP - URI:(\S+)}g; } } return \%hash; } sub CERT_create { my %args = @_%2 ? %{ shift() } : @_; my $cert = Net::SSLeay::X509_new(); my $digest_name = delete $args{digest} || 'sha256'; Net::SSLeay::ASN1_INTEGER_set( Net::SSLeay::X509_get_serialNumber($cert), delete $args{serial} || rand(2**32), ); # version default to 2 (V3) Net::SSLeay::X509_set_version($cert, delete $args{version} || 2 ); # not_before default to now Net::SSLeay::ASN1_TIME_set( Net::SSLeay::X509_get_notBefore($cert), delete $args{not_before} || time() ); # not_after default to now+365 days Net::SSLeay::ASN1_TIME_set( Net::SSLeay::X509_get_notAfter($cert), delete $args{not_after} || time() + 365*86400 ); # set subject my $subj_e = Net::SSLeay::X509_get_subject_name($cert); my $subj = delete $args{subject} || { organizationName => 'IO::Socket::SSL', commonName => 'IO::Socket::SSL Test' }; while ( my ($k,$v) = each %$subj ) { # Not everything we get is nice - try with MBSTRING_UTF8 first and if it # fails try V_ASN1_T61STRING and finally V_ASN1_OCTET_STRING Net::SSLeay::X509_NAME_add_entry_by_txt($subj_e,$k,0x1000,$v,-1,0) or Net::SSLeay::X509_NAME_add_entry_by_txt($subj_e,$k,20,$v,-1,0) or Net::SSLeay::X509_NAME_add_entry_by_txt($subj_e,$k,4,$v,-1,0) or croak("failed to add entry for $k - ". Net::SSLeay::ERR_error_string(Net::SSLeay::ERR_get_error())); } my @ext = ( &Net::SSLeay::NID_subject_key_identifier => 'hash', &Net::SSLeay::NID_authority_key_identifier => 'keyid', ); if ( my $altsubj = delete $args{subjectAltNames} ) { push @ext, &Net::SSLeay::NID_subject_alt_name => join(',', map { "$_->[0]:$_->[1]" } @$altsubj) } my $key = delete $args{key} || KEY_create_rsa(); Net::SSLeay::X509_set_pubkey($cert,$key); my $is = delete $args{issuer}; my $issuer_cert = delete $args{issuer_cert} || $is && $is->[0] || $cert; my $issuer_key = delete $args{issuer_key} || $is && $is->[1] || $key; my %purpose; if (my $p = delete $args{purpose}) { if (!ref($p)) { $purpose{lc($2)} = (!$1 || $1 eq '+') ? 1:0 while $p =~m{([+-]?)(\w+)}g; } elsif (ref($p) eq 'ARRAY') { for(@$p) { m{^([+-]?)(\w+)$} or die "invalid entry in purpose: $_"; $purpose{lc($2)} = (!$1 || $1 eq '+') ? 1:0 } } else { while( my ($k,$v) = each %$p) { $purpose{lc($k)} = ($v && $v ne '-')?1:0; } } } if (delete $args{CA}) { # add defaults for CA %purpose = ( ca => 1, sslca => 1, emailca => 1, objca => 1, %purpose ); } if (!%purpose) { %purpose = (server => 1, client => 1); } my (%key_usage,%ext_key_usage,%cert_type,%basic_constraints); my %dS = ( digitalSignature => \%key_usage ); my %kE = ( keyEncipherment => \%key_usage ); my %CA = ( 'CA:TRUE' => \%basic_constraints, %dS, keyCertSign => \%key_usage ); my @disable; for( [ client => { %dS, %kE, clientAuth => \%ext_key_usage, client => \%cert_type } ], [ server => { %dS, %kE, serverAuth => \%ext_key_usage, server => \%cert_type } ], [ email => { %dS, %kE, emailProtection => \%ext_key_usage, email => \%cert_type } ], [ objsign => { %dS, %kE, codeSigning => \%ext_key_usage, objsign => \%cert_type } ], [ CA => { %CA }], [ sslCA => { %CA, sslCA => \%cert_type }], [ emailCA => { %CA, emailCA => \%cert_type }], [ objCA => { %CA, objCA => \%cert_type }], [ emailProtection => { %dS, %kE, emailProtection => \%ext_key_usage, email => \%cert_type } ], [ codeSigning => { %dS, %kE, codeSigning => \%ext_key_usage, objsign => \%cert_type } ], [ timeStamping => { timeStamping => \%ext_key_usage } ], [ digitalSignature => { digitalSignature => \%key_usage } ], [ nonRepudiation => { nonRepudiation => \%key_usage } ], [ keyEncipherment => { keyEncipherment => \%key_usage } ], [ dataEncipherment => { dataEncipherment => \%key_usage } ], [ keyAgreement => { keyAgreement => \%key_usage } ], [ keyCertSign => { keyCertSign => \%key_usage } ], [ cRLSign => { cRLSign => \%key_usage } ], [ encipherOnly => { encipherOnly => \%key_usage } ], [ decipherOnly => { decipherOnly => \%key_usage } ], [ clientAuth => { clientAuth => \%ext_key_usage } ], [ serverAuth => { serverAuth => \%ext_key_usage } ], ) { exists $purpose{lc($_->[0])} or next; if (delete $purpose{lc($_->[0])}) { while (my($k,$h) = each %{$_->[1]}) { $h->{$k} = 1; } } else { push @disable, $_->[1]; } } die "unknown purpose ".join(",",keys %purpose) if %purpose; for(@disable) { while (my($k,$h) = each %$_) { delete $h->{$k}; } } if (%basic_constraints) { push @ext,&Net::SSLeay::NID_basic_constraints, => join(",",'critical', sort keys %basic_constraints); } else { push @ext, &Net::SSLeay::NID_basic_constraints => 'critical,CA:FALSE'; } push @ext,&Net::SSLeay::NID_key_usage => join(",",'critical', sort keys %key_usage) if %key_usage; push @ext,&Net::SSLeay::NID_netscape_cert_type => join(",",sort keys %cert_type) if %cert_type; push @ext,&Net::SSLeay::NID_ext_key_usage => join(",",sort keys %ext_key_usage) if %ext_key_usage; Net::SSLeay::P_X509_add_extensions($cert, $issuer_cert, @ext); my %have_ext; for(my $i=0;$i<@ext;$i+=2) { $have_ext{ $ext[$i] }++ } for my $ext (@{ $args{ext} || [] }) { my $nid = $ext->{nid} || $ext->{sn} && Net::SSLeay::OBJ_sn2nid($ext->{sn}) || croak "cannot determine NID of extension"; $have_ext{$nid} and next; my $val = $ext->{data}; if ($nid == 177) { # authorityInfoAccess: # OpenSSL i2v does not output the same way as expected by i2v :( for (split(/\n/,$val)) { s{ - }{;}; # "OCSP - URI:..." -> "OCSP;URI:..." $_ = "critical,$_" if $ext->{critical}; Net::SSLeay::P_X509_add_extensions($cert,$issuer_cert,$nid,$_); } } else { $val = "critical,$val" if $ext->{critical}; Net::SSLeay::P_X509_add_extensions($cert, $issuer_cert, $nid, $val); } } Net::SSLeay::X509_set_issuer_name($cert, Net::SSLeay::X509_get_subject_name($issuer_cert)); Net::SSLeay::X509_sign($cert,$issuer_key,_digest($digest_name)); return ($cert,$key); } if ( defined &Net::SSLeay::ASN1_TIME_timet ) { *_asn1t2t = \&Net::SSLeay::ASN1_TIME_timet } else { require Time::Local; my %mon2i = qw( Jan 0 Feb 1 Mar 2 Apr 3 May 4 Jun 5 Jul 6 Aug 7 Sep 8 Oct 9 Nov 10 Dec 11 ); *_asn1t2t = sub { my $t = Net::SSLeay::P_ASN1_TIME_put2string( shift ); my ($mon,$d,$h,$m,$s,$y,$tz) = split(/[\s:]+/,$t); defined( $mon = $mon2i{$mon} ) or die "invalid month in $t"; $tz ||= $y =~s{^(\d+)([A-Z]\S*)}{$1} && $2; if ( ! $tz ) { return Time::Local::timelocal($s,$m,$h,$d,$mon,$y) } elsif ( $tz eq 'GMT' ) { return Time::Local::timegm($s,$m,$h,$d,$mon,$y) } else { die "unexpected TZ $tz from ASN1_TIME_print"; } } } { my %digest; sub _digest { my $digest_name = shift; return $digest{$digest_name} ||= do { Net::SSLeay::SSLeay_add_ssl_algorithms(); Net::SSLeay::EVP_get_digestbyname($digest_name) or die "Digest algorithm $digest_name is not available"; }; } } 1; __END__ =head1 NAME IO::Socket::SSL::Utils -- loading, storing, creating certificates and keys =head1 SYNOPSIS use IO::Socket::SSL::Utils; my $cert = PEM_file2cert('cert.pem'); # load certificate from file my $string = PEM_cert2string($cert); # convert certificate to PEM string CERT_free($cert); # free memory within OpenSSL my $key = KEY_create_rsa(2048); # create new 2048-bit RSA key PEM_string2file($key,"key.pem"); # and write it to file KEY_free($key); # free memory within OpenSSL =head1 DESCRIPTION This module provides various utility functions to work with certificates and private keys, shielding some of the complexity of the underlying Net::SSLeay and OpenSSL. =head1 FUNCTIONS =over 4 =item * Functions converting between string or file and certificates and keys. They croak if the operation cannot be completed. =over 8 =item PEM_file2cert(file) -> cert =item PEM_cert2file(cert,file) =item PEM_string2cert(string) -> cert =item PEM_cert2string(cert) -> string =item PEM_file2key(file) -> key =item PEM_key2file(key,file) =item PEM_string2key(string) -> key =item PEM_key2string(key) -> string =back =item * Functions for cleaning up. Each loaded or created cert and key must be freed to not leak memory. =over 8 =item CERT_free(cert) =item KEY_free(key) =back =item * KEY_create_rsa(bits) -> key Creates an RSA key pair, bits defaults to 2048. =item * KEY_create_ec(curve) -> key Creates an EC key, curve defaults to C. =item * CERT_asHash(cert,[digest_algo]) -> hash Extracts the information from the certificate into a hash and uses the given digest_algo (default: SHA-256) to determine digest of pubkey and cert. The resulting hash contains: =over 8 =item subject Hash with the parts of the subject, e.g. commonName, countryName, organizationName, stateOrProvinceName, localityName. =item subjectAltNames Array with list of alternative names. Each entry in the list is of C<[type,value]>, where C can be OTHERNAME, EMAIL, DNS, X400, DIRNAME, EDIPARTY, URI, IP or RID. =item issuer Hash with the parts of the issuer, e.g. commonName, countryName, organizationName, stateOrProvinceName, localityName. =item not_before, not_after The time frame, where the certificate is valid, as time_t, e.g. can be converted with localtime or similar functions. =item serial The serial number =item crl_uri List of URIs for CRL distribution. =item ocsp_uri List of URIs for revocation checking using OCSP. =item keyusage List of keyUsage information in the certificate. =item extkeyusage List of extended key usage information from the certificate. Each entry in this list consists of a hash with oid, nid, ln and sn. =item pubkey_digest_xxx Binary digest of the pubkey using the given digest algorithm, e.g. pubkey_digest_sha256 if (the default) SHA-256 was used. =item x509_digest_xxx Binary digest of the X.509 certificate using the given digest algorithm, e.g. x509_digest_sha256 if (the default) SHA-256 was used. =item fingerprint_xxx Fingerprint of the certificate using the given digest algorithm, e.g. fingerprint_sha256 if (the default) SHA-256 was used. Contrary to digest_* this is an ASCII string with a list if hexadecimal numbers, e.g. "73:59:75:5C:6D...". =item signature_alg Algorithm used to sign certificate, e.g. C. =item ext List of extensions. Each entry in the list is a hash with oid, nid, sn, critical flag (boolean) and data (string representation given by X509V3_EXT_print). =item version Certificate version, usually 2 (x509v3) =back =item * CERT_create(hash) -> (cert,key) Creates a certificate based on the given hash. If the issuer is not specified the certificate will be self-signed. The following keys can be given: =over 8 =item subject Hash with the parts of the subject, e.g. commonName, countryName, ... as described in C. Default points to IO::Socket::SSL. =item not_before A time_t value when the certificate starts to be valid. Defaults to current time. =item not_after A time_t value when the certificate ends to be valid. Defaults to current time plus one 365 days. =item serial The serial number. If not given a random number will be used. =item version The version of the certificate, default 2 (x509v3). =item CA true|false If true declare certificate as CA, defaults to false. =item purpose string|array|hash Set the purpose of the certificate. The different purposes can be given as a string separated by non-word character, as array or hash. With string or array each purpose can be prefixed with '+' (enable) or '-' (disable) and same can be done with the value when given as a hash. By default enabling the purpose is assumed. If the CA option is given and true the defaults "ca,sslca,emailca,objca" are assumed, but can be overridden with explicit purpose. If the CA option is given and false the defaults "server,client" are assumed. If no CA option and no purpose is given it defaults to "server,client". Purpose affects basicConstraints, keyUsage, extKeyUsage and netscapeCertType. The following purposes are defined (case is not important): client server email objsign CA sslCA emailCA objCA emailProtection codeSigning timeStamping digitalSignature nonRepudiation keyEncipherment dataEncipherment keyAgreement keyCertSign cRLSign encipherOnly decipherOnly Examples: # root-CA for SSL certificates purpose => 'sslCA' # or CA => 1 # server certificate and CA (typically self-signed) purpose => 'sslCA,server' # client certificate purpose => 'client', =item ext [{ sn => .., data => ... }, ... ] List of extensions. The type of the extension can be specified as name with C or as NID with C and the data with C. These data must be in the same syntax as expected within openssl.cnf, e.g. something like C. Additionally the critical flag can be set with C 1>. =item key key use given key as key for certificate, otherwise a new one will be generated and returned =item issuer_cert cert set issuer for new certificate =item issuer_key key sign new certificate with given key =item issuer [ cert, key ] Instead of giving issuer_key and issuer_cert as separate arguments they can be given both together. =item digest algorithm specify the algorithm used to sign the certificate, default SHA-256. =back =back =head1 AUTHOR Steffen Ullrich PKH]'``Socket/SSL/PublicSuffix.pmnu[ use strict; use warnings; package IO::Socket::SSL::PublicSuffix; use Carp; # for updates use constant URL => 'http://publicsuffix.org/list/effective_tld_names.dat'; =head1 NAME IO::Socket::SSL::PublicSuffix - provide access to Mozilla's list of effective TLD names =head1 SYNOPSIS # use builtin default use IO::Socket::SSL::PublicSuffix; $ps = IO::Socket::SSL::PublicSuffix->default; # load from string $ps = IO::Socket::SSL::PublicSuffix->from_string("*.uk\n*"); # load from file or file handle $ps = IO::Socket::SSL::PublicSuffix->from_file($filename); $ps = IO::Socket::SSL::PublicSuffix->from_file(\*STDIN); # --- string in -> string out # $rest -> whatever.host # $tld -> co.uk my ($rest,$tld) = $ps->public_suffix('whatever.host.co.uk'); my $tld = $ps->public_suffix('whatever.host.co.uk'); # $root_domain -> host.co.uk my $root_domain = $ps->public_suffix('whatever.host.co.uk', 1); # --- array in -> array out # $rest -> [qw(whatever host)] # $tld -> [qw(co uk)] my ($rest,$tld) = $ps->public_suffix([qw(whatever host co uk)]); ---- # To update this file with the current list: perl -MIO::Socket::SSL::PublicSuffix -e 'IO::Socket::SSL::PublicSuffix::update_self_from_url()' =head1 DESCRIPTION This module uses the list of effective top level domain names from the mozilla project to determine the public top level domain for a given hostname. =head2 Method =over 4 =item class->default(%args) Returns object with builtin default. C can be given in C<%args> to specify the minimal suffix, default is 1. =item class->from_string(string,%args) Returns object with configuration from string. See method C for C<%args>. =item class->from_file( file name| file handle, %args ) Returns object with configuration from file or file handle. See method C for C<%args>. =item $self->public_suffix( $host|\@host, [ $add ] ) In array context the function returns the non-tld part and the tld part of the given hostname, in scalar context only the tld part. It adds C<$add> parts of the non-tld part to the tld, e.g. with C<$add=1> it will return the root domain. If there were no explicit matches against the public suffix configuration it will fall back to a suffix of length 1. The function accepts a string or an array-ref (e.g. host split by C<.>). In the first case it will return string(s), in the latter case array-ref(s). International hostnames or labels can be in ASCII (IDNA form starting with C) or unicode. In the latter case an IDNA handling library like L, L or recent versions of L need to be installed. =item ($self|class)->can_idn Returns true if IDN support is available. =back =head1 FILES http://publicsuffix.org/list/effective_tld_names.dat =head1 SEE ALSO Domain::PublicSuffix, Mozilla::PublicSuffix =head1 BUGS Q: Why yet another module, we already have L and L. A: Because the public suffix data change more often than these modules do, IO::Socket::SSL needs this list and it is more easy this way to keep it up-to-date. =head1 AUTHOR Steffen Ullrich =cut BEGIN { if ( eval { require URI::_idna; defined &URI::_idna::encode && defined &URI::_idna::decode }) { *idn_to_ascii = \&URI::_idna::encode; *idn_to_unicode = \&URI::_idna::decode; *can_idn = sub { 1 }; } elsif ( eval { require Net::IDN::Encode } ) { *idn_to_ascii = \&Net::IDN::Encode::domain_to_ascii; *idn_to_unicode = \&Net::IDN::Encode::domain_to_unicode; *can_idn = sub { 1 }; } elsif ( eval { require Net::LibIDN; require Encode } ) { # Net::LibIDN does not use utf-8 flag and expects raw data *idn_to_ascii = sub { Net::LibIDN::idn_to_ascii(Encode::encode('utf-8',$_[0]),'utf-8'); }, *idn_to_unicode = sub { Encode::decode('utf-8',Net::LibIDN::idn_to_unicode($_[0],'utf-8')); }, *can_idn = sub { 1 }; } else { *idn_to_ascii = sub { croak "idn_to_ascii(@_) - no IDNA library installed" }; *idn_to_unicode = sub { croak "idn_to_unicode(@_) - no IDNA library installed" }; *can_idn = sub { 0 }; } } { my %default; sub default { my (undef,%args) = @_; my $min_suffix = delete $args{min_suffix}; $min_suffix = 1 if ! defined $min_suffix; %args and die "unknown args: ".join(" ",sort keys %args); return $default{$min_suffix} ||= shift->from_string(_default_data(), min_suffix => $min_suffix); } } sub from_string { my $class = shift; my $data = shift; open( my $fh,'<', \$data ); return $class->from_file($fh,@_); } sub from_file { my ($class,$file,%args) = @_; my $min_suffix = delete $args{min_suffix}; $min_suffix = 1 if ! defined $min_suffix; %args and die "unknown args: ".join(" ",sort keys %args); my $fh; if ( ref($file)) { $fh = $file } elsif ( ! open($fh,'<',$file)) { die "failed to open $file: $!"; } my %tree; local $/ = "\n"; while ( my $line = <$fh>) { $line =~s{//.*}{}; $line =~s{\s+$}{}; $line eq '' and next; my $p = \%tree; $line = idn_to_ascii($line) if $line !~m{\A[\x00-\x7f]*\Z}; my $not = $line =~s{^!}{}; my @path = split(m{\.},$line); for(reverse @path) { $p = $p->{$_} ||= {} } $p->{'\0'} = $not ? -1:1; } return bless { tree => \%tree, min_suffix => $min_suffix },$class; } sub public_suffix { my ($self,$name,$add) = @_; my $want; # [a]rray, [s]tring, [u]nicode-string if ( ref($name)) { $want = 'a'; $name = [ @$name ]; # don't change input } else { return if ! defined $name; if ( $name !~m{\A[\x00-\x7f]*\Z} ) { $name = idn_to_ascii($name); $want = 'u'; } else { $want = 's'; } $name = lc($name); $name =~s{\.$}{}; $name = [ $name =~m{([^.]+)}g ]; } @$name or return; $_ = lc($_) for(@$name); my (%wild,%host,%xcept,@stack,$choices); my $p = $self->{tree}; for( my $i=0; $i<@$name; $i++ ) { $choices = []; if ( my $px = $p->{ $name->[$#$name-$i] } ) { # name match, continue with next path element push @$choices,$px; if ( my $end = $px->{'\0'} ) { ( $end>0 ? \%host : \%xcept )->{$i+1} = $end; } } if ( my $px = $p->{'*'} ) { # wildcard match, continue with next path element push @$choices,$px; if ( my $end = $px->{'\0'} ) { ( $end>0 ? \%wild : \%xcept )->{$i+1} = $end; } } next_choice: if ( @$choices ) { $p = shift(@$choices); push @stack, [ $choices, $i ] if @$choices; next; # go deeper } # backtrack @stack or last; ($choices,$i) = @{ pop(@stack) }; goto next_choice; } #warn Dumper([\%wild,\%host,\%xcept]); use Data::Dumper; # remove all exceptions from wildcards delete @wild{ keys %xcept } if %xcept; # get longest match my ($len) = sort { $b <=> $a } ( keys(%wild), keys(%host), map { $_-1 } keys(%xcept)); # if we have no matches use a minimum of min_suffix $len = $self->{min_suffix} if ! defined $len; $len += $add if $add; my $suffix; if ( $len < @$name ) { $suffix = [ splice( @$name, -$len, $len ) ]; } elsif ( $len > 0 ) { $suffix = $name; $name = [] } else { $suffix = [] } if ( $want ne 'a' ) { $suffix = join('.',@$suffix); $name = join('.',@$name); if ( $want eq 'u' ) { $suffix = idn_to_unicode($suffix); $name = idn_to_unicode($name); } } return wantarray ? ($name,$suffix):$suffix; } { my $data; sub _default_data { if ( ! defined $data ) { $data = _builtin_data(); $data =~s{^// ===END ICANN DOMAINS.*}{}ms or die "cannot find END ICANN DOMAINS"; } return $data; } } sub update_self_from_url { my $url = shift || URL(); my $dst = __FILE__; -w $dst or die "cannot write $dst"; open( my $fh,'<',$dst ) or die "open $dst: $!"; my $code = ''; local $/ = "\n"; while (<$fh>) { $code .= $_; m{<<\'END_BUILTIN_DATA\'} and last; } my $tail; while (<$fh>) { m{\AEND_BUILTIN_DATA\r?\n} or next; $tail = $_; last; } $tail .= do { local $/; <$fh> }; close($fh); require LWP::UserAgent; my $resp = LWP::UserAgent->new->get($url) or die "no response from $url"; die "no success url=$url code=".$resp->code." ".$resp->message if ! $resp->is_success; my $content = $resp->decoded_content; while ( $content =~m{(.*\n)}g ) { my $line = $1; if ( $line =~m{\S} && $line !~m{\A\s*//} ) { $line =~s{//.*}{}; $line =~s{\s+$}{}; $line eq '' and next; if ( $line !~m{\A[\x00-\x7f]+\Z} ) { $line = idn_to_ascii($line); } $code .= "$line\n"; } else { $code .= "$line"; } } open( $fh,'>:utf8',$dst ) or die "open $dst: $!"; print $fh $code.$tail; } sub _builtin_data { return <<'END_BUILTIN_DATA' } // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. // Please pull this list from, and only from https://publicsuffix.org/list/public_suffix_list.dat, // rather than any other VCS sites. Pulling from any other URL is not guaranteed to be supported. // Instructions on pulling and using this list can be found at https://publicsuffix.org/list/. // ===BEGIN ICANN DOMAINS=== // ac : https://en.wikipedia.org/wiki/.ac ac com.ac edu.ac gov.ac net.ac mil.ac org.ac // ad : https://en.wikipedia.org/wiki/.ad ad nom.ad // ae : https://en.wikipedia.org/wiki/.ae // see also: "Domain Name Eligibility Policy" at http://www.aeda.ae/eng/aepolicy.php ae co.ae net.ae org.ae sch.ae ac.ae gov.ae mil.ae // aero : see https://www.information.aero/index.php?id=66 aero accident-investigation.aero accident-prevention.aero aerobatic.aero aeroclub.aero aerodrome.aero agents.aero aircraft.aero airline.aero airport.aero air-surveillance.aero airtraffic.aero air-traffic-control.aero ambulance.aero amusement.aero association.aero author.aero ballooning.aero broker.aero caa.aero cargo.aero catering.aero certification.aero championship.aero charter.aero civilaviation.aero club.aero conference.aero consultant.aero consulting.aero control.aero council.aero crew.aero design.aero dgca.aero educator.aero emergency.aero engine.aero engineer.aero entertainment.aero equipment.aero exchange.aero express.aero federation.aero flight.aero freight.aero fuel.aero gliding.aero government.aero groundhandling.aero group.aero hanggliding.aero homebuilt.aero insurance.aero journal.aero journalist.aero leasing.aero logistics.aero magazine.aero maintenance.aero media.aero microlight.aero modelling.aero navigation.aero parachuting.aero paragliding.aero passenger-association.aero pilot.aero press.aero production.aero recreation.aero repbody.aero res.aero research.aero rotorcraft.aero safety.aero scientist.aero services.aero show.aero skydiving.aero software.aero student.aero trader.aero trading.aero trainer.aero union.aero workinggroup.aero works.aero // af : http://www.nic.af/help.jsp af gov.af com.af org.af net.af edu.af // ag : http://www.nic.ag/prices.htm ag com.ag org.ag net.ag co.ag nom.ag // ai : http://nic.com.ai/ ai off.ai com.ai net.ai org.ai // al : http://www.ert.gov.al/ert_alb/faq_det.html?Id=31 al com.al edu.al gov.al mil.al net.al org.al // am : https://en.wikipedia.org/wiki/.am am // ao : https://en.wikipedia.org/wiki/.ao // http://www.dns.ao/REGISTR.DOC ao ed.ao gv.ao og.ao co.ao pb.ao it.ao // aq : https://en.wikipedia.org/wiki/.aq aq // ar : https://nic.ar/nic-argentina/normativa-vigente ar com.ar edu.ar gob.ar gov.ar int.ar mil.ar musica.ar net.ar org.ar tur.ar // arpa : https://en.wikipedia.org/wiki/.arpa // Confirmed by registry 2008-06-18 arpa e164.arpa in-addr.arpa ip6.arpa iris.arpa uri.arpa urn.arpa // as : https://en.wikipedia.org/wiki/.as as gov.as // asia : https://en.wikipedia.org/wiki/.asia asia // at : https://en.wikipedia.org/wiki/.at // Confirmed by registry 2008-06-17 at ac.at co.at gv.at or.at // au : https://en.wikipedia.org/wiki/.au // http://www.auda.org.au/ au // 2LDs com.au net.au org.au edu.au gov.au asn.au id.au // Historic 2LDs (closed to new registration, but sites still exist) info.au conf.au oz.au // CGDNs - http://www.cgdn.org.au/ act.au nsw.au nt.au qld.au sa.au tas.au vic.au wa.au // 3LDs act.edu.au nsw.edu.au nt.edu.au qld.edu.au sa.edu.au tas.edu.au vic.edu.au wa.edu.au // act.gov.au Bug 984824 - Removed at request of Greg Tankard // nsw.gov.au Bug 547985 - Removed at request of // nt.gov.au Bug 940478 - Removed at request of Greg Connors qld.gov.au sa.gov.au tas.gov.au vic.gov.au wa.gov.au // aw : https://en.wikipedia.org/wiki/.aw aw com.aw // ax : https://en.wikipedia.org/wiki/.ax ax // az : https://en.wikipedia.org/wiki/.az az com.az net.az int.az gov.az org.az edu.az info.az pp.az mil.az name.az pro.az biz.az // ba : http://nic.ba/users_data/files/pravilnik_o_registraciji.pdf ba com.ba edu.ba gov.ba mil.ba net.ba org.ba // bb : https://en.wikipedia.org/wiki/.bb bb biz.bb co.bb com.bb edu.bb gov.bb info.bb net.bb org.bb store.bb tv.bb // bd : https://en.wikipedia.org/wiki/.bd *.bd // be : https://en.wikipedia.org/wiki/.be // Confirmed by registry 2008-06-08 be ac.be // bf : https://en.wikipedia.org/wiki/.bf bf gov.bf // bg : https://en.wikipedia.org/wiki/.bg // https://www.register.bg/user/static/rules/en/index.html bg a.bg b.bg c.bg d.bg e.bg f.bg g.bg h.bg i.bg j.bg k.bg l.bg m.bg n.bg o.bg p.bg q.bg r.bg s.bg t.bg u.bg v.bg w.bg x.bg y.bg z.bg 0.bg 1.bg 2.bg 3.bg 4.bg 5.bg 6.bg 7.bg 8.bg 9.bg // bh : https://en.wikipedia.org/wiki/.bh bh com.bh edu.bh net.bh org.bh gov.bh // bi : https://en.wikipedia.org/wiki/.bi // http://whois.nic.bi/ bi co.bi com.bi edu.bi or.bi org.bi // biz : https://en.wikipedia.org/wiki/.biz biz // bj : https://en.wikipedia.org/wiki/.bj bj asso.bj barreau.bj gouv.bj // bm : http://www.bermudanic.bm/dnr-text.txt bm com.bm edu.bm gov.bm net.bm org.bm // bn : http://www.bnnic.bn/faqs bn com.bn edu.bn gov.bn net.bn org.bn // bo : https://nic.bo/delegacion2015.php#h-1.10 bo com.bo edu.bo gob.bo int.bo org.bo net.bo mil.bo tv.bo web.bo // Social Domains academia.bo agro.bo arte.bo blog.bo bolivia.bo ciencia.bo cooperativa.bo democracia.bo deporte.bo ecologia.bo economia.bo empresa.bo indigena.bo industria.bo info.bo medicina.bo movimiento.bo musica.bo natural.bo nombre.bo noticias.bo patria.bo politica.bo profesional.bo plurinacional.bo pueblo.bo revista.bo salud.bo tecnologia.bo tksat.bo transporte.bo wiki.bo // br : http://registro.br/dominio/categoria.html // Submitted by registry br 9guacu.br abc.br adm.br adv.br agr.br aju.br am.br anani.br aparecida.br arq.br art.br ato.br b.br barueri.br belem.br bhz.br bio.br blog.br bmd.br boavista.br bsb.br campinagrande.br campinas.br caxias.br cim.br cng.br cnt.br com.br contagem.br coop.br cri.br cuiaba.br curitiba.br def.br ecn.br eco.br edu.br emp.br eng.br esp.br etc.br eti.br far.br feira.br flog.br floripa.br fm.br fnd.br fortal.br fot.br foz.br fst.br g12.br ggf.br goiania.br gov.br // gov.br 26 states + df https://en.wikipedia.org/wiki/States_of_Brazil ac.gov.br al.gov.br am.gov.br ap.gov.br ba.gov.br ce.gov.br df.gov.br es.gov.br go.gov.br ma.gov.br mg.gov.br ms.gov.br mt.gov.br pa.gov.br pb.gov.br pe.gov.br pi.gov.br pr.gov.br rj.gov.br rn.gov.br ro.gov.br rr.gov.br rs.gov.br sc.gov.br se.gov.br sp.gov.br to.gov.br gru.br imb.br ind.br inf.br jab.br jampa.br jdf.br joinville.br jor.br jus.br leg.br lel.br londrina.br macapa.br maceio.br manaus.br maringa.br mat.br med.br mil.br morena.br mp.br mus.br natal.br net.br niteroi.br *.nom.br not.br ntr.br odo.br ong.br org.br osasco.br palmas.br poa.br ppg.br pro.br psc.br psi.br pvh.br qsl.br radio.br rec.br recife.br ribeirao.br rio.br riobranco.br riopreto.br salvador.br sampa.br santamaria.br santoandre.br saobernardo.br saogonca.br sjc.br slg.br slz.br sorocaba.br srv.br taxi.br teo.br the.br tmp.br trd.br tur.br tv.br udi.br vet.br vix.br vlog.br wiki.br zlg.br // bs : http://www.nic.bs/rules.html bs com.bs net.bs org.bs edu.bs gov.bs // bt : https://en.wikipedia.org/wiki/.bt bt com.bt edu.bt gov.bt net.bt org.bt // bv : No registrations at this time. // Submitted by registry bv // bw : https://en.wikipedia.org/wiki/.bw // http://www.gobin.info/domainname/bw.doc // list of other 2nd level tlds ? bw co.bw org.bw // by : https://en.wikipedia.org/wiki/.by // http://tld.by/rules_2006_en.html // list of other 2nd level tlds ? by gov.by mil.by // Official information does not indicate that com.by is a reserved // second-level domain, but it's being used as one (see www.google.com.by and // www.yahoo.com.by, for example), so we list it here for safety's sake. com.by // http://hoster.by/ of.by // bz : https://en.wikipedia.org/wiki/.bz // http://www.belizenic.bz/ bz com.bz net.bz org.bz edu.bz gov.bz // ca : https://en.wikipedia.org/wiki/.ca ca // ca geographical names ab.ca bc.ca mb.ca nb.ca nf.ca nl.ca ns.ca nt.ca nu.ca on.ca pe.ca qc.ca sk.ca yk.ca // gc.ca: https://en.wikipedia.org/wiki/.gc.ca // see also: http://registry.gc.ca/en/SubdomainFAQ gc.ca // cat : https://en.wikipedia.org/wiki/.cat cat // cc : https://en.wikipedia.org/wiki/.cc cc // cd : https://en.wikipedia.org/wiki/.cd // see also: https://www.nic.cd/domain/insertDomain_2.jsp?act=1 cd gov.cd // cf : https://en.wikipedia.org/wiki/.cf cf // cg : https://en.wikipedia.org/wiki/.cg cg // ch : https://en.wikipedia.org/wiki/.ch ch // ci : https://en.wikipedia.org/wiki/.ci // http://www.nic.ci/index.php?page=charte ci org.ci or.ci com.ci co.ci edu.ci ed.ci ac.ci net.ci go.ci asso.ci xn--aroport-bya.ci int.ci presse.ci md.ci gouv.ci // ck : https://en.wikipedia.org/wiki/.ck *.ck !www.ck // cl : https://en.wikipedia.org/wiki/.cl cl gov.cl gob.cl co.cl mil.cl // cm : https://en.wikipedia.org/wiki/.cm plus bug 981927 cm co.cm com.cm gov.cm net.cm // cn : https://en.wikipedia.org/wiki/.cn // Submitted by registry cn ac.cn com.cn edu.cn gov.cn net.cn org.cn mil.cn xn--55qx5d.cn xn--io0a7i.cn xn--od0alg.cn // cn geographic names ah.cn bj.cn cq.cn fj.cn gd.cn gs.cn gz.cn gx.cn ha.cn hb.cn he.cn hi.cn hl.cn hn.cn jl.cn js.cn jx.cn ln.cn nm.cn nx.cn qh.cn sc.cn sd.cn sh.cn sn.cn sx.cn tj.cn xj.cn xz.cn yn.cn zj.cn hk.cn mo.cn tw.cn // co : https://en.wikipedia.org/wiki/.co // Submitted by registry co arts.co com.co edu.co firm.co gov.co info.co int.co mil.co net.co nom.co org.co rec.co web.co // com : https://en.wikipedia.org/wiki/.com com // coop : https://en.wikipedia.org/wiki/.coop coop // cr : http://www.nic.cr/niccr_publico/showRegistroDominiosScreen.do cr ac.cr co.cr ed.cr fi.cr go.cr or.cr sa.cr // cu : https://en.wikipedia.org/wiki/.cu cu com.cu edu.cu org.cu net.cu gov.cu inf.cu // cv : https://en.wikipedia.org/wiki/.cv cv // cw : http://www.una.cw/cw_registry/ // Confirmed by registry 2013-03-26 cw com.cw edu.cw net.cw org.cw // cx : https://en.wikipedia.org/wiki/.cx // list of other 2nd level tlds ? cx gov.cx // cy : http://www.nic.cy/ // Submitted by registry Panayiotou Fotia cy ac.cy biz.cy com.cy ekloges.cy gov.cy ltd.cy name.cy net.cy org.cy parliament.cy press.cy pro.cy tm.cy // cz : https://en.wikipedia.org/wiki/.cz cz // de : https://en.wikipedia.org/wiki/.de // Confirmed by registry (with technical // reservations) 2008-07-01 de // dj : https://en.wikipedia.org/wiki/.dj dj // dk : https://en.wikipedia.org/wiki/.dk // Confirmed by registry 2008-06-17 dk // dm : https://en.wikipedia.org/wiki/.dm dm com.dm net.dm org.dm edu.dm gov.dm // do : https://en.wikipedia.org/wiki/.do do art.do com.do edu.do gob.do gov.do mil.do net.do org.do sld.do web.do // dz : https://en.wikipedia.org/wiki/.dz dz com.dz org.dz net.dz gov.dz edu.dz asso.dz pol.dz art.dz // ec : http://www.nic.ec/reg/paso1.asp // Submitted by registry ec com.ec info.ec net.ec fin.ec k12.ec med.ec pro.ec org.ec edu.ec gov.ec gob.ec mil.ec // edu : https://en.wikipedia.org/wiki/.edu edu // ee : http://www.eenet.ee/EENet/dom_reeglid.html#lisa_B ee edu.ee gov.ee riik.ee lib.ee med.ee com.ee pri.ee aip.ee org.ee fie.ee // eg : https://en.wikipedia.org/wiki/.eg eg com.eg edu.eg eun.eg gov.eg mil.eg name.eg net.eg org.eg sci.eg // er : https://en.wikipedia.org/wiki/.er *.er // es : https://www.nic.es/site_ingles/ingles/dominios/index.html es com.es nom.es org.es gob.es edu.es // et : https://en.wikipedia.org/wiki/.et et com.et gov.et org.et edu.et biz.et name.et info.et net.et // eu : https://en.wikipedia.org/wiki/.eu eu // fi : https://en.wikipedia.org/wiki/.fi fi // aland.fi : https://en.wikipedia.org/wiki/.ax // This domain is being phased out in favor of .ax. As there are still many // domains under aland.fi, we still keep it on the list until aland.fi is // completely removed. // TODO: Check for updates (expected to be phased out around Q1/2009) aland.fi // fj : https://en.wikipedia.org/wiki/.fj *.fj // fk : https://en.wikipedia.org/wiki/.fk *.fk // fm : https://en.wikipedia.org/wiki/.fm fm // fo : https://en.wikipedia.org/wiki/.fo fo // fr : http://www.afnic.fr/ // domaines descriptifs : http://www.afnic.fr/obtenir/chartes/nommage-fr/annexe-descriptifs fr com.fr asso.fr nom.fr prd.fr presse.fr tm.fr // domaines sectoriels : http://www.afnic.fr/obtenir/chartes/nommage-fr/annexe-sectoriels aeroport.fr assedic.fr avocat.fr avoues.fr cci.fr chambagri.fr chirurgiens-dentistes.fr experts-comptables.fr geometre-expert.fr gouv.fr greta.fr huissier-justice.fr medecin.fr notaires.fr pharmacien.fr port.fr veterinaire.fr // ga : https://en.wikipedia.org/wiki/.ga ga // gb : This registry is effectively dormant // Submitted by registry gb // gd : https://en.wikipedia.org/wiki/.gd gd // ge : http://www.nic.net.ge/policy_en.pdf ge com.ge edu.ge gov.ge org.ge mil.ge net.ge pvt.ge // gf : https://en.wikipedia.org/wiki/.gf gf // gg : http://www.channelisles.net/register-domains/ // Confirmed by registry 2013-11-28 gg co.gg net.gg org.gg // gh : https://en.wikipedia.org/wiki/.gh // see also: http://www.nic.gh/reg_now.php // Although domains directly at second level are not possible at the moment, // they have been possible for some time and may come back. gh com.gh edu.gh gov.gh org.gh mil.gh // gi : http://www.nic.gi/rules.html gi com.gi ltd.gi gov.gi mod.gi edu.gi org.gi // gl : https://en.wikipedia.org/wiki/.gl // http://nic.gl gl co.gl com.gl edu.gl net.gl org.gl // gm : http://www.nic.gm/htmlpages%5Cgm-policy.htm gm // gn : http://psg.com/dns/gn/gn.txt // Submitted by registry gn ac.gn com.gn edu.gn gov.gn org.gn net.gn // gov : https://en.wikipedia.org/wiki/.gov gov // gp : http://www.nic.gp/index.php?lang=en gp com.gp net.gp mobi.gp edu.gp org.gp asso.gp // gq : https://en.wikipedia.org/wiki/.gq gq // gr : https://grweb.ics.forth.gr/english/1617-B-2005.html // Submitted by registry gr com.gr edu.gr net.gr org.gr gov.gr // gs : https://en.wikipedia.org/wiki/.gs gs // gt : http://www.gt/politicas_de_registro.html gt com.gt edu.gt gob.gt ind.gt mil.gt net.gt org.gt // gu : http://gadao.gov.gu/register.html // University of Guam : https://www.uog.edu // Submitted by uognoc@triton.uog.edu gu com.gu edu.gu gov.gu guam.gu info.gu net.gu org.gu web.gu // gw : https://en.wikipedia.org/wiki/.gw gw // gy : https://en.wikipedia.org/wiki/.gy // http://registry.gy/ gy co.gy com.gy edu.gy gov.gy net.gy org.gy // hk : https://www.hkirc.hk // Submitted by registry hk com.hk edu.hk gov.hk idv.hk net.hk org.hk xn--55qx5d.hk xn--wcvs22d.hk xn--lcvr32d.hk xn--mxtq1m.hk xn--gmqw5a.hk xn--ciqpn.hk xn--gmq050i.hk xn--zf0avx.hk xn--io0a7i.hk xn--mk0axi.hk xn--od0alg.hk xn--od0aq3b.hk xn--tn0ag.hk xn--uc0atv.hk xn--uc0ay4a.hk // hm : https://en.wikipedia.org/wiki/.hm hm // hn : http://www.nic.hn/politicas/ps02,,05.html hn com.hn edu.hn org.hn net.hn mil.hn gob.hn // hr : http://www.dns.hr/documents/pdf/HRTLD-regulations.pdf hr iz.hr from.hr name.hr com.hr // ht : http://www.nic.ht/info/charte.cfm ht com.ht shop.ht firm.ht info.ht adult.ht net.ht pro.ht org.ht med.ht art.ht coop.ht pol.ht asso.ht edu.ht rel.ht gouv.ht perso.ht // hu : http://www.domain.hu/domain/English/sld.html // Confirmed by registry 2008-06-12 hu co.hu info.hu org.hu priv.hu sport.hu tm.hu 2000.hu agrar.hu bolt.hu casino.hu city.hu erotica.hu erotika.hu film.hu forum.hu games.hu hotel.hu ingatlan.hu jogasz.hu konyvelo.hu lakas.hu media.hu news.hu reklam.hu sex.hu shop.hu suli.hu szex.hu tozsde.hu utazas.hu video.hu // id : https://pandi.id/en/domain/registration-requirements/ id ac.id biz.id co.id desa.id go.id mil.id my.id net.id or.id ponpes.id sch.id web.id // ie : https://en.wikipedia.org/wiki/.ie ie gov.ie // il : http://www.isoc.org.il/domains/ il ac.il co.il gov.il idf.il k12.il muni.il net.il org.il // im : https://www.nic.im/ // Submitted by registry im ac.im co.im com.im ltd.co.im net.im org.im plc.co.im tt.im tv.im // in : https://en.wikipedia.org/wiki/.in // see also: https://registry.in/Policies // Please note, that nic.in is not an official eTLD, but used by most // government institutions. in co.in firm.in net.in org.in gen.in ind.in nic.in ac.in edu.in res.in gov.in mil.in // info : https://en.wikipedia.org/wiki/.info info // int : https://en.wikipedia.org/wiki/.int // Confirmed by registry 2008-06-18 int eu.int // io : http://www.nic.io/rules.html // list of other 2nd level tlds ? io com.io // iq : http://www.cmc.iq/english/iq/iqregister1.htm iq gov.iq edu.iq mil.iq com.iq org.iq net.iq // ir : http://www.nic.ir/Terms_and_Conditions_ir,_Appendix_1_Domain_Rules // Also see http://www.nic.ir/Internationalized_Domain_Names // Two .ir entries added at request of , 2010-04-16 ir ac.ir co.ir gov.ir id.ir net.ir org.ir sch.ir // xn--mgba3a4f16a.ir (.ir, Persian YEH) xn--mgba3a4f16a.ir // xn--mgba3a4fra.ir (.ir, Arabic YEH) xn--mgba3a4fra.ir // is : http://www.isnic.is/domain/rules.php // Confirmed by registry 2008-12-06 is net.is com.is edu.is gov.is org.is int.is // it : https://en.wikipedia.org/wiki/.it it gov.it edu.it // Reserved geo-names (regions and provinces): // http://www.nic.it/sites/default/files/docs/Regulation_assignation_v7.1.pdf // Regions abr.it abruzzo.it aosta-valley.it aostavalley.it bas.it basilicata.it cal.it calabria.it cam.it campania.it emilia-romagna.it emiliaromagna.it emr.it friuli-v-giulia.it friuli-ve-giulia.it friuli-vegiulia.it friuli-venezia-giulia.it friuli-veneziagiulia.it friuli-vgiulia.it friuliv-giulia.it friulive-giulia.it friulivegiulia.it friulivenezia-giulia.it friuliveneziagiulia.it friulivgiulia.it fvg.it laz.it lazio.it lig.it liguria.it lom.it lombardia.it lombardy.it lucania.it mar.it marche.it mol.it molise.it piedmont.it piemonte.it pmn.it pug.it puglia.it sar.it sardegna.it sardinia.it sic.it sicilia.it sicily.it taa.it tos.it toscana.it trentin-sud-tirol.it xn--trentin-sd-tirol-rzb.it trentin-sudtirol.it xn--trentin-sdtirol-7vb.it trentin-sued-tirol.it trentin-suedtirol.it trentino-a-adige.it trentino-aadige.it trentino-alto-adige.it trentino-altoadige.it trentino-s-tirol.it trentino-stirol.it trentino-sud-tirol.it xn--trentino-sd-tirol-c3b.it trentino-sudtirol.it xn--trentino-sdtirol-szb.it trentino-sued-tirol.it trentino-suedtirol.it trentino.it trentinoa-adige.it trentinoaadige.it trentinoalto-adige.it trentinoaltoadige.it trentinos-tirol.it trentinostirol.it trentinosud-tirol.it xn--trentinosd-tirol-rzb.it trentinosudtirol.it xn--trentinosdtirol-7vb.it trentinosued-tirol.it trentinosuedtirol.it trentinsud-tirol.it xn--trentinsd-tirol-6vb.it trentinsudtirol.it xn--trentinsdtirol-nsb.it trentinsued-tirol.it trentinsuedtirol.it tuscany.it umb.it umbria.it val-d-aosta.it val-daosta.it vald-aosta.it valdaosta.it valle-aosta.it valle-d-aosta.it valle-daosta.it valleaosta.it valled-aosta.it valledaosta.it vallee-aoste.it xn--valle-aoste-ebb.it vallee-d-aoste.it xn--valle-d-aoste-ehb.it valleeaoste.it xn--valleaoste-e7a.it valleedaoste.it xn--valledaoste-ebb.it vao.it vda.it ven.it veneto.it // Provinces ag.it agrigento.it al.it alessandria.it alto-adige.it altoadige.it an.it ancona.it andria-barletta-trani.it andria-trani-barletta.it andriabarlettatrani.it andriatranibarletta.it ao.it aosta.it aoste.it ap.it aq.it aquila.it ar.it arezzo.it ascoli-piceno.it ascolipiceno.it asti.it at.it av.it avellino.it ba.it balsan-sudtirol.it xn--balsan-sdtirol-nsb.it balsan-suedtirol.it balsan.it bari.it barletta-trani-andria.it barlettatraniandria.it belluno.it benevento.it bergamo.it bg.it bi.it biella.it bl.it bn.it bo.it bologna.it bolzano-altoadige.it bolzano.it bozen-sudtirol.it xn--bozen-sdtirol-2ob.it bozen-suedtirol.it bozen.it br.it brescia.it brindisi.it bs.it bt.it bulsan-sudtirol.it xn--bulsan-sdtirol-nsb.it bulsan-suedtirol.it bulsan.it bz.it ca.it cagliari.it caltanissetta.it campidano-medio.it campidanomedio.it campobasso.it carbonia-iglesias.it carboniaiglesias.it carrara-massa.it carraramassa.it caserta.it catania.it catanzaro.it cb.it ce.it cesena-forli.it xn--cesena-forl-mcb.it cesenaforli.it xn--cesenaforl-i8a.it ch.it chieti.it ci.it cl.it cn.it co.it como.it cosenza.it cr.it cremona.it crotone.it cs.it ct.it cuneo.it cz.it dell-ogliastra.it dellogliastra.it en.it enna.it fc.it fe.it fermo.it ferrara.it fg.it fi.it firenze.it florence.it fm.it foggia.it forli-cesena.it xn--forl-cesena-fcb.it forlicesena.it xn--forlcesena-c8a.it fr.it frosinone.it ge.it genoa.it genova.it go.it gorizia.it gr.it grosseto.it iglesias-carbonia.it iglesiascarbonia.it im.it imperia.it is.it isernia.it kr.it la-spezia.it laquila.it laspezia.it latina.it lc.it le.it lecce.it lecco.it li.it livorno.it lo.it lodi.it lt.it lu.it lucca.it macerata.it mantova.it massa-carrara.it massacarrara.it matera.it mb.it mc.it me.it medio-campidano.it mediocampidano.it messina.it mi.it milan.it milano.it mn.it mo.it modena.it monza-brianza.it monza-e-della-brianza.it monza.it monzabrianza.it monzaebrianza.it monzaedellabrianza.it ms.it mt.it na.it naples.it napoli.it no.it novara.it nu.it nuoro.it og.it ogliastra.it olbia-tempio.it olbiatempio.it or.it oristano.it ot.it pa.it padova.it padua.it palermo.it parma.it pavia.it pc.it pd.it pe.it perugia.it pesaro-urbino.it pesarourbino.it pescara.it pg.it pi.it piacenza.it pisa.it pistoia.it pn.it po.it pordenone.it potenza.it pr.it prato.it pt.it pu.it pv.it pz.it ra.it ragusa.it ravenna.it rc.it re.it reggio-calabria.it reggio-emilia.it reggiocalabria.it reggioemilia.it rg.it ri.it rieti.it rimini.it rm.it rn.it ro.it roma.it rome.it rovigo.it sa.it salerno.it sassari.it savona.it si.it siena.it siracusa.it so.it sondrio.it sp.it sr.it ss.it suedtirol.it xn--sdtirol-n2a.it sv.it ta.it taranto.it te.it tempio-olbia.it tempioolbia.it teramo.it terni.it tn.it to.it torino.it tp.it tr.it trani-andria-barletta.it trani-barletta-andria.it traniandriabarletta.it tranibarlettaandria.it trapani.it trento.it treviso.it trieste.it ts.it turin.it tv.it ud.it udine.it urbino-pesaro.it urbinopesaro.it va.it varese.it vb.it vc.it ve.it venezia.it venice.it verbania.it vercelli.it verona.it vi.it vibo-valentia.it vibovalentia.it vicenza.it viterbo.it vr.it vs.it vt.it vv.it // je : http://www.channelisles.net/register-domains/ // Confirmed by registry 2013-11-28 je co.je net.je org.je // jm : http://www.com.jm/register.html *.jm // jo : http://www.dns.jo/Registration_policy.aspx jo com.jo org.jo net.jo edu.jo sch.jo gov.jo mil.jo name.jo // jobs : https://en.wikipedia.org/wiki/.jobs jobs // jp : https://en.wikipedia.org/wiki/.jp // http://jprs.co.jp/en/jpdomain.html // Submitted by registry jp // jp organizational type names ac.jp ad.jp co.jp ed.jp go.jp gr.jp lg.jp ne.jp or.jp // jp prefecture type names aichi.jp akita.jp aomori.jp chiba.jp ehime.jp fukui.jp fukuoka.jp fukushima.jp gifu.jp gunma.jp hiroshima.jp hokkaido.jp hyogo.jp ibaraki.jp ishikawa.jp iwate.jp kagawa.jp kagoshima.jp kanagawa.jp kochi.jp kumamoto.jp kyoto.jp mie.jp miyagi.jp miyazaki.jp nagano.jp nagasaki.jp nara.jp niigata.jp oita.jp okayama.jp okinawa.jp osaka.jp saga.jp saitama.jp shiga.jp shimane.jp shizuoka.jp tochigi.jp tokushima.jp tokyo.jp tottori.jp toyama.jp wakayama.jp yamagata.jp yamaguchi.jp yamanashi.jp xn--4pvxs.jp xn--vgu402c.jp xn--c3s14m.jp xn--f6qx53a.jp xn--8pvr4u.jp xn--uist22h.jp xn--djrs72d6uy.jp xn--mkru45i.jp xn--0trq7p7nn.jp xn--8ltr62k.jp xn--2m4a15e.jp xn--efvn9s.jp xn--32vp30h.jp xn--4it797k.jp xn--1lqs71d.jp xn--5rtp49c.jp xn--5js045d.jp xn--ehqz56n.jp xn--1lqs03n.jp xn--qqqt11m.jp xn--kbrq7o.jp xn--pssu33l.jp xn--ntsq17g.jp xn--uisz3g.jp xn--6btw5a.jp xn--1ctwo.jp xn--6orx2r.jp xn--rht61e.jp xn--rht27z.jp xn--djty4k.jp xn--nit225k.jp xn--rht3d.jp xn--klty5x.jp xn--kltx9a.jp xn--kltp7d.jp xn--uuwu58a.jp xn--zbx025d.jp xn--ntso0iqx3a.jp xn--elqq16h.jp xn--4it168d.jp xn--klt787d.jp xn--rny31h.jp xn--7t0a264c.jp xn--5rtq34k.jp xn--k7yn95e.jp xn--tor131o.jp xn--d5qv7z876c.jp // jp geographic type names // http://jprs.jp/doc/rule/saisoku-1.html *.kawasaki.jp *.kitakyushu.jp *.kobe.jp *.nagoya.jp *.sapporo.jp *.sendai.jp *.yokohama.jp !city.kawasaki.jp !city.kitakyushu.jp !city.kobe.jp !city.nagoya.jp !city.sapporo.jp !city.sendai.jp !city.yokohama.jp // 4th level registration aisai.aichi.jp ama.aichi.jp anjo.aichi.jp asuke.aichi.jp chiryu.aichi.jp chita.aichi.jp fuso.aichi.jp gamagori.aichi.jp handa.aichi.jp hazu.aichi.jp hekinan.aichi.jp higashiura.aichi.jp ichinomiya.aichi.jp inazawa.aichi.jp inuyama.aichi.jp isshiki.aichi.jp iwakura.aichi.jp kanie.aichi.jp kariya.aichi.jp kasugai.aichi.jp kira.aichi.jp kiyosu.aichi.jp komaki.aichi.jp konan.aichi.jp kota.aichi.jp mihama.aichi.jp miyoshi.aichi.jp nishio.aichi.jp nisshin.aichi.jp obu.aichi.jp oguchi.aichi.jp oharu.aichi.jp okazaki.aichi.jp owariasahi.aichi.jp seto.aichi.jp shikatsu.aichi.jp shinshiro.aichi.jp shitara.aichi.jp tahara.aichi.jp takahama.aichi.jp tobishima.aichi.jp toei.aichi.jp togo.aichi.jp tokai.aichi.jp tokoname.aichi.jp toyoake.aichi.jp toyohashi.aichi.jp toyokawa.aichi.jp toyone.aichi.jp toyota.aichi.jp tsushima.aichi.jp yatomi.aichi.jp akita.akita.jp daisen.akita.jp fujisato.akita.jp gojome.akita.jp hachirogata.akita.jp happou.akita.jp higashinaruse.akita.jp honjo.akita.jp honjyo.akita.jp ikawa.akita.jp kamikoani.akita.jp kamioka.akita.jp katagami.akita.jp kazuno.akita.jp kitaakita.akita.jp kosaka.akita.jp kyowa.akita.jp misato.akita.jp mitane.akita.jp moriyoshi.akita.jp nikaho.akita.jp noshiro.akita.jp odate.akita.jp oga.akita.jp ogata.akita.jp semboku.akita.jp yokote.akita.jp yurihonjo.akita.jp aomori.aomori.jp gonohe.aomori.jp hachinohe.aomori.jp hashikami.aomori.jp hiranai.aomori.jp hirosaki.aomori.jp itayanagi.aomori.jp kuroishi.aomori.jp misawa.aomori.jp mutsu.aomori.jp nakadomari.aomori.jp noheji.aomori.jp oirase.aomori.jp owani.aomori.jp rokunohe.aomori.jp sannohe.aomori.jp shichinohe.aomori.jp shingo.aomori.jp takko.aomori.jp towada.aomori.jp tsugaru.aomori.jp tsuruta.aomori.jp abiko.chiba.jp asahi.chiba.jp chonan.chiba.jp chosei.chiba.jp choshi.chiba.jp chuo.chiba.jp funabashi.chiba.jp futtsu.chiba.jp hanamigawa.chiba.jp ichihara.chiba.jp ichikawa.chiba.jp ichinomiya.chiba.jp inzai.chiba.jp isumi.chiba.jp kamagaya.chiba.jp kamogawa.chiba.jp kashiwa.chiba.jp katori.chiba.jp katsuura.chiba.jp kimitsu.chiba.jp kisarazu.chiba.jp kozaki.chiba.jp kujukuri.chiba.jp kyonan.chiba.jp matsudo.chiba.jp midori.chiba.jp mihama.chiba.jp minamiboso.chiba.jp mobara.chiba.jp mutsuzawa.chiba.jp nagara.chiba.jp nagareyama.chiba.jp narashino.chiba.jp narita.chiba.jp noda.chiba.jp oamishirasato.chiba.jp omigawa.chiba.jp onjuku.chiba.jp otaki.chiba.jp sakae.chiba.jp sakura.chiba.jp shimofusa.chiba.jp shirako.chiba.jp shiroi.chiba.jp shisui.chiba.jp sodegaura.chiba.jp sosa.chiba.jp tako.chiba.jp tateyama.chiba.jp togane.chiba.jp tohnosho.chiba.jp tomisato.chiba.jp urayasu.chiba.jp yachimata.chiba.jp yachiyo.chiba.jp yokaichiba.chiba.jp yokoshibahikari.chiba.jp yotsukaido.chiba.jp ainan.ehime.jp honai.ehime.jp ikata.ehime.jp imabari.ehime.jp iyo.ehime.jp kamijima.ehime.jp kihoku.ehime.jp kumakogen.ehime.jp masaki.ehime.jp matsuno.ehime.jp matsuyama.ehime.jp namikata.ehime.jp niihama.ehime.jp ozu.ehime.jp saijo.ehime.jp seiyo.ehime.jp shikokuchuo.ehime.jp tobe.ehime.jp toon.ehime.jp uchiko.ehime.jp uwajima.ehime.jp yawatahama.ehime.jp echizen.fukui.jp eiheiji.fukui.jp fukui.fukui.jp ikeda.fukui.jp katsuyama.fukui.jp mihama.fukui.jp minamiechizen.fukui.jp obama.fukui.jp ohi.fukui.jp ono.fukui.jp sabae.fukui.jp sakai.fukui.jp takahama.fukui.jp tsuruga.fukui.jp wakasa.fukui.jp ashiya.fukuoka.jp buzen.fukuoka.jp chikugo.fukuoka.jp chikuho.fukuoka.jp chikujo.fukuoka.jp chikushino.fukuoka.jp chikuzen.fukuoka.jp chuo.fukuoka.jp dazaifu.fukuoka.jp fukuchi.fukuoka.jp hakata.fukuoka.jp higashi.fukuoka.jp hirokawa.fukuoka.jp hisayama.fukuoka.jp iizuka.fukuoka.jp inatsuki.fukuoka.jp kaho.fukuoka.jp kasuga.fukuoka.jp kasuya.fukuoka.jp kawara.fukuoka.jp keisen.fukuoka.jp koga.fukuoka.jp kurate.fukuoka.jp kurogi.fukuoka.jp kurume.fukuoka.jp minami.fukuoka.jp miyako.fukuoka.jp miyama.fukuoka.jp miyawaka.fukuoka.jp mizumaki.fukuoka.jp munakata.fukuoka.jp nakagawa.fukuoka.jp nakama.fukuoka.jp nishi.fukuoka.jp nogata.fukuoka.jp ogori.fukuoka.jp okagaki.fukuoka.jp okawa.fukuoka.jp oki.fukuoka.jp omuta.fukuoka.jp onga.fukuoka.jp onojo.fukuoka.jp oto.fukuoka.jp saigawa.fukuoka.jp sasaguri.fukuoka.jp shingu.fukuoka.jp shinyoshitomi.fukuoka.jp shonai.fukuoka.jp soeda.fukuoka.jp sue.fukuoka.jp tachiarai.fukuoka.jp tagawa.fukuoka.jp takata.fukuoka.jp toho.fukuoka.jp toyotsu.fukuoka.jp tsuiki.fukuoka.jp ukiha.fukuoka.jp umi.fukuoka.jp usui.fukuoka.jp yamada.fukuoka.jp yame.fukuoka.jp yanagawa.fukuoka.jp yukuhashi.fukuoka.jp aizubange.fukushima.jp aizumisato.fukushima.jp aizuwakamatsu.fukushima.jp asakawa.fukushima.jp bandai.fukushima.jp date.fukushima.jp fukushima.fukushima.jp furudono.fukushima.jp futaba.fukushima.jp hanawa.fukushima.jp higashi.fukushima.jp hirata.fukushima.jp hirono.fukushima.jp iitate.fukushima.jp inawashiro.fukushima.jp ishikawa.fukushima.jp iwaki.fukushima.jp izumizaki.fukushima.jp kagamiishi.fukushima.jp kaneyama.fukushima.jp kawamata.fukushima.jp kitakata.fukushima.jp kitashiobara.fukushima.jp koori.fukushima.jp koriyama.fukushima.jp kunimi.fukushima.jp miharu.fukushima.jp mishima.fukushima.jp namie.fukushima.jp nango.fukushima.jp nishiaizu.fukushima.jp nishigo.fukushima.jp okuma.fukushima.jp omotego.fukushima.jp ono.fukushima.jp otama.fukushima.jp samegawa.fukushima.jp shimogo.fukushima.jp shirakawa.fukushima.jp showa.fukushima.jp soma.fukushima.jp sukagawa.fukushima.jp taishin.fukushima.jp tamakawa.fukushima.jp tanagura.fukushima.jp tenei.fukushima.jp yabuki.fukushima.jp yamato.fukushima.jp yamatsuri.fukushima.jp yanaizu.fukushima.jp yugawa.fukushima.jp anpachi.gifu.jp ena.gifu.jp gifu.gifu.jp ginan.gifu.jp godo.gifu.jp gujo.gifu.jp hashima.gifu.jp hichiso.gifu.jp hida.gifu.jp higashishirakawa.gifu.jp ibigawa.gifu.jp ikeda.gifu.jp kakamigahara.gifu.jp kani.gifu.jp kasahara.gifu.jp kasamatsu.gifu.jp kawaue.gifu.jp kitagata.gifu.jp mino.gifu.jp minokamo.gifu.jp mitake.gifu.jp mizunami.gifu.jp motosu.gifu.jp nakatsugawa.gifu.jp ogaki.gifu.jp sakahogi.gifu.jp seki.gifu.jp sekigahara.gifu.jp shirakawa.gifu.jp tajimi.gifu.jp takayama.gifu.jp tarui.gifu.jp toki.gifu.jp tomika.gifu.jp wanouchi.gifu.jp yamagata.gifu.jp yaotsu.gifu.jp yoro.gifu.jp annaka.gunma.jp chiyoda.gunma.jp fujioka.gunma.jp higashiagatsuma.gunma.jp isesaki.gunma.jp itakura.gunma.jp kanna.gunma.jp kanra.gunma.jp katashina.gunma.jp kawaba.gunma.jp kiryu.gunma.jp kusatsu.gunma.jp maebashi.gunma.jp meiwa.gunma.jp midori.gunma.jp minakami.gunma.jp naganohara.gunma.jp nakanojo.gunma.jp nanmoku.gunma.jp numata.gunma.jp oizumi.gunma.jp ora.gunma.jp ota.gunma.jp shibukawa.gunma.jp shimonita.gunma.jp shinto.gunma.jp showa.gunma.jp takasaki.gunma.jp takayama.gunma.jp tamamura.gunma.jp tatebayashi.gunma.jp tomioka.gunma.jp tsukiyono.gunma.jp tsumagoi.gunma.jp ueno.gunma.jp yoshioka.gunma.jp asaminami.hiroshima.jp daiwa.hiroshima.jp etajima.hiroshima.jp fuchu.hiroshima.jp fukuyama.hiroshima.jp hatsukaichi.hiroshima.jp higashihiroshima.hiroshima.jp hongo.hiroshima.jp jinsekikogen.hiroshima.jp kaita.hiroshima.jp kui.hiroshima.jp kumano.hiroshima.jp kure.hiroshima.jp mihara.hiroshima.jp miyoshi.hiroshima.jp naka.hiroshima.jp onomichi.hiroshima.jp osakikamijima.hiroshima.jp otake.hiroshima.jp saka.hiroshima.jp sera.hiroshima.jp seranishi.hiroshima.jp shinichi.hiroshima.jp shobara.hiroshima.jp takehara.hiroshima.jp abashiri.hokkaido.jp abira.hokkaido.jp aibetsu.hokkaido.jp akabira.hokkaido.jp akkeshi.hokkaido.jp asahikawa.hokkaido.jp ashibetsu.hokkaido.jp ashoro.hokkaido.jp assabu.hokkaido.jp atsuma.hokkaido.jp bibai.hokkaido.jp biei.hokkaido.jp bifuka.hokkaido.jp bihoro.hokkaido.jp biratori.hokkaido.jp chippubetsu.hokkaido.jp chitose.hokkaido.jp date.hokkaido.jp ebetsu.hokkaido.jp embetsu.hokkaido.jp eniwa.hokkaido.jp erimo.hokkaido.jp esan.hokkaido.jp esashi.hokkaido.jp fukagawa.hokkaido.jp fukushima.hokkaido.jp furano.hokkaido.jp furubira.hokkaido.jp haboro.hokkaido.jp hakodate.hokkaido.jp hamatonbetsu.hokkaido.jp hidaka.hokkaido.jp higashikagura.hokkaido.jp higashikawa.hokkaido.jp hiroo.hokkaido.jp hokuryu.hokkaido.jp hokuto.hokkaido.jp honbetsu.hokkaido.jp horokanai.hokkaido.jp horonobe.hokkaido.jp ikeda.hokkaido.jp imakane.hokkaido.jp ishikari.hokkaido.jp iwamizawa.hokkaido.jp iwanai.hokkaido.jp kamifurano.hokkaido.jp kamikawa.hokkaido.jp kamishihoro.hokkaido.jp kamisunagawa.hokkaido.jp kamoenai.hokkaido.jp kayabe.hokkaido.jp kembuchi.hokkaido.jp kikonai.hokkaido.jp kimobetsu.hokkaido.jp kitahiroshima.hokkaido.jp kitami.hokkaido.jp kiyosato.hokkaido.jp koshimizu.hokkaido.jp kunneppu.hokkaido.jp kuriyama.hokkaido.jp kuromatsunai.hokkaido.jp kushiro.hokkaido.jp kutchan.hokkaido.jp kyowa.hokkaido.jp mashike.hokkaido.jp matsumae.hokkaido.jp mikasa.hokkaido.jp minamifurano.hokkaido.jp mombetsu.hokkaido.jp moseushi.hokkaido.jp mukawa.hokkaido.jp muroran.hokkaido.jp naie.hokkaido.jp nakagawa.hokkaido.jp nakasatsunai.hokkaido.jp nakatombetsu.hokkaido.jp nanae.hokkaido.jp nanporo.hokkaido.jp nayoro.hokkaido.jp nemuro.hokkaido.jp niikappu.hokkaido.jp niki.hokkaido.jp nishiokoppe.hokkaido.jp noboribetsu.hokkaido.jp numata.hokkaido.jp obihiro.hokkaido.jp obira.hokkaido.jp oketo.hokkaido.jp okoppe.hokkaido.jp otaru.hokkaido.jp otobe.hokkaido.jp otofuke.hokkaido.jp otoineppu.hokkaido.jp oumu.hokkaido.jp ozora.hokkaido.jp pippu.hokkaido.jp rankoshi.hokkaido.jp rebun.hokkaido.jp rikubetsu.hokkaido.jp rishiri.hokkaido.jp rishirifuji.hokkaido.jp saroma.hokkaido.jp sarufutsu.hokkaido.jp shakotan.hokkaido.jp shari.hokkaido.jp shibecha.hokkaido.jp shibetsu.hokkaido.jp shikabe.hokkaido.jp shikaoi.hokkaido.jp shimamaki.hokkaido.jp shimizu.hokkaido.jp shimokawa.hokkaido.jp shinshinotsu.hokkaido.jp shintoku.hokkaido.jp shiranuka.hokkaido.jp shiraoi.hokkaido.jp shiriuchi.hokkaido.jp sobetsu.hokkaido.jp sunagawa.hokkaido.jp taiki.hokkaido.jp takasu.hokkaido.jp takikawa.hokkaido.jp takinoue.hokkaido.jp teshikaga.hokkaido.jp tobetsu.hokkaido.jp tohma.hokkaido.jp tomakomai.hokkaido.jp tomari.hokkaido.jp toya.hokkaido.jp toyako.hokkaido.jp toyotomi.hokkaido.jp toyoura.hokkaido.jp tsubetsu.hokkaido.jp tsukigata.hokkaido.jp urakawa.hokkaido.jp urausu.hokkaido.jp uryu.hokkaido.jp utashinai.hokkaido.jp wakkanai.hokkaido.jp wassamu.hokkaido.jp yakumo.hokkaido.jp yoichi.hokkaido.jp aioi.hyogo.jp akashi.hyogo.jp ako.hyogo.jp amagasaki.hyogo.jp aogaki.hyogo.jp asago.hyogo.jp ashiya.hyogo.jp awaji.hyogo.jp fukusaki.hyogo.jp goshiki.hyogo.jp harima.hyogo.jp himeji.hyogo.jp ichikawa.hyogo.jp inagawa.hyogo.jp itami.hyogo.jp kakogawa.hyogo.jp kamigori.hyogo.jp kamikawa.hyogo.jp kasai.hyogo.jp kasuga.hyogo.jp kawanishi.hyogo.jp miki.hyogo.jp minamiawaji.hyogo.jp nishinomiya.hyogo.jp nishiwaki.hyogo.jp ono.hyogo.jp sanda.hyogo.jp sannan.hyogo.jp sasayama.hyogo.jp sayo.hyogo.jp shingu.hyogo.jp shinonsen.hyogo.jp shiso.hyogo.jp sumoto.hyogo.jp taishi.hyogo.jp taka.hyogo.jp takarazuka.hyogo.jp takasago.hyogo.jp takino.hyogo.jp tamba.hyogo.jp tatsuno.hyogo.jp toyooka.hyogo.jp yabu.hyogo.jp yashiro.hyogo.jp yoka.hyogo.jp yokawa.hyogo.jp ami.ibaraki.jp asahi.ibaraki.jp bando.ibaraki.jp chikusei.ibaraki.jp daigo.ibaraki.jp fujishiro.ibaraki.jp hitachi.ibaraki.jp hitachinaka.ibaraki.jp hitachiomiya.ibaraki.jp hitachiota.ibaraki.jp ibaraki.ibaraki.jp ina.ibaraki.jp inashiki.ibaraki.jp itako.ibaraki.jp iwama.ibaraki.jp joso.ibaraki.jp kamisu.ibaraki.jp kasama.ibaraki.jp kashima.ibaraki.jp kasumigaura.ibaraki.jp koga.ibaraki.jp miho.ibaraki.jp mito.ibaraki.jp moriya.ibaraki.jp naka.ibaraki.jp namegata.ibaraki.jp oarai.ibaraki.jp ogawa.ibaraki.jp omitama.ibaraki.jp ryugasaki.ibaraki.jp sakai.ibaraki.jp sakuragawa.ibaraki.jp shimodate.ibaraki.jp shimotsuma.ibaraki.jp shirosato.ibaraki.jp sowa.ibaraki.jp suifu.ibaraki.jp takahagi.ibaraki.jp tamatsukuri.ibaraki.jp tokai.ibaraki.jp tomobe.ibaraki.jp tone.ibaraki.jp toride.ibaraki.jp tsuchiura.ibaraki.jp tsukuba.ibaraki.jp uchihara.ibaraki.jp ushiku.ibaraki.jp yachiyo.ibaraki.jp yamagata.ibaraki.jp yawara.ibaraki.jp yuki.ibaraki.jp anamizu.ishikawa.jp hakui.ishikawa.jp hakusan.ishikawa.jp kaga.ishikawa.jp kahoku.ishikawa.jp kanazawa.ishikawa.jp kawakita.ishikawa.jp komatsu.ishikawa.jp nakanoto.ishikawa.jp nanao.ishikawa.jp nomi.ishikawa.jp nonoichi.ishikawa.jp noto.ishikawa.jp shika.ishikawa.jp suzu.ishikawa.jp tsubata.ishikawa.jp tsurugi.ishikawa.jp uchinada.ishikawa.jp wajima.ishikawa.jp fudai.iwate.jp fujisawa.iwate.jp hanamaki.iwate.jp hiraizumi.iwate.jp hirono.iwate.jp ichinohe.iwate.jp ichinoseki.iwate.jp iwaizumi.iwate.jp iwate.iwate.jp joboji.iwate.jp kamaishi.iwate.jp kanegasaki.iwate.jp karumai.iwate.jp kawai.iwate.jp kitakami.iwate.jp kuji.iwate.jp kunohe.iwate.jp kuzumaki.iwate.jp miyako.iwate.jp mizusawa.iwate.jp morioka.iwate.jp ninohe.iwate.jp noda.iwate.jp ofunato.iwate.jp oshu.iwate.jp otsuchi.iwate.jp rikuzentakata.iwate.jp shiwa.iwate.jp shizukuishi.iwate.jp sumita.iwate.jp tanohata.iwate.jp tono.iwate.jp yahaba.iwate.jp yamada.iwate.jp ayagawa.kagawa.jp higashikagawa.kagawa.jp kanonji.kagawa.jp kotohira.kagawa.jp manno.kagawa.jp marugame.kagawa.jp mitoyo.kagawa.jp naoshima.kagawa.jp sanuki.kagawa.jp tadotsu.kagawa.jp takamatsu.kagawa.jp tonosho.kagawa.jp uchinomi.kagawa.jp utazu.kagawa.jp zentsuji.kagawa.jp akune.kagoshima.jp amami.kagoshima.jp hioki.kagoshima.jp isa.kagoshima.jp isen.kagoshima.jp izumi.kagoshima.jp kagoshima.kagoshima.jp kanoya.kagoshima.jp kawanabe.kagoshima.jp kinko.kagoshima.jp kouyama.kagoshima.jp makurazaki.kagoshima.jp matsumoto.kagoshima.jp minamitane.kagoshima.jp nakatane.kagoshima.jp nishinoomote.kagoshima.jp satsumasendai.kagoshima.jp soo.kagoshima.jp tarumizu.kagoshima.jp yusui.kagoshima.jp aikawa.kanagawa.jp atsugi.kanagawa.jp ayase.kanagawa.jp chigasaki.kanagawa.jp ebina.kanagawa.jp fujisawa.kanagawa.jp hadano.kanagawa.jp hakone.kanagawa.jp hiratsuka.kanagawa.jp isehara.kanagawa.jp kaisei.kanagawa.jp kamakura.kanagawa.jp kiyokawa.kanagawa.jp matsuda.kanagawa.jp minamiashigara.kanagawa.jp miura.kanagawa.jp nakai.kanagawa.jp ninomiya.kanagawa.jp odawara.kanagawa.jp oi.kanagawa.jp oiso.kanagawa.jp sagamihara.kanagawa.jp samukawa.kanagawa.jp tsukui.kanagawa.jp yamakita.kanagawa.jp yamato.kanagawa.jp yokosuka.kanagawa.jp yugawara.kanagawa.jp zama.kanagawa.jp zushi.kanagawa.jp aki.kochi.jp geisei.kochi.jp hidaka.kochi.jp higashitsuno.kochi.jp ino.kochi.jp kagami.kochi.jp kami.kochi.jp kitagawa.kochi.jp kochi.kochi.jp mihara.kochi.jp motoyama.kochi.jp muroto.kochi.jp nahari.kochi.jp nakamura.kochi.jp nankoku.kochi.jp nishitosa.kochi.jp niyodogawa.kochi.jp ochi.kochi.jp okawa.kochi.jp otoyo.kochi.jp otsuki.kochi.jp sakawa.kochi.jp sukumo.kochi.jp susaki.kochi.jp tosa.kochi.jp tosashimizu.kochi.jp toyo.kochi.jp tsuno.kochi.jp umaji.kochi.jp yasuda.kochi.jp yusuhara.kochi.jp amakusa.kumamoto.jp arao.kumamoto.jp aso.kumamoto.jp choyo.kumamoto.jp gyokuto.kumamoto.jp kamiamakusa.kumamoto.jp kikuchi.kumamoto.jp kumamoto.kumamoto.jp mashiki.kumamoto.jp mifune.kumamoto.jp minamata.kumamoto.jp minamioguni.kumamoto.jp nagasu.kumamoto.jp nishihara.kumamoto.jp oguni.kumamoto.jp ozu.kumamoto.jp sumoto.kumamoto.jp takamori.kumamoto.jp uki.kumamoto.jp uto.kumamoto.jp yamaga.kumamoto.jp yamato.kumamoto.jp yatsushiro.kumamoto.jp ayabe.kyoto.jp fukuchiyama.kyoto.jp higashiyama.kyoto.jp ide.kyoto.jp ine.kyoto.jp joyo.kyoto.jp kameoka.kyoto.jp kamo.kyoto.jp kita.kyoto.jp kizu.kyoto.jp kumiyama.kyoto.jp kyotamba.kyoto.jp kyotanabe.kyoto.jp kyotango.kyoto.jp maizuru.kyoto.jp minami.kyoto.jp minamiyamashiro.kyoto.jp miyazu.kyoto.jp muko.kyoto.jp nagaokakyo.kyoto.jp nakagyo.kyoto.jp nantan.kyoto.jp oyamazaki.kyoto.jp sakyo.kyoto.jp seika.kyoto.jp tanabe.kyoto.jp uji.kyoto.jp ujitawara.kyoto.jp wazuka.kyoto.jp yamashina.kyoto.jp yawata.kyoto.jp asahi.mie.jp inabe.mie.jp ise.mie.jp kameyama.mie.jp kawagoe.mie.jp kiho.mie.jp kisosaki.mie.jp kiwa.mie.jp komono.mie.jp kumano.mie.jp kuwana.mie.jp matsusaka.mie.jp meiwa.mie.jp mihama.mie.jp minamiise.mie.jp misugi.mie.jp miyama.mie.jp nabari.mie.jp shima.mie.jp suzuka.mie.jp tado.mie.jp taiki.mie.jp taki.mie.jp tamaki.mie.jp toba.mie.jp tsu.mie.jp udono.mie.jp ureshino.mie.jp watarai.mie.jp yokkaichi.mie.jp furukawa.miyagi.jp higashimatsushima.miyagi.jp ishinomaki.miyagi.jp iwanuma.miyagi.jp kakuda.miyagi.jp kami.miyagi.jp kawasaki.miyagi.jp marumori.miyagi.jp matsushima.miyagi.jp minamisanriku.miyagi.jp misato.miyagi.jp murata.miyagi.jp natori.miyagi.jp ogawara.miyagi.jp ohira.miyagi.jp onagawa.miyagi.jp osaki.miyagi.jp rifu.miyagi.jp semine.miyagi.jp shibata.miyagi.jp shichikashuku.miyagi.jp shikama.miyagi.jp shiogama.miyagi.jp shiroishi.miyagi.jp tagajo.miyagi.jp taiwa.miyagi.jp tome.miyagi.jp tomiya.miyagi.jp wakuya.miyagi.jp watari.miyagi.jp yamamoto.miyagi.jp zao.miyagi.jp aya.miyazaki.jp ebino.miyazaki.jp gokase.miyazaki.jp hyuga.miyazaki.jp kadogawa.miyazaki.jp kawaminami.miyazaki.jp kijo.miyazaki.jp kitagawa.miyazaki.jp kitakata.miyazaki.jp kitaura.miyazaki.jp kobayashi.miyazaki.jp kunitomi.miyazaki.jp kushima.miyazaki.jp mimata.miyazaki.jp miyakonojo.miyazaki.jp miyazaki.miyazaki.jp morotsuka.miyazaki.jp nichinan.miyazaki.jp nishimera.miyazaki.jp nobeoka.miyazaki.jp saito.miyazaki.jp shiiba.miyazaki.jp shintomi.miyazaki.jp takaharu.miyazaki.jp takanabe.miyazaki.jp takazaki.miyazaki.jp tsuno.miyazaki.jp achi.nagano.jp agematsu.nagano.jp anan.nagano.jp aoki.nagano.jp asahi.nagano.jp azumino.nagano.jp chikuhoku.nagano.jp chikuma.nagano.jp chino.nagano.jp fujimi.nagano.jp hakuba.nagano.jp hara.nagano.jp hiraya.nagano.jp iida.nagano.jp iijima.nagano.jp iiyama.nagano.jp iizuna.nagano.jp ikeda.nagano.jp ikusaka.nagano.jp ina.nagano.jp karuizawa.nagano.jp kawakami.nagano.jp kiso.nagano.jp kisofukushima.nagano.jp kitaaiki.nagano.jp komagane.nagano.jp komoro.nagano.jp matsukawa.nagano.jp matsumoto.nagano.jp miasa.nagano.jp minamiaiki.nagano.jp minamimaki.nagano.jp minamiminowa.nagano.jp minowa.nagano.jp miyada.nagano.jp miyota.nagano.jp mochizuki.nagano.jp nagano.nagano.jp nagawa.nagano.jp nagiso.nagano.jp nakagawa.nagano.jp nakano.nagano.jp nozawaonsen.nagano.jp obuse.nagano.jp ogawa.nagano.jp okaya.nagano.jp omachi.nagano.jp omi.nagano.jp ookuwa.nagano.jp ooshika.nagano.jp otaki.nagano.jp otari.nagano.jp sakae.nagano.jp sakaki.nagano.jp saku.nagano.jp sakuho.nagano.jp shimosuwa.nagano.jp shinanomachi.nagano.jp shiojiri.nagano.jp suwa.nagano.jp suzaka.nagano.jp takagi.nagano.jp takamori.nagano.jp takayama.nagano.jp tateshina.nagano.jp tatsuno.nagano.jp togakushi.nagano.jp togura.nagano.jp tomi.nagano.jp ueda.nagano.jp wada.nagano.jp yamagata.nagano.jp yamanouchi.nagano.jp yasaka.nagano.jp yasuoka.nagano.jp chijiwa.nagasaki.jp futsu.nagasaki.jp goto.nagasaki.jp hasami.nagasaki.jp hirado.nagasaki.jp iki.nagasaki.jp isahaya.nagasaki.jp kawatana.nagasaki.jp kuchinotsu.nagasaki.jp matsuura.nagasaki.jp nagasaki.nagasaki.jp obama.nagasaki.jp omura.nagasaki.jp oseto.nagasaki.jp saikai.nagasaki.jp sasebo.nagasaki.jp seihi.nagasaki.jp shimabara.nagasaki.jp shinkamigoto.nagasaki.jp togitsu.nagasaki.jp tsushima.nagasaki.jp unzen.nagasaki.jp ando.nara.jp gose.nara.jp heguri.nara.jp higashiyoshino.nara.jp ikaruga.nara.jp ikoma.nara.jp kamikitayama.nara.jp kanmaki.nara.jp kashiba.nara.jp kashihara.nara.jp katsuragi.nara.jp kawai.nara.jp kawakami.nara.jp kawanishi.nara.jp koryo.nara.jp kurotaki.nara.jp mitsue.nara.jp miyake.nara.jp nara.nara.jp nosegawa.nara.jp oji.nara.jp ouda.nara.jp oyodo.nara.jp sakurai.nara.jp sango.nara.jp shimoichi.nara.jp shimokitayama.nara.jp shinjo.nara.jp soni.nara.jp takatori.nara.jp tawaramoto.nara.jp tenkawa.nara.jp tenri.nara.jp uda.nara.jp yamatokoriyama.nara.jp yamatotakada.nara.jp yamazoe.nara.jp yoshino.nara.jp aga.niigata.jp agano.niigata.jp gosen.niigata.jp itoigawa.niigata.jp izumozaki.niigata.jp joetsu.niigata.jp kamo.niigata.jp kariwa.niigata.jp kashiwazaki.niigata.jp minamiuonuma.niigata.jp mitsuke.niigata.jp muika.niigata.jp murakami.niigata.jp myoko.niigata.jp nagaoka.niigata.jp niigata.niigata.jp ojiya.niigata.jp omi.niigata.jp sado.niigata.jp sanjo.niigata.jp seiro.niigata.jp seirou.niigata.jp sekikawa.niigata.jp shibata.niigata.jp tagami.niigata.jp tainai.niigata.jp tochio.niigata.jp tokamachi.niigata.jp tsubame.niigata.jp tsunan.niigata.jp uonuma.niigata.jp yahiko.niigata.jp yoita.niigata.jp yuzawa.niigata.jp beppu.oita.jp bungoono.oita.jp bungotakada.oita.jp hasama.oita.jp hiji.oita.jp himeshima.oita.jp hita.oita.jp kamitsue.oita.jp kokonoe.oita.jp kuju.oita.jp kunisaki.oita.jp kusu.oita.jp oita.oita.jp saiki.oita.jp taketa.oita.jp tsukumi.oita.jp usa.oita.jp usuki.oita.jp yufu.oita.jp akaiwa.okayama.jp asakuchi.okayama.jp bizen.okayama.jp hayashima.okayama.jp ibara.okayama.jp kagamino.okayama.jp kasaoka.okayama.jp kibichuo.okayama.jp kumenan.okayama.jp kurashiki.okayama.jp maniwa.okayama.jp misaki.okayama.jp nagi.okayama.jp niimi.okayama.jp nishiawakura.okayama.jp okayama.okayama.jp satosho.okayama.jp setouchi.okayama.jp shinjo.okayama.jp shoo.okayama.jp soja.okayama.jp takahashi.okayama.jp tamano.okayama.jp tsuyama.okayama.jp wake.okayama.jp yakage.okayama.jp aguni.okinawa.jp ginowan.okinawa.jp ginoza.okinawa.jp gushikami.okinawa.jp haebaru.okinawa.jp higashi.okinawa.jp hirara.okinawa.jp iheya.okinawa.jp ishigaki.okinawa.jp ishikawa.okinawa.jp itoman.okinawa.jp izena.okinawa.jp kadena.okinawa.jp kin.okinawa.jp kitadaito.okinawa.jp kitanakagusuku.okinawa.jp kumejima.okinawa.jp kunigami.okinawa.jp minamidaito.okinawa.jp motobu.okinawa.jp nago.okinawa.jp naha.okinawa.jp nakagusuku.okinawa.jp nakijin.okinawa.jp nanjo.okinawa.jp nishihara.okinawa.jp ogimi.okinawa.jp okinawa.okinawa.jp onna.okinawa.jp shimoji.okinawa.jp taketomi.okinawa.jp tarama.okinawa.jp tokashiki.okinawa.jp tomigusuku.okinawa.jp tonaki.okinawa.jp urasoe.okinawa.jp uruma.okinawa.jp yaese.okinawa.jp yomitan.okinawa.jp yonabaru.okinawa.jp yonaguni.okinawa.jp zamami.okinawa.jp abeno.osaka.jp chihayaakasaka.osaka.jp chuo.osaka.jp daito.osaka.jp fujiidera.osaka.jp habikino.osaka.jp hannan.osaka.jp higashiosaka.osaka.jp higashisumiyoshi.osaka.jp higashiyodogawa.osaka.jp hirakata.osaka.jp ibaraki.osaka.jp ikeda.osaka.jp izumi.osaka.jp izumiotsu.osaka.jp izumisano.osaka.jp kadoma.osaka.jp kaizuka.osaka.jp kanan.osaka.jp kashiwara.osaka.jp katano.osaka.jp kawachinagano.osaka.jp kishiwada.osaka.jp kita.osaka.jp kumatori.osaka.jp matsubara.osaka.jp minato.osaka.jp minoh.osaka.jp misaki.osaka.jp moriguchi.osaka.jp neyagawa.osaka.jp nishi.osaka.jp nose.osaka.jp osakasayama.osaka.jp sakai.osaka.jp sayama.osaka.jp sennan.osaka.jp settsu.osaka.jp shijonawate.osaka.jp shimamoto.osaka.jp suita.osaka.jp tadaoka.osaka.jp taishi.osaka.jp tajiri.osaka.jp takaishi.osaka.jp takatsuki.osaka.jp tondabayashi.osaka.jp toyonaka.osaka.jp toyono.osaka.jp yao.osaka.jp ariake.saga.jp arita.saga.jp fukudomi.saga.jp genkai.saga.jp hamatama.saga.jp hizen.saga.jp imari.saga.jp kamimine.saga.jp kanzaki.saga.jp karatsu.saga.jp kashima.saga.jp kitagata.saga.jp kitahata.saga.jp kiyama.saga.jp kouhoku.saga.jp kyuragi.saga.jp nishiarita.saga.jp ogi.saga.jp omachi.saga.jp ouchi.saga.jp saga.saga.jp shiroishi.saga.jp taku.saga.jp tara.saga.jp tosu.saga.jp yoshinogari.saga.jp arakawa.saitama.jp asaka.saitama.jp chichibu.saitama.jp fujimi.saitama.jp fujimino.saitama.jp fukaya.saitama.jp hanno.saitama.jp hanyu.saitama.jp hasuda.saitama.jp hatogaya.saitama.jp hatoyama.saitama.jp hidaka.saitama.jp higashichichibu.saitama.jp higashimatsuyama.saitama.jp honjo.saitama.jp ina.saitama.jp iruma.saitama.jp iwatsuki.saitama.jp kamiizumi.saitama.jp kamikawa.saitama.jp kamisato.saitama.jp kasukabe.saitama.jp kawagoe.saitama.jp kawaguchi.saitama.jp kawajima.saitama.jp kazo.saitama.jp kitamoto.saitama.jp koshigaya.saitama.jp kounosu.saitama.jp kuki.saitama.jp kumagaya.saitama.jp matsubushi.saitama.jp minano.saitama.jp misato.saitama.jp miyashiro.saitama.jp miyoshi.saitama.jp moroyama.saitama.jp nagatoro.saitama.jp namegawa.saitama.jp niiza.saitama.jp ogano.saitama.jp ogawa.saitama.jp ogose.saitama.jp okegawa.saitama.jp omiya.saitama.jp otaki.saitama.jp ranzan.saitama.jp ryokami.saitama.jp saitama.saitama.jp sakado.saitama.jp satte.saitama.jp sayama.saitama.jp shiki.saitama.jp shiraoka.saitama.jp soka.saitama.jp sugito.saitama.jp toda.saitama.jp tokigawa.saitama.jp tokorozawa.saitama.jp tsurugashima.saitama.jp urawa.saitama.jp warabi.saitama.jp yashio.saitama.jp yokoze.saitama.jp yono.saitama.jp yorii.saitama.jp yoshida.saitama.jp yoshikawa.saitama.jp yoshimi.saitama.jp aisho.shiga.jp gamo.shiga.jp higashiomi.shiga.jp hikone.shiga.jp koka.shiga.jp konan.shiga.jp kosei.shiga.jp koto.shiga.jp kusatsu.shiga.jp maibara.shiga.jp moriyama.shiga.jp nagahama.shiga.jp nishiazai.shiga.jp notogawa.shiga.jp omihachiman.shiga.jp otsu.shiga.jp ritto.shiga.jp ryuoh.shiga.jp takashima.shiga.jp takatsuki.shiga.jp torahime.shiga.jp toyosato.shiga.jp yasu.shiga.jp akagi.shimane.jp ama.shimane.jp gotsu.shimane.jp hamada.shimane.jp higashiizumo.shimane.jp hikawa.shimane.jp hikimi.shimane.jp izumo.shimane.jp kakinoki.shimane.jp masuda.shimane.jp matsue.shimane.jp misato.shimane.jp nishinoshima.shimane.jp ohda.shimane.jp okinoshima.shimane.jp okuizumo.shimane.jp shimane.shimane.jp tamayu.shimane.jp tsuwano.shimane.jp unnan.shimane.jp yakumo.shimane.jp yasugi.shimane.jp yatsuka.shimane.jp arai.shizuoka.jp atami.shizuoka.jp fuji.shizuoka.jp fujieda.shizuoka.jp fujikawa.shizuoka.jp fujinomiya.shizuoka.jp fukuroi.shizuoka.jp gotemba.shizuoka.jp haibara.shizuoka.jp hamamatsu.shizuoka.jp higashiizu.shizuoka.jp ito.shizuoka.jp iwata.shizuoka.jp izu.shizuoka.jp izunokuni.shizuoka.jp kakegawa.shizuoka.jp kannami.shizuoka.jp kawanehon.shizuoka.jp kawazu.shizuoka.jp kikugawa.shizuoka.jp kosai.shizuoka.jp makinohara.shizuoka.jp matsuzaki.shizuoka.jp minamiizu.shizuoka.jp mishima.shizuoka.jp morimachi.shizuoka.jp nishiizu.shizuoka.jp numazu.shizuoka.jp omaezaki.shizuoka.jp shimada.shizuoka.jp shimizu.shizuoka.jp shimoda.shizuoka.jp shizuoka.shizuoka.jp susono.shizuoka.jp yaizu.shizuoka.jp yoshida.shizuoka.jp ashikaga.tochigi.jp bato.tochigi.jp haga.tochigi.jp ichikai.tochigi.jp iwafune.tochigi.jp kaminokawa.tochigi.jp kanuma.tochigi.jp karasuyama.tochigi.jp kuroiso.tochigi.jp mashiko.tochigi.jp mibu.tochigi.jp moka.tochigi.jp motegi.tochigi.jp nasu.tochigi.jp nasushiobara.tochigi.jp nikko.tochigi.jp nishikata.tochigi.jp nogi.tochigi.jp ohira.tochigi.jp ohtawara.tochigi.jp oyama.tochigi.jp sakura.tochigi.jp sano.tochigi.jp shimotsuke.tochigi.jp shioya.tochigi.jp takanezawa.tochigi.jp tochigi.tochigi.jp tsuga.tochigi.jp ujiie.tochigi.jp utsunomiya.tochigi.jp yaita.tochigi.jp aizumi.tokushima.jp anan.tokushima.jp ichiba.tokushima.jp itano.tokushima.jp kainan.tokushima.jp komatsushima.tokushima.jp matsushige.tokushima.jp mima.tokushima.jp minami.tokushima.jp miyoshi.tokushima.jp mugi.tokushima.jp nakagawa.tokushima.jp naruto.tokushima.jp sanagochi.tokushima.jp shishikui.tokushima.jp tokushima.tokushima.jp wajiki.tokushima.jp adachi.tokyo.jp akiruno.tokyo.jp akishima.tokyo.jp aogashima.tokyo.jp arakawa.tokyo.jp bunkyo.tokyo.jp chiyoda.tokyo.jp chofu.tokyo.jp chuo.tokyo.jp edogawa.tokyo.jp fuchu.tokyo.jp fussa.tokyo.jp hachijo.tokyo.jp hachioji.tokyo.jp hamura.tokyo.jp higashikurume.tokyo.jp higashimurayama.tokyo.jp higashiyamato.tokyo.jp hino.tokyo.jp hinode.tokyo.jp hinohara.tokyo.jp inagi.tokyo.jp itabashi.tokyo.jp katsushika.tokyo.jp kita.tokyo.jp kiyose.tokyo.jp kodaira.tokyo.jp koganei.tokyo.jp kokubunji.tokyo.jp komae.tokyo.jp koto.tokyo.jp kouzushima.tokyo.jp kunitachi.tokyo.jp machida.tokyo.jp meguro.tokyo.jp minato.tokyo.jp mitaka.tokyo.jp mizuho.tokyo.jp musashimurayama.tokyo.jp musashino.tokyo.jp nakano.tokyo.jp nerima.tokyo.jp ogasawara.tokyo.jp okutama.tokyo.jp ome.tokyo.jp oshima.tokyo.jp ota.tokyo.jp setagaya.tokyo.jp shibuya.tokyo.jp shinagawa.tokyo.jp shinjuku.tokyo.jp suginami.tokyo.jp sumida.tokyo.jp tachikawa.tokyo.jp taito.tokyo.jp tama.tokyo.jp toshima.tokyo.jp chizu.tottori.jp hino.tottori.jp kawahara.tottori.jp koge.tottori.jp kotoura.tottori.jp misasa.tottori.jp nanbu.tottori.jp nichinan.tottori.jp sakaiminato.tottori.jp tottori.tottori.jp wakasa.tottori.jp yazu.tottori.jp yonago.tottori.jp asahi.toyama.jp fuchu.toyama.jp fukumitsu.toyama.jp funahashi.toyama.jp himi.toyama.jp imizu.toyama.jp inami.toyama.jp johana.toyama.jp kamiichi.toyama.jp kurobe.toyama.jp nakaniikawa.toyama.jp namerikawa.toyama.jp nanto.toyama.jp nyuzen.toyama.jp oyabe.toyama.jp taira.toyama.jp takaoka.toyama.jp tateyama.toyama.jp toga.toyama.jp tonami.toyama.jp toyama.toyama.jp unazuki.toyama.jp uozu.toyama.jp yamada.toyama.jp arida.wakayama.jp aridagawa.wakayama.jp gobo.wakayama.jp hashimoto.wakayama.jp hidaka.wakayama.jp hirogawa.wakayama.jp inami.wakayama.jp iwade.wakayama.jp kainan.wakayama.jp kamitonda.wakayama.jp katsuragi.wakayama.jp kimino.wakayama.jp kinokawa.wakayama.jp kitayama.wakayama.jp koya.wakayama.jp koza.wakayama.jp kozagawa.wakayama.jp kudoyama.wakayama.jp kushimoto.wakayama.jp mihama.wakayama.jp misato.wakayama.jp nachikatsuura.wakayama.jp shingu.wakayama.jp shirahama.wakayama.jp taiji.wakayama.jp tanabe.wakayama.jp wakayama.wakayama.jp yuasa.wakayama.jp yura.wakayama.jp asahi.yamagata.jp funagata.yamagata.jp higashine.yamagata.jp iide.yamagata.jp kahoku.yamagata.jp kaminoyama.yamagata.jp kaneyama.yamagata.jp kawanishi.yamagata.jp mamurogawa.yamagata.jp mikawa.yamagata.jp murayama.yamagata.jp nagai.yamagata.jp nakayama.yamagata.jp nanyo.yamagata.jp nishikawa.yamagata.jp obanazawa.yamagata.jp oe.yamagata.jp oguni.yamagata.jp ohkura.yamagata.jp oishida.yamagata.jp sagae.yamagata.jp sakata.yamagata.jp sakegawa.yamagata.jp shinjo.yamagata.jp shirataka.yamagata.jp shonai.yamagata.jp takahata.yamagata.jp tendo.yamagata.jp tozawa.yamagata.jp tsuruoka.yamagata.jp yamagata.yamagata.jp yamanobe.yamagata.jp yonezawa.yamagata.jp yuza.yamagata.jp abu.yamaguchi.jp hagi.yamaguchi.jp hikari.yamaguchi.jp hofu.yamaguchi.jp iwakuni.yamaguchi.jp kudamatsu.yamaguchi.jp mitou.yamaguchi.jp nagato.yamaguchi.jp oshima.yamaguchi.jp shimonoseki.yamaguchi.jp shunan.yamaguchi.jp tabuse.yamaguchi.jp tokuyama.yamaguchi.jp toyota.yamaguchi.jp ube.yamaguchi.jp yuu.yamaguchi.jp chuo.yamanashi.jp doshi.yamanashi.jp fuefuki.yamanashi.jp fujikawa.yamanashi.jp fujikawaguchiko.yamanashi.jp fujiyoshida.yamanashi.jp hayakawa.yamanashi.jp hokuto.yamanashi.jp ichikawamisato.yamanashi.jp kai.yamanashi.jp kofu.yamanashi.jp koshu.yamanashi.jp kosuge.yamanashi.jp minami-alps.yamanashi.jp minobu.yamanashi.jp nakamichi.yamanashi.jp nanbu.yamanashi.jp narusawa.yamanashi.jp nirasaki.yamanashi.jp nishikatsura.yamanashi.jp oshino.yamanashi.jp otsuki.yamanashi.jp showa.yamanashi.jp tabayama.yamanashi.jp tsuru.yamanashi.jp uenohara.yamanashi.jp yamanakako.yamanashi.jp yamanashi.yamanashi.jp // ke : http://www.kenic.or.ke/index.php/en/ke-domains/ke-domains ke ac.ke co.ke go.ke info.ke me.ke mobi.ke ne.ke or.ke sc.ke // kg : http://www.domain.kg/dmn_n.html kg org.kg net.kg com.kg edu.kg gov.kg mil.kg // kh : http://www.mptc.gov.kh/dns_registration.htm *.kh // ki : http://www.ki/dns/index.html ki edu.ki biz.ki net.ki org.ki gov.ki info.ki com.ki // km : https://en.wikipedia.org/wiki/.km // http://www.domaine.km/documents/charte.doc km org.km nom.km gov.km prd.km tm.km edu.km mil.km ass.km com.km // These are only mentioned as proposed suggestions at domaine.km, but // https://en.wikipedia.org/wiki/.km says they're available for registration: coop.km asso.km presse.km medecin.km notaires.km pharmaciens.km veterinaire.km gouv.km // kn : https://en.wikipedia.org/wiki/.kn // http://www.dot.kn/domainRules.html kn net.kn org.kn edu.kn gov.kn // kp : http://www.kcce.kp/en_index.php kp com.kp edu.kp gov.kp org.kp rep.kp tra.kp // kr : https://en.wikipedia.org/wiki/.kr // see also: http://domain.nida.or.kr/eng/registration.jsp kr ac.kr co.kr es.kr go.kr hs.kr kg.kr mil.kr ms.kr ne.kr or.kr pe.kr re.kr sc.kr // kr geographical names busan.kr chungbuk.kr chungnam.kr daegu.kr daejeon.kr gangwon.kr gwangju.kr gyeongbuk.kr gyeonggi.kr gyeongnam.kr incheon.kr jeju.kr jeonbuk.kr jeonnam.kr seoul.kr ulsan.kr // kw : https://www.nic.kw/policies/ // Confirmed by registry kw com.kw edu.kw emb.kw gov.kw ind.kw net.kw org.kw // ky : http://www.icta.ky/da_ky_reg_dom.php // Confirmed by registry 2008-06-17 ky edu.ky gov.ky com.ky org.ky net.ky // kz : https://en.wikipedia.org/wiki/.kz // see also: http://www.nic.kz/rules/index.jsp kz org.kz edu.kz net.kz gov.kz mil.kz com.kz // la : https://en.wikipedia.org/wiki/.la // Submitted by registry la int.la net.la info.la edu.la gov.la per.la com.la org.la // lb : https://en.wikipedia.org/wiki/.lb // Submitted by registry lb com.lb edu.lb gov.lb net.lb org.lb // lc : https://en.wikipedia.org/wiki/.lc // see also: http://www.nic.lc/rules.htm lc com.lc net.lc co.lc org.lc edu.lc gov.lc // li : https://en.wikipedia.org/wiki/.li li // lk : http://www.nic.lk/seclevpr.html lk gov.lk sch.lk net.lk int.lk com.lk org.lk edu.lk ngo.lk soc.lk web.lk ltd.lk assn.lk grp.lk hotel.lk ac.lk // lr : http://psg.com/dns/lr/lr.txt // Submitted by registry lr com.lr edu.lr gov.lr org.lr net.lr // ls : http://www.nic.ls/ // Confirmed by registry ls ac.ls biz.ls co.ls edu.ls gov.ls info.ls net.ls org.ls sc.ls // lt : https://en.wikipedia.org/wiki/.lt lt // gov.lt : http://www.gov.lt/index_en.php gov.lt // lu : http://www.dns.lu/en/ lu // lv : http://www.nic.lv/DNS/En/generic.php lv com.lv edu.lv gov.lv org.lv mil.lv id.lv net.lv asn.lv conf.lv // ly : http://www.nic.ly/regulations.php ly com.ly net.ly gov.ly plc.ly edu.ly sch.ly med.ly org.ly id.ly // ma : https://en.wikipedia.org/wiki/.ma // http://www.anrt.ma/fr/admin/download/upload/file_fr782.pdf ma co.ma net.ma gov.ma org.ma ac.ma press.ma // mc : http://www.nic.mc/ mc tm.mc asso.mc // md : https://en.wikipedia.org/wiki/.md md // me : https://en.wikipedia.org/wiki/.me me co.me net.me org.me edu.me ac.me gov.me its.me priv.me // mg : http://nic.mg/nicmg/?page_id=39 mg org.mg nom.mg gov.mg prd.mg tm.mg edu.mg mil.mg com.mg co.mg // mh : https://en.wikipedia.org/wiki/.mh mh // mil : https://en.wikipedia.org/wiki/.mil mil // mk : https://en.wikipedia.org/wiki/.mk // see also: http://dns.marnet.net.mk/postapka.php mk com.mk org.mk net.mk edu.mk gov.mk inf.mk name.mk // ml : http://www.gobin.info/domainname/ml-template.doc // see also: https://en.wikipedia.org/wiki/.ml ml com.ml edu.ml gouv.ml gov.ml net.ml org.ml presse.ml // mm : https://en.wikipedia.org/wiki/.mm *.mm // mn : https://en.wikipedia.org/wiki/.mn mn gov.mn edu.mn org.mn // mo : http://www.monic.net.mo/ mo com.mo net.mo org.mo edu.mo gov.mo // mobi : https://en.wikipedia.org/wiki/.mobi mobi // mp : http://www.dot.mp/ // Confirmed by registry 2008-06-17 mp // mq : https://en.wikipedia.org/wiki/.mq mq // mr : https://en.wikipedia.org/wiki/.mr mr gov.mr // ms : http://www.nic.ms/pdf/MS_Domain_Name_Rules.pdf ms com.ms edu.ms gov.ms net.ms org.ms // mt : https://www.nic.org.mt/go/policy // Submitted by registry mt com.mt edu.mt net.mt org.mt // mu : https://en.wikipedia.org/wiki/.mu mu com.mu net.mu org.mu gov.mu ac.mu co.mu or.mu // museum : http://about.museum/naming/ // http://index.museum/ museum academy.museum agriculture.museum air.museum airguard.museum alabama.museum alaska.museum amber.museum ambulance.museum american.museum americana.museum americanantiques.museum americanart.museum amsterdam.museum and.museum annefrank.museum anthro.museum anthropology.museum antiques.museum aquarium.museum arboretum.museum archaeological.museum archaeology.museum architecture.museum art.museum artanddesign.museum artcenter.museum artdeco.museum arteducation.museum artgallery.museum arts.museum artsandcrafts.museum asmatart.museum assassination.museum assisi.museum association.museum astronomy.museum atlanta.museum austin.museum australia.museum automotive.museum aviation.museum axis.museum badajoz.museum baghdad.museum bahn.museum bale.museum baltimore.museum barcelona.museum baseball.museum basel.museum baths.museum bauern.museum beauxarts.museum beeldengeluid.museum bellevue.museum bergbau.museum berkeley.museum berlin.museum bern.museum bible.museum bilbao.museum bill.museum birdart.museum birthplace.museum bonn.museum boston.museum botanical.museum botanicalgarden.museum botanicgarden.museum botany.museum brandywinevalley.museum brasil.museum bristol.museum british.museum britishcolumbia.museum broadcast.museum brunel.museum brussel.museum brussels.museum bruxelles.museum building.museum burghof.museum bus.museum bushey.museum cadaques.museum california.museum cambridge.museum can.museum canada.museum capebreton.museum carrier.museum cartoonart.museum casadelamoneda.museum castle.museum castres.museum celtic.museum center.museum chattanooga.museum cheltenham.museum chesapeakebay.museum chicago.museum children.museum childrens.museum childrensgarden.museum chiropractic.museum chocolate.museum christiansburg.museum cincinnati.museum cinema.museum circus.museum civilisation.museum civilization.museum civilwar.museum clinton.museum clock.museum coal.museum coastaldefence.museum cody.museum coldwar.museum collection.museum colonialwilliamsburg.museum coloradoplateau.museum columbia.museum columbus.museum communication.museum communications.museum community.museum computer.museum computerhistory.museum xn--comunicaes-v6a2o.museum contemporary.museum contemporaryart.museum convent.museum copenhagen.museum corporation.museum xn--correios-e-telecomunicaes-ghc29a.museum corvette.museum costume.museum countryestate.museum county.museum crafts.museum cranbrook.museum creation.museum cultural.museum culturalcenter.museum culture.museum cyber.museum cymru.museum dali.museum dallas.museum database.museum ddr.museum decorativearts.museum delaware.museum delmenhorst.museum denmark.museum depot.museum design.museum detroit.museum dinosaur.museum discovery.museum dolls.museum donostia.museum durham.museum eastafrica.museum eastcoast.museum education.museum educational.museum egyptian.museum eisenbahn.museum elburg.museum elvendrell.museum embroidery.museum encyclopedic.museum england.museum entomology.museum environment.museum environmentalconservation.museum epilepsy.museum essex.museum estate.museum ethnology.museum exeter.museum exhibition.museum family.museum farm.museum farmequipment.museum farmers.museum farmstead.museum field.museum figueres.museum filatelia.museum film.museum fineart.museum finearts.museum finland.museum flanders.museum florida.museum force.museum fortmissoula.museum fortworth.museum foundation.museum francaise.museum frankfurt.museum franziskaner.museum freemasonry.museum freiburg.museum fribourg.museum frog.museum fundacio.museum furniture.museum gallery.museum garden.museum gateway.museum geelvinck.museum gemological.museum geology.museum georgia.museum giessen.museum glas.museum glass.museum gorge.museum grandrapids.museum graz.museum guernsey.museum halloffame.museum hamburg.museum handson.museum harvestcelebration.museum hawaii.museum health.museum heimatunduhren.museum hellas.museum helsinki.museum hembygdsforbund.museum heritage.museum histoire.museum historical.museum historicalsociety.museum historichouses.museum historisch.museum historisches.museum history.museum historyofscience.museum horology.museum house.museum humanities.museum illustration.museum imageandsound.museum indian.museum indiana.museum indianapolis.museum indianmarket.museum intelligence.museum interactive.museum iraq.museum iron.museum isleofman.museum jamison.museum jefferson.museum jerusalem.museum jewelry.museum jewish.museum jewishart.museum jfk.museum journalism.museum judaica.museum judygarland.museum juedisches.museum juif.museum karate.museum karikatur.museum kids.museum koebenhavn.museum koeln.museum kunst.museum kunstsammlung.museum kunstunddesign.museum labor.museum labour.museum lajolla.museum lancashire.museum landes.museum lans.museum xn--lns-qla.museum larsson.museum lewismiller.museum lincoln.museum linz.museum living.museum livinghistory.museum localhistory.museum london.museum losangeles.museum louvre.museum loyalist.museum lucerne.museum luxembourg.museum luzern.museum mad.museum madrid.museum mallorca.museum manchester.museum mansion.museum mansions.museum manx.museum marburg.museum maritime.museum maritimo.museum maryland.museum marylhurst.museum media.museum medical.museum medizinhistorisches.museum meeres.museum memorial.museum mesaverde.museum michigan.museum midatlantic.museum military.museum mill.museum miners.museum mining.museum minnesota.museum missile.museum missoula.museum modern.museum moma.museum money.museum monmouth.museum monticello.museum montreal.museum moscow.museum motorcycle.museum muenchen.museum muenster.museum mulhouse.museum muncie.museum museet.museum museumcenter.museum museumvereniging.museum music.museum national.museum nationalfirearms.museum nationalheritage.museum nativeamerican.museum naturalhistory.museum naturalhistorymuseum.museum naturalsciences.museum nature.museum naturhistorisches.museum natuurwetenschappen.museum naumburg.museum naval.museum nebraska.museum neues.museum newhampshire.museum newjersey.museum newmexico.museum newport.museum newspaper.museum newyork.museum niepce.museum norfolk.museum north.museum nrw.museum nuernberg.museum nuremberg.museum nyc.museum nyny.museum oceanographic.museum oceanographique.museum omaha.museum online.museum ontario.museum openair.museum oregon.museum oregontrail.museum otago.museum oxford.museum pacific.museum paderborn.museum palace.museum paleo.museum palmsprings.museum panama.museum paris.museum pasadena.museum pharmacy.museum philadelphia.museum philadelphiaarea.museum philately.museum phoenix.museum photography.museum pilots.museum pittsburgh.museum planetarium.museum plantation.museum plants.museum plaza.museum portal.museum portland.museum portlligat.museum posts-and-telecommunications.museum preservation.museum presidio.museum press.museum project.museum public.museum pubol.museum quebec.museum railroad.museum railway.museum research.museum resistance.museum riodejaneiro.museum rochester.museum rockart.museum roma.museum russia.museum saintlouis.museum salem.museum salvadordali.museum salzburg.museum sandiego.museum sanfrancisco.museum santabarbara.museum santacruz.museum santafe.museum saskatchewan.museum satx.museum savannahga.museum schlesisches.museum schoenbrunn.museum schokoladen.museum school.museum schweiz.museum science.museum scienceandhistory.museum scienceandindustry.museum sciencecenter.museum sciencecenters.museum science-fiction.museum sciencehistory.museum sciences.museum sciencesnaturelles.museum scotland.museum seaport.museum settlement.museum settlers.museum shell.museum sherbrooke.museum sibenik.museum silk.museum ski.museum skole.museum society.museum sologne.museum soundandvision.museum southcarolina.museum southwest.museum space.museum spy.museum square.museum stadt.museum stalbans.museum starnberg.museum state.museum stateofdelaware.museum station.museum steam.museum steiermark.museum stjohn.museum stockholm.museum stpetersburg.museum stuttgart.museum suisse.museum surgeonshall.museum surrey.museum svizzera.museum sweden.museum sydney.museum tank.museum tcm.museum technology.museum telekommunikation.museum television.museum texas.museum textile.museum theater.museum time.museum timekeeping.museum topology.museum torino.museum touch.museum town.museum transport.museum tree.museum trolley.museum trust.museum trustee.museum uhren.museum ulm.museum undersea.museum university.museum usa.museum usantiques.museum usarts.museum uscountryestate.museum usculture.museum usdecorativearts.museum usgarden.museum ushistory.museum ushuaia.museum uslivinghistory.museum utah.museum uvic.museum valley.museum vantaa.museum versailles.museum viking.museum village.museum virginia.museum virtual.museum virtuel.museum vlaanderen.museum volkenkunde.museum wales.museum wallonie.museum war.museum washingtondc.museum watchandclock.museum watch-and-clock.museum western.museum westfalen.museum whaling.museum wildlife.museum williamsburg.museum windmill.museum workshop.museum york.museum yorkshire.museum yosemite.museum youth.museum zoological.museum zoology.museum xn--9dbhblg6di.museum xn--h1aegh.museum // mv : https://en.wikipedia.org/wiki/.mv // "mv" included because, contra Wikipedia, google.mv exists. mv aero.mv biz.mv com.mv coop.mv edu.mv gov.mv info.mv int.mv mil.mv museum.mv name.mv net.mv org.mv pro.mv // mw : http://www.registrar.mw/ mw ac.mw biz.mw co.mw com.mw coop.mw edu.mw gov.mw int.mw museum.mw net.mw org.mw // mx : http://www.nic.mx/ // Submitted by registry mx com.mx org.mx gob.mx edu.mx net.mx // my : http://www.mynic.net.my/ my com.my net.my org.my gov.my edu.my mil.my name.my // mz : http://www.uem.mz/ // Submitted by registry mz ac.mz adv.mz co.mz edu.mz gov.mz mil.mz net.mz org.mz // na : http://www.na-nic.com.na/ // http://www.info.na/domain/ na info.na pro.na name.na school.na or.na dr.na us.na mx.na ca.na in.na cc.na tv.na ws.na mobi.na co.na com.na org.na // name : has 2nd-level tlds, but there's no list of them name // nc : http://www.cctld.nc/ nc asso.nc nom.nc // ne : https://en.wikipedia.org/wiki/.ne ne // net : https://en.wikipedia.org/wiki/.net net // nf : https://en.wikipedia.org/wiki/.nf nf com.nf net.nf per.nf rec.nf web.nf arts.nf firm.nf info.nf other.nf store.nf // ng : http://www.nira.org.ng/index.php/join-us/register-ng-domain/189-nira-slds ng com.ng edu.ng gov.ng i.ng mil.ng mobi.ng name.ng net.ng org.ng sch.ng // ni : http://www.nic.ni/ ni ac.ni biz.ni co.ni com.ni edu.ni gob.ni in.ni info.ni int.ni mil.ni net.ni nom.ni org.ni web.ni // nl : https://en.wikipedia.org/wiki/.nl // https://www.sidn.nl/ // ccTLD for the Netherlands nl // no : http://www.norid.no/regelverk/index.en.html // The Norwegian registry has declined to notify us of updates. The web pages // referenced below are the official source of the data. There is also an // announce mailing list: // https://postlister.uninett.no/sympa/info/norid-diskusjon no // Norid generic domains : http://www.norid.no/regelverk/vedlegg-c.en.html fhs.no vgs.no fylkesbibl.no folkebibl.no museum.no idrett.no priv.no // Non-Norid generic domains : http://www.norid.no/regelverk/vedlegg-d.en.html mil.no stat.no dep.no kommune.no herad.no // no geographical names : http://www.norid.no/regelverk/vedlegg-b.en.html // counties aa.no ah.no bu.no fm.no hl.no hm.no jan-mayen.no mr.no nl.no nt.no of.no ol.no oslo.no rl.no sf.no st.no svalbard.no tm.no tr.no va.no vf.no // primary and lower secondary schools per county gs.aa.no gs.ah.no gs.bu.no gs.fm.no gs.hl.no gs.hm.no gs.jan-mayen.no gs.mr.no gs.nl.no gs.nt.no gs.of.no gs.ol.no gs.oslo.no gs.rl.no gs.sf.no gs.st.no gs.svalbard.no gs.tm.no gs.tr.no gs.va.no gs.vf.no // cities akrehamn.no xn--krehamn-dxa.no algard.no xn--lgrd-poac.no arna.no brumunddal.no bryne.no bronnoysund.no xn--brnnysund-m8ac.no drobak.no xn--drbak-wua.no egersund.no fetsund.no floro.no xn--flor-jra.no fredrikstad.no hokksund.no honefoss.no xn--hnefoss-q1a.no jessheim.no jorpeland.no xn--jrpeland-54a.no kirkenes.no kopervik.no krokstadelva.no langevag.no xn--langevg-jxa.no leirvik.no mjondalen.no xn--mjndalen-64a.no mo-i-rana.no mosjoen.no xn--mosjen-eya.no nesoddtangen.no orkanger.no osoyro.no xn--osyro-wua.no raholt.no xn--rholt-mra.no sandnessjoen.no xn--sandnessjen-ogb.no skedsmokorset.no slattum.no spjelkavik.no stathelle.no stavern.no stjordalshalsen.no xn--stjrdalshalsen-sqb.no tananger.no tranby.no vossevangen.no // communities afjord.no xn--fjord-lra.no agdenes.no al.no xn--l-1fa.no alesund.no xn--lesund-hua.no alstahaug.no alta.no xn--lt-liac.no alaheadju.no xn--laheadju-7ya.no alvdal.no amli.no xn--mli-tla.no amot.no xn--mot-tla.no andebu.no andoy.no xn--andy-ira.no andasuolo.no ardal.no xn--rdal-poa.no aremark.no arendal.no xn--s-1fa.no aseral.no xn--seral-lra.no asker.no askim.no askvoll.no askoy.no xn--asky-ira.no asnes.no xn--snes-poa.no audnedaln.no aukra.no aure.no aurland.no aurskog-holand.no xn--aurskog-hland-jnb.no austevoll.no austrheim.no averoy.no xn--avery-yua.no balestrand.no ballangen.no balat.no xn--blt-elab.no balsfjord.no bahccavuotna.no xn--bhccavuotna-k7a.no bamble.no bardu.no beardu.no beiarn.no bajddar.no xn--bjddar-pta.no baidar.no xn--bidr-5nac.no berg.no bergen.no berlevag.no xn--berlevg-jxa.no bearalvahki.no xn--bearalvhki-y4a.no bindal.no birkenes.no bjarkoy.no xn--bjarky-fya.no bjerkreim.no bjugn.no bodo.no xn--bod-2na.no badaddja.no xn--bdddj-mrabd.no budejju.no bokn.no bremanger.no bronnoy.no xn--brnny-wuac.no bygland.no bykle.no barum.no xn--brum-voa.no bo.telemark.no xn--b-5ga.telemark.no bo.nordland.no xn--b-5ga.nordland.no bievat.no xn--bievt-0qa.no bomlo.no xn--bmlo-gra.no batsfjord.no xn--btsfjord-9za.no bahcavuotna.no xn--bhcavuotna-s4a.no dovre.no drammen.no drangedal.no dyroy.no xn--dyry-ira.no donna.no xn--dnna-gra.no eid.no eidfjord.no eidsberg.no eidskog.no eidsvoll.no eigersund.no elverum.no enebakk.no engerdal.no etne.no etnedal.no evenes.no evenassi.no xn--eveni-0qa01ga.no evje-og-hornnes.no farsund.no fauske.no fuossko.no fuoisku.no fedje.no fet.no finnoy.no xn--finny-yua.no fitjar.no fjaler.no fjell.no flakstad.no flatanger.no flekkefjord.no flesberg.no flora.no fla.no xn--fl-zia.no folldal.no forsand.no fosnes.no frei.no frogn.no froland.no frosta.no frana.no xn--frna-woa.no froya.no xn--frya-hra.no fusa.no fyresdal.no forde.no xn--frde-gra.no gamvik.no gangaviika.no xn--ggaviika-8ya47h.no gaular.no gausdal.no gildeskal.no xn--gildeskl-g0a.no giske.no gjemnes.no gjerdrum.no gjerstad.no gjesdal.no gjovik.no xn--gjvik-wua.no gloppen.no gol.no gran.no grane.no granvin.no gratangen.no grimstad.no grong.no kraanghke.no xn--kranghke-b0a.no grue.no gulen.no hadsel.no halden.no halsa.no hamar.no hamaroy.no habmer.no xn--hbmer-xqa.no hapmir.no xn--hpmir-xqa.no hammerfest.no hammarfeasta.no xn--hmmrfeasta-s4ac.no haram.no hareid.no harstad.no hasvik.no aknoluokta.no xn--koluokta-7ya57h.no hattfjelldal.no aarborte.no haugesund.no hemne.no hemnes.no hemsedal.no heroy.more-og-romsdal.no xn--hery-ira.xn--mre-og-romsdal-qqb.no heroy.nordland.no xn--hery-ira.nordland.no hitra.no hjartdal.no hjelmeland.no hobol.no xn--hobl-ira.no hof.no hol.no hole.no holmestrand.no holtalen.no xn--holtlen-hxa.no hornindal.no horten.no hurdal.no hurum.no hvaler.no hyllestad.no hagebostad.no xn--hgebostad-g3a.no hoyanger.no xn--hyanger-q1a.no hoylandet.no xn--hylandet-54a.no ha.no xn--h-2fa.no ibestad.no inderoy.no xn--indery-fya.no iveland.no jevnaker.no jondal.no jolster.no xn--jlster-bya.no karasjok.no karasjohka.no xn--krjohka-hwab49j.no karlsoy.no galsa.no xn--gls-elac.no karmoy.no xn--karmy-yua.no kautokeino.no guovdageaidnu.no klepp.no klabu.no xn--klbu-woa.no kongsberg.no kongsvinger.no kragero.no xn--krager-gya.no kristiansand.no kristiansund.no krodsherad.no xn--krdsherad-m8a.no kvalsund.no rahkkeravju.no xn--rhkkervju-01af.no kvam.no kvinesdal.no kvinnherad.no kviteseid.no kvitsoy.no xn--kvitsy-fya.no kvafjord.no xn--kvfjord-nxa.no giehtavuoatna.no kvanangen.no xn--kvnangen-k0a.no navuotna.no xn--nvuotna-hwa.no kafjord.no xn--kfjord-iua.no gaivuotna.no xn--givuotna-8ya.no larvik.no lavangen.no lavagis.no loabat.no xn--loabt-0qa.no lebesby.no davvesiida.no leikanger.no leirfjord.no leka.no leksvik.no lenvik.no leangaviika.no xn--leagaviika-52b.no lesja.no levanger.no lier.no lierne.no lillehammer.no lillesand.no lindesnes.no lindas.no xn--linds-pra.no lom.no loppa.no lahppi.no xn--lhppi-xqa.no lund.no lunner.no luroy.no xn--lury-ira.no luster.no lyngdal.no lyngen.no ivgu.no lardal.no lerdal.no xn--lrdal-sra.no lodingen.no xn--ldingen-q1a.no lorenskog.no xn--lrenskog-54a.no loten.no xn--lten-gra.no malvik.no masoy.no xn--msy-ula0h.no muosat.no xn--muost-0qa.no mandal.no marker.no marnardal.no masfjorden.no meland.no meldal.no melhus.no meloy.no xn--mely-ira.no meraker.no xn--merker-kua.no moareke.no xn--moreke-jua.no midsund.no midtre-gauldal.no modalen.no modum.no molde.no moskenes.no moss.no mosvik.no malselv.no xn--mlselv-iua.no malatvuopmi.no xn--mlatvuopmi-s4a.no namdalseid.no aejrie.no namsos.no namsskogan.no naamesjevuemie.no xn--nmesjevuemie-tcba.no laakesvuemie.no nannestad.no narvik.no narviika.no naustdal.no nedre-eiker.no nes.akershus.no nes.buskerud.no nesna.no nesodden.no nesseby.no unjarga.no xn--unjrga-rta.no nesset.no nissedal.no nittedal.no nord-aurdal.no nord-fron.no nord-odal.no norddal.no nordkapp.no davvenjarga.no xn--davvenjrga-y4a.no nordre-land.no nordreisa.no raisa.no xn--risa-5na.no nore-og-uvdal.no notodden.no naroy.no xn--nry-yla5g.no notteroy.no xn--nttery-byae.no odda.no oksnes.no xn--ksnes-uua.no oppdal.no oppegard.no xn--oppegrd-ixa.no orkdal.no orland.no xn--rland-uua.no orskog.no xn--rskog-uua.no orsta.no xn--rsta-fra.no os.hedmark.no os.hordaland.no osen.no osteroy.no xn--ostery-fya.no ostre-toten.no xn--stre-toten-zcb.no overhalla.no ovre-eiker.no xn--vre-eiker-k8a.no oyer.no xn--yer-zna.no oygarden.no xn--ygarden-p1a.no oystre-slidre.no xn--ystre-slidre-ujb.no porsanger.no porsangu.no xn--porsgu-sta26f.no porsgrunn.no radoy.no xn--rady-ira.no rakkestad.no rana.no ruovat.no randaberg.no rauma.no rendalen.no rennebu.no rennesoy.no xn--rennesy-v1a.no rindal.no ringebu.no ringerike.no ringsaker.no rissa.no risor.no xn--risr-ira.no roan.no rollag.no rygge.no ralingen.no xn--rlingen-mxa.no rodoy.no xn--rdy-0nab.no romskog.no xn--rmskog-bya.no roros.no xn--rros-gra.no rost.no xn--rst-0na.no royken.no xn--ryken-vua.no royrvik.no xn--ryrvik-bya.no rade.no xn--rde-ula.no salangen.no siellak.no saltdal.no salat.no xn--slt-elab.no xn--slat-5na.no samnanger.no sande.more-og-romsdal.no sande.xn--mre-og-romsdal-qqb.no sande.vestfold.no sandefjord.no sandnes.no sandoy.no xn--sandy-yua.no sarpsborg.no sauda.no sauherad.no sel.no selbu.no selje.no seljord.no sigdal.no siljan.no sirdal.no skaun.no skedsmo.no ski.no skien.no skiptvet.no skjervoy.no xn--skjervy-v1a.no skierva.no xn--skierv-uta.no skjak.no xn--skjk-soa.no skodje.no skanland.no xn--sknland-fxa.no skanit.no xn--sknit-yqa.no smola.no xn--smla-hra.no snillfjord.no snasa.no xn--snsa-roa.no snoasa.no snaase.no xn--snase-nra.no sogndal.no sokndal.no sola.no solund.no songdalen.no sortland.no spydeberg.no stange.no stavanger.no steigen.no steinkjer.no stjordal.no xn--stjrdal-s1a.no stokke.no stor-elvdal.no stord.no stordal.no storfjord.no omasvuotna.no strand.no stranda.no stryn.no sula.no suldal.no sund.no sunndal.no surnadal.no sveio.no svelvik.no sykkylven.no sogne.no xn--sgne-gra.no somna.no xn--smna-gra.no sondre-land.no xn--sndre-land-0cb.no sor-aurdal.no xn--sr-aurdal-l8a.no sor-fron.no xn--sr-fron-q1a.no sor-odal.no xn--sr-odal-q1a.no sor-varanger.no xn--sr-varanger-ggb.no matta-varjjat.no xn--mtta-vrjjat-k7af.no sorfold.no xn--srfold-bya.no sorreisa.no xn--srreisa-q1a.no sorum.no xn--srum-gra.no tana.no deatnu.no time.no tingvoll.no tinn.no tjeldsund.no dielddanuorri.no tjome.no xn--tjme-hra.no tokke.no tolga.no torsken.no tranoy.no xn--trany-yua.no tromso.no xn--troms-zua.no tromsa.no romsa.no trondheim.no troandin.no trysil.no trana.no xn--trna-woa.no trogstad.no xn--trgstad-r1a.no tvedestrand.no tydal.no tynset.no tysfjord.no divtasvuodna.no divttasvuotna.no tysnes.no tysvar.no xn--tysvr-vra.no tonsberg.no xn--tnsberg-q1a.no ullensaker.no ullensvang.no ulvik.no utsira.no vadso.no xn--vads-jra.no cahcesuolo.no xn--hcesuolo-7ya35b.no vaksdal.no valle.no vang.no vanylven.no vardo.no xn--vard-jra.no varggat.no xn--vrggt-xqad.no vefsn.no vaapste.no vega.no vegarshei.no xn--vegrshei-c0a.no vennesla.no verdal.no verran.no vestby.no vestnes.no vestre-slidre.no vestre-toten.no vestvagoy.no xn--vestvgy-ixa6o.no vevelstad.no vik.no vikna.no vindafjord.no volda.no voss.no varoy.no xn--vry-yla5g.no vagan.no xn--vgan-qoa.no voagat.no vagsoy.no xn--vgsy-qoa0j.no vaga.no xn--vg-yiab.no valer.ostfold.no xn--vler-qoa.xn--stfold-9xa.no valer.hedmark.no xn--vler-qoa.hedmark.no // np : http://www.mos.com.np/register.html *.np // nr : http://cenpac.net.nr/dns/index.html // Submitted by registry nr biz.nr info.nr gov.nr edu.nr org.nr net.nr com.nr // nu : https://en.wikipedia.org/wiki/.nu nu // nz : https://en.wikipedia.org/wiki/.nz // Submitted by registry nz ac.nz co.nz cri.nz geek.nz gen.nz govt.nz health.nz iwi.nz kiwi.nz maori.nz mil.nz xn--mori-qsa.nz net.nz org.nz parliament.nz school.nz // om : https://en.wikipedia.org/wiki/.om om co.om com.om edu.om gov.om med.om museum.om net.om org.om pro.om // onion : https://tools.ietf.org/html/rfc7686 onion // org : https://en.wikipedia.org/wiki/.org org // pa : http://www.nic.pa/ // Some additional second level "domains" resolve directly as hostnames, such as // pannet.pa, so we add a rule for "pa". pa ac.pa gob.pa com.pa org.pa sld.pa edu.pa net.pa ing.pa abo.pa med.pa nom.pa // pe : https://www.nic.pe/InformeFinalComision.pdf pe edu.pe gob.pe nom.pe mil.pe org.pe com.pe net.pe // pf : http://www.gobin.info/domainname/formulaire-pf.pdf pf com.pf org.pf edu.pf // pg : https://en.wikipedia.org/wiki/.pg *.pg // ph : http://www.domains.ph/FAQ2.asp // Submitted by registry ph com.ph net.ph org.ph gov.ph edu.ph ngo.ph mil.ph i.ph // pk : http://pk5.pknic.net.pk/pk5/msgNamepk.PK pk com.pk net.pk edu.pk org.pk fam.pk biz.pk web.pk gov.pk gob.pk gok.pk gon.pk gop.pk gos.pk info.pk // pl http://www.dns.pl/english/index.html // Submitted by registry pl com.pl net.pl org.pl // pl functional domains (http://www.dns.pl/english/index.html) aid.pl agro.pl atm.pl auto.pl biz.pl edu.pl gmina.pl gsm.pl info.pl mail.pl miasta.pl media.pl mil.pl nieruchomosci.pl nom.pl pc.pl powiat.pl priv.pl realestate.pl rel.pl sex.pl shop.pl sklep.pl sos.pl szkola.pl targi.pl tm.pl tourism.pl travel.pl turystyka.pl // Government domains gov.pl ap.gov.pl ic.gov.pl is.gov.pl us.gov.pl kmpsp.gov.pl kppsp.gov.pl kwpsp.gov.pl psp.gov.pl wskr.gov.pl kwp.gov.pl mw.gov.pl ug.gov.pl um.gov.pl umig.gov.pl ugim.gov.pl upow.gov.pl uw.gov.pl starostwo.gov.pl pa.gov.pl po.gov.pl psse.gov.pl pup.gov.pl rzgw.gov.pl sa.gov.pl so.gov.pl sr.gov.pl wsa.gov.pl sko.gov.pl uzs.gov.pl wiih.gov.pl winb.gov.pl pinb.gov.pl wios.gov.pl witd.gov.pl wzmiuw.gov.pl piw.gov.pl wiw.gov.pl griw.gov.pl wif.gov.pl oum.gov.pl sdn.gov.pl zp.gov.pl uppo.gov.pl mup.gov.pl wuoz.gov.pl konsulat.gov.pl oirm.gov.pl // pl regional domains (http://www.dns.pl/english/index.html) augustow.pl babia-gora.pl bedzin.pl beskidy.pl bialowieza.pl bialystok.pl bielawa.pl bieszczady.pl boleslawiec.pl bydgoszcz.pl bytom.pl cieszyn.pl czeladz.pl czest.pl dlugoleka.pl elblag.pl elk.pl glogow.pl gniezno.pl gorlice.pl grajewo.pl ilawa.pl jaworzno.pl jelenia-gora.pl jgora.pl kalisz.pl kazimierz-dolny.pl karpacz.pl kartuzy.pl kaszuby.pl katowice.pl kepno.pl ketrzyn.pl klodzko.pl kobierzyce.pl kolobrzeg.pl konin.pl konskowola.pl kutno.pl lapy.pl lebork.pl legnica.pl lezajsk.pl limanowa.pl lomza.pl lowicz.pl lubin.pl lukow.pl malbork.pl malopolska.pl mazowsze.pl mazury.pl mielec.pl mielno.pl mragowo.pl naklo.pl nowaruda.pl nysa.pl olawa.pl olecko.pl olkusz.pl olsztyn.pl opoczno.pl opole.pl ostroda.pl ostroleka.pl ostrowiec.pl ostrowwlkp.pl pila.pl pisz.pl podhale.pl podlasie.pl polkowice.pl pomorze.pl pomorskie.pl prochowice.pl pruszkow.pl przeworsk.pl pulawy.pl radom.pl rawa-maz.pl rybnik.pl rzeszow.pl sanok.pl sejny.pl slask.pl slupsk.pl sosnowiec.pl stalowa-wola.pl skoczow.pl starachowice.pl stargard.pl suwalki.pl swidnica.pl swiebodzin.pl swinoujscie.pl szczecin.pl szczytno.pl tarnobrzeg.pl tgory.pl turek.pl tychy.pl ustka.pl walbrzych.pl warmia.pl warszawa.pl waw.pl wegrow.pl wielun.pl wlocl.pl wloclawek.pl wodzislaw.pl wolomin.pl wroclaw.pl zachpomor.pl zagan.pl zarow.pl zgora.pl zgorzelec.pl // pm : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf pm // pn : http://www.government.pn/PnRegistry/policies.htm pn gov.pn co.pn org.pn edu.pn net.pn // post : https://en.wikipedia.org/wiki/.post post // pr : http://www.nic.pr/index.asp?f=1 pr com.pr net.pr org.pr gov.pr edu.pr isla.pr pro.pr biz.pr info.pr name.pr // these aren't mentioned on nic.pr, but on https://en.wikipedia.org/wiki/.pr est.pr prof.pr ac.pr // pro : http://registry.pro/get-pro pro aaa.pro aca.pro acct.pro avocat.pro bar.pro cpa.pro eng.pro jur.pro law.pro med.pro recht.pro // ps : https://en.wikipedia.org/wiki/.ps // http://www.nic.ps/registration/policy.html#reg ps edu.ps gov.ps sec.ps plo.ps com.ps org.ps net.ps // pt : http://online.dns.pt/dns/start_dns pt net.pt gov.pt org.pt edu.pt int.pt publ.pt com.pt nome.pt // pw : https://en.wikipedia.org/wiki/.pw pw co.pw ne.pw or.pw ed.pw go.pw belau.pw // py : http://www.nic.py/pautas.html#seccion_9 // Submitted by registry py com.py coop.py edu.py gov.py mil.py net.py org.py // qa : http://domains.qa/en/ qa com.qa edu.qa gov.qa mil.qa name.qa net.qa org.qa sch.qa // re : http://www.afnic.re/obtenir/chartes/nommage-re/annexe-descriptifs re asso.re com.re nom.re // ro : http://www.rotld.ro/ ro arts.ro com.ro firm.ro info.ro nom.ro nt.ro org.ro rec.ro store.ro tm.ro www.ro // rs : https://www.rnids.rs/en/domains/national-domains rs ac.rs co.rs edu.rs gov.rs in.rs org.rs // ru : https://cctld.ru/en/domains/domens_ru/reserved/ ru ac.ru edu.ru gov.ru int.ru mil.ru test.ru // rw : http://www.nic.rw/cgi-bin/policy.pl rw gov.rw net.rw edu.rw ac.rw com.rw co.rw int.rw mil.rw gouv.rw // sa : http://www.nic.net.sa/ sa com.sa net.sa org.sa gov.sa med.sa pub.sa edu.sa sch.sa // sb : http://www.sbnic.net.sb/ // Submitted by registry sb com.sb edu.sb gov.sb net.sb org.sb // sc : http://www.nic.sc/ sc com.sc gov.sc net.sc org.sc edu.sc // sd : http://www.isoc.sd/sudanic.isoc.sd/billing_pricing.htm // Submitted by registry sd com.sd net.sd org.sd edu.sd med.sd tv.sd gov.sd info.sd // se : https://en.wikipedia.org/wiki/.se // Submitted by registry se a.se ac.se b.se bd.se brand.se c.se d.se e.se f.se fh.se fhsk.se fhv.se g.se h.se i.se k.se komforb.se kommunalforbund.se komvux.se l.se lanbib.se m.se n.se naturbruksgymn.se o.se org.se p.se parti.se pp.se press.se r.se s.se t.se tm.se u.se w.se x.se y.se z.se // sg : http://www.nic.net.sg/page/registration-policies-procedures-and-guidelines sg com.sg net.sg org.sg gov.sg edu.sg per.sg // sh : http://www.nic.sh/registrar.html sh com.sh net.sh gov.sh org.sh mil.sh // si : https://en.wikipedia.org/wiki/.si si // sj : No registrations at this time. // Submitted by registry sj // sk : https://en.wikipedia.org/wiki/.sk // list of 2nd level domains ? sk // sl : http://www.nic.sl // Submitted by registry sl com.sl net.sl edu.sl gov.sl org.sl // sm : https://en.wikipedia.org/wiki/.sm sm // sn : https://en.wikipedia.org/wiki/.sn sn art.sn com.sn edu.sn gouv.sn org.sn perso.sn univ.sn // so : http://www.soregistry.com/ so com.so net.so org.so // sr : https://en.wikipedia.org/wiki/.sr sr // st : http://www.nic.st/html/policyrules/ st co.st com.st consulado.st edu.st embaixada.st gov.st mil.st net.st org.st principe.st saotome.st store.st // su : https://en.wikipedia.org/wiki/.su su // sv : http://www.svnet.org.sv/niveldos.pdf sv com.sv edu.sv gob.sv org.sv red.sv // sx : https://en.wikipedia.org/wiki/.sx // Submitted by registry sx gov.sx // sy : https://en.wikipedia.org/wiki/.sy // see also: http://www.gobin.info/domainname/sy.doc sy edu.sy gov.sy net.sy mil.sy com.sy org.sy // sz : https://en.wikipedia.org/wiki/.sz // http://www.sispa.org.sz/ sz co.sz ac.sz org.sz // tc : https://en.wikipedia.org/wiki/.tc tc // td : https://en.wikipedia.org/wiki/.td td // tel: https://en.wikipedia.org/wiki/.tel // http://www.telnic.org/ tel // tf : https://en.wikipedia.org/wiki/.tf tf // tg : https://en.wikipedia.org/wiki/.tg // http://www.nic.tg/ tg // th : https://en.wikipedia.org/wiki/.th // Submitted by registry th ac.th co.th go.th in.th mi.th net.th or.th // tj : http://www.nic.tj/policy.html tj ac.tj biz.tj co.tj com.tj edu.tj go.tj gov.tj int.tj mil.tj name.tj net.tj nic.tj org.tj test.tj web.tj // tk : https://en.wikipedia.org/wiki/.tk tk // tl : https://en.wikipedia.org/wiki/.tl tl gov.tl // tm : http://www.nic.tm/local.html tm com.tm co.tm org.tm net.tm nom.tm gov.tm mil.tm edu.tm // tn : https://en.wikipedia.org/wiki/.tn // http://whois.ati.tn/ tn com.tn ens.tn fin.tn gov.tn ind.tn intl.tn nat.tn net.tn org.tn info.tn perso.tn tourism.tn edunet.tn rnrt.tn rns.tn rnu.tn mincom.tn agrinet.tn defense.tn turen.tn // to : https://en.wikipedia.org/wiki/.to // Submitted by registry to com.to gov.to net.to org.to edu.to mil.to // subTLDs: https://www.nic.tr/forms/eng/policies.pdf // and: https://www.nic.tr/forms/politikalar.pdf // Submitted by tr com.tr info.tr biz.tr net.tr org.tr web.tr gen.tr tv.tr av.tr dr.tr bbs.tr name.tr tel.tr gov.tr bel.tr pol.tr mil.tr k12.tr edu.tr kep.tr // Used by Northern Cyprus nc.tr // Used by government agencies of Northern Cyprus gov.nc.tr // tt : http://www.nic.tt/ tt co.tt com.tt org.tt net.tt biz.tt info.tt pro.tt int.tt coop.tt jobs.tt mobi.tt travel.tt museum.tt aero.tt name.tt gov.tt edu.tt // tv : https://en.wikipedia.org/wiki/.tv // Not listing any 2LDs as reserved since none seem to exist in practice, // Wikipedia notwithstanding. tv // tw : https://en.wikipedia.org/wiki/.tw tw edu.tw gov.tw mil.tw com.tw net.tw org.tw idv.tw game.tw ebiz.tw club.tw xn--zf0ao64a.tw xn--uc0atv.tw xn--czrw28b.tw // tz : http://www.tznic.or.tz/index.php/domains // Submitted by registry tz ac.tz co.tz go.tz hotel.tz info.tz me.tz mil.tz mobi.tz ne.tz or.tz sc.tz tv.tz // ua : https://hostmaster.ua/policy/?ua // Submitted by registry ua // ua 2LD com.ua edu.ua gov.ua in.ua net.ua org.ua // ua geographic names // https://hostmaster.ua/2ld/ cherkassy.ua cherkasy.ua chernigov.ua chernihiv.ua chernivtsi.ua chernovtsy.ua ck.ua cn.ua cr.ua crimea.ua cv.ua dn.ua dnepropetrovsk.ua dnipropetrovsk.ua dominic.ua donetsk.ua dp.ua if.ua ivano-frankivsk.ua kh.ua kharkiv.ua kharkov.ua kherson.ua khmelnitskiy.ua khmelnytskyi.ua kiev.ua kirovograd.ua km.ua kr.ua krym.ua ks.ua kv.ua kyiv.ua lg.ua lt.ua lugansk.ua lutsk.ua lv.ua lviv.ua mk.ua mykolaiv.ua nikolaev.ua od.ua odesa.ua odessa.ua pl.ua poltava.ua rivne.ua rovno.ua rv.ua sb.ua sebastopol.ua sevastopol.ua sm.ua sumy.ua te.ua ternopil.ua uz.ua uzhgorod.ua vinnica.ua vinnytsia.ua vn.ua volyn.ua yalta.ua zaporizhzhe.ua zaporizhzhia.ua zhitomir.ua zhytomyr.ua zp.ua zt.ua // ug : https://www.registry.co.ug/ ug co.ug or.ug ac.ug sc.ug go.ug ne.ug com.ug org.ug // uk : https://en.wikipedia.org/wiki/.uk // Submitted by registry uk ac.uk co.uk gov.uk ltd.uk me.uk net.uk nhs.uk org.uk plc.uk police.uk *.sch.uk // us : https://en.wikipedia.org/wiki/.us us dni.us fed.us isa.us kids.us nsn.us // us geographic names ak.us al.us ar.us as.us az.us ca.us co.us ct.us dc.us de.us fl.us ga.us gu.us hi.us ia.us id.us il.us in.us ks.us ky.us la.us ma.us md.us me.us mi.us mn.us mo.us ms.us mt.us nc.us nd.us ne.us nh.us nj.us nm.us nv.us ny.us oh.us ok.us or.us pa.us pr.us ri.us sc.us sd.us tn.us tx.us ut.us vi.us vt.us va.us wa.us wi.us wv.us wy.us // The registrar notes several more specific domains available in each state, // such as state.*.us, dst.*.us, etc., but resolution of these is somewhat // haphazard; in some states these domains resolve as addresses, while in others // only subdomains are available, or even nothing at all. We include the // most common ones where it's clear that different sites are different // entities. k12.ak.us k12.al.us k12.ar.us k12.as.us k12.az.us k12.ca.us k12.co.us k12.ct.us k12.dc.us k12.de.us k12.fl.us k12.ga.us k12.gu.us // k12.hi.us Bug 614565 - Hawaii has a state-wide DOE login k12.ia.us k12.id.us k12.il.us k12.in.us k12.ks.us k12.ky.us k12.la.us k12.ma.us k12.md.us k12.me.us k12.mi.us k12.mn.us k12.mo.us k12.ms.us k12.mt.us k12.nc.us // k12.nd.us Bug 1028347 - Removed at request of Travis Rosso k12.ne.us k12.nh.us k12.nj.us k12.nm.us k12.nv.us k12.ny.us k12.oh.us k12.ok.us k12.or.us k12.pa.us k12.pr.us k12.ri.us k12.sc.us // k12.sd.us Bug 934131 - Removed at request of James Booze k12.tn.us k12.tx.us k12.ut.us k12.vi.us k12.vt.us k12.va.us k12.wa.us k12.wi.us // k12.wv.us Bug 947705 - Removed at request of Verne Britton k12.wy.us cc.ak.us cc.al.us cc.ar.us cc.as.us cc.az.us cc.ca.us cc.co.us cc.ct.us cc.dc.us cc.de.us cc.fl.us cc.ga.us cc.gu.us cc.hi.us cc.ia.us cc.id.us cc.il.us cc.in.us cc.ks.us cc.ky.us cc.la.us cc.ma.us cc.md.us cc.me.us cc.mi.us cc.mn.us cc.mo.us cc.ms.us cc.mt.us cc.nc.us cc.nd.us cc.ne.us cc.nh.us cc.nj.us cc.nm.us cc.nv.us cc.ny.us cc.oh.us cc.ok.us cc.or.us cc.pa.us cc.pr.us cc.ri.us cc.sc.us cc.sd.us cc.tn.us cc.tx.us cc.ut.us cc.vi.us cc.vt.us cc.va.us cc.wa.us cc.wi.us cc.wv.us cc.wy.us lib.ak.us lib.al.us lib.ar.us lib.as.us lib.az.us lib.ca.us lib.co.us lib.ct.us lib.dc.us // lib.de.us Issue #243 - Moved to Private section at request of Ed Moore lib.fl.us lib.ga.us lib.gu.us lib.hi.us lib.ia.us lib.id.us lib.il.us lib.in.us lib.ks.us lib.ky.us lib.la.us lib.ma.us lib.md.us lib.me.us lib.mi.us lib.mn.us lib.mo.us lib.ms.us lib.mt.us lib.nc.us lib.nd.us lib.ne.us lib.nh.us lib.nj.us lib.nm.us lib.nv.us lib.ny.us lib.oh.us lib.ok.us lib.or.us lib.pa.us lib.pr.us lib.ri.us lib.sc.us lib.sd.us lib.tn.us lib.tx.us lib.ut.us lib.vi.us lib.vt.us lib.va.us lib.wa.us lib.wi.us // lib.wv.us Bug 941670 - Removed at request of Larry W Arnold lib.wy.us // k12.ma.us contains school districts in Massachusetts. The 4LDs are // managed independently except for private (PVT), charter (CHTR) and // parochial (PAROCH) schools. Those are delegated directly to the // 5LD operators. pvt.k12.ma.us chtr.k12.ma.us paroch.k12.ma.us // Merit Network, Inc. maintains the registry for =~ /(k12|cc|lib).mi.us/ and the following // see also: http://domreg.merit.edu // see also: whois -h whois.domreg.merit.edu help ann-arbor.mi.us cog.mi.us dst.mi.us eaton.mi.us gen.mi.us mus.mi.us tec.mi.us washtenaw.mi.us // uy : http://www.nic.org.uy/ uy com.uy edu.uy gub.uy mil.uy net.uy org.uy // uz : http://www.reg.uz/ uz co.uz com.uz net.uz org.uz // va : https://en.wikipedia.org/wiki/.va va // vc : https://en.wikipedia.org/wiki/.vc // Submitted by registry vc com.vc net.vc org.vc gov.vc mil.vc edu.vc // ve : https://registro.nic.ve/ // Submitted by registry ve arts.ve co.ve com.ve e12.ve edu.ve firm.ve gob.ve gov.ve info.ve int.ve mil.ve net.ve org.ve rec.ve store.ve tec.ve web.ve // vg : https://en.wikipedia.org/wiki/.vg vg // vi : http://www.nic.vi/newdomainform.htm // http://www.nic.vi/Domain_Rules/body_domain_rules.html indicates some other // TLDs are "reserved", such as edu.vi and gov.vi, but doesn't actually say they // are available for registration (which they do not seem to be). vi co.vi com.vi k12.vi net.vi org.vi // vn : https://www.dot.vn/vnnic/vnnic/domainregistration.jsp vn com.vn net.vn org.vn edu.vn gov.vn int.vn ac.vn biz.vn info.vn name.vn pro.vn health.vn // vu : https://en.wikipedia.org/wiki/.vu // http://www.vunic.vu/ vu com.vu edu.vu net.vu org.vu // wf : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf wf // ws : https://en.wikipedia.org/wiki/.ws // http://samoanic.ws/index.dhtml ws com.ws net.ws org.ws gov.ws edu.ws // yt : http://www.afnic.fr/medias/documents/AFNIC-naming-policy2012.pdf yt // IDN ccTLDs // When submitting patches, please maintain a sort by ISO 3166 ccTLD, then // U-label, and follow this format: // // A-Label ("", [, variant info]) : // // [sponsoring org] // U-Label // xn--mgbaam7a8h ("Emerat", Arabic) : AE // http://nic.ae/english/arabicdomain/rules.jsp xn--mgbaam7a8h // xn--y9a3aq ("hye", Armenian) : AM // ISOC AM (operated by .am Registry) xn--y9a3aq // xn--54b7fta0cc ("Bangla", Bangla) : BD xn--54b7fta0cc // xn--90ae ("bg", Bulgarian) : BG xn--90ae // xn--90ais ("bel", Belarusian/Russian Cyrillic) : BY // Operated by .by registry xn--90ais // xn--fiqs8s ("Zhongguo/China", Chinese, Simplified) : CN // CNNIC // http://cnnic.cn/html/Dir/2005/10/11/3218.htm xn--fiqs8s // xn--fiqz9s ("Zhongguo/China", Chinese, Traditional) : CN // CNNIC // http://cnnic.cn/html/Dir/2005/10/11/3218.htm xn--fiqz9s // xn--lgbbat1ad8j ("Algeria/Al Jazair", Arabic) : DZ xn--lgbbat1ad8j // xn--wgbh1c ("Egypt/Masr", Arabic) : EG // http://www.dotmasr.eg/ xn--wgbh1c // xn--e1a4c ("eu", Cyrillic) : EU xn--e1a4c // xn--node ("ge", Georgian Mkhedruli) : GE xn--node // xn--qxam ("el", Greek) : GR // Hellenic Ministry of Infrastructure, Transport, and Networks xn--qxam // xn--j6w193g ("Hong Kong", Chinese) : HK // https://www.hkirc.hk // Submitted by registry // https://www.hkirc.hk/content.jsp?id=30#!/34 xn--j6w193g xn--55qx5d.xn--j6w193g xn--wcvs22d.xn--j6w193g xn--mxtq1m.xn--j6w193g xn--gmqw5a.xn--j6w193g xn--od0alg.xn--j6w193g xn--uc0atv.xn--j6w193g // xn--2scrj9c ("Bharat", Kannada) : IN // India xn--2scrj9c // xn--3hcrj9c ("Bharat", Oriya) : IN // India xn--3hcrj9c // xn--45br5cyl ("Bharatam", Assamese) : IN // India xn--45br5cyl // xn--h2breg3eve ("Bharatam", Sanskrit) : IN // India xn--h2breg3eve // xn--h2brj9c8c ("Bharot", Santali) : IN // India xn--h2brj9c8c // xn--mgbgu82a ("Bharat", Sindhi) : IN // India xn--mgbgu82a // xn--rvc1e0am3e ("Bharatam", Malayalam) : IN // India xn--rvc1e0am3e // xn--h2brj9c ("Bharat", Devanagari) : IN // India xn--h2brj9c // xn--mgbbh1a ("Bharat", Kashmiri) : IN // India xn--mgbbh1a // xn--mgbbh1a71e ("Bharat", Arabic) : IN // India xn--mgbbh1a71e // xn--fpcrj9c3d ("Bharat", Telugu) : IN // India xn--fpcrj9c3d // xn--gecrj9c ("Bharat", Gujarati) : IN // India xn--gecrj9c // xn--s9brj9c ("Bharat", Gurmukhi) : IN // India xn--s9brj9c // xn--45brj9c ("Bharat", Bengali) : IN // India xn--45brj9c // xn--xkc2dl3a5ee0h ("India", Tamil) : IN // India xn--xkc2dl3a5ee0h // xn--mgba3a4f16a ("Iran", Persian) : IR xn--mgba3a4f16a // xn--mgba3a4fra ("Iran", Arabic) : IR xn--mgba3a4fra // xn--mgbtx2b ("Iraq", Arabic) : IQ // Communications and Media Commission xn--mgbtx2b // xn--mgbayh7gpa ("al-Ordon", Arabic) : JO // National Information Technology Center (NITC) // Royal Scientific Society, Al-Jubeiha xn--mgbayh7gpa // xn--3e0b707e ("Republic of Korea", Hangul) : KR xn--3e0b707e // xn--80ao21a ("Kaz", Kazakh) : KZ xn--80ao21a // xn--fzc2c9e2c ("Lanka", Sinhalese-Sinhala) : LK // http://nic.lk xn--fzc2c9e2c // xn--xkc2al3hye2a ("Ilangai", Tamil) : LK // http://nic.lk xn--xkc2al3hye2a // xn--mgbc0a9azcg ("Morocco/al-Maghrib", Arabic) : MA xn--mgbc0a9azcg // xn--d1alf ("mkd", Macedonian) : MK // MARnet xn--d1alf // xn--l1acc ("mon", Mongolian) : MN xn--l1acc // xn--mix891f ("Macao", Chinese, Traditional) : MO // MONIC / HNET Asia (Registry Operator for .mo) xn--mix891f // xn--mix082f ("Macao", Chinese, Simplified) : MO xn--mix082f // xn--mgbx4cd0ab ("Malaysia", Malay) : MY xn--mgbx4cd0ab // xn--mgb9awbf ("Oman", Arabic) : OM xn--mgb9awbf // xn--mgbai9azgqp6j ("Pakistan", Urdu/Arabic) : PK xn--mgbai9azgqp6j // xn--mgbai9a5eva00b ("Pakistan", Urdu/Arabic, variant) : PK xn--mgbai9a5eva00b // xn--ygbi2ammx ("Falasteen", Arabic) : PS // The Palestinian National Internet Naming Authority (PNINA) // http://www.pnina.ps xn--ygbi2ammx // xn--90a3ac ("srb", Cyrillic) : RS // https://www.rnids.rs/en/domains/national-domains xn--90a3ac xn--o1ac.xn--90a3ac xn--c1avg.xn--90a3ac xn--90azh.xn--90a3ac xn--d1at.xn--90a3ac xn--o1ach.xn--90a3ac xn--80au.xn--90a3ac // xn--p1ai ("rf", Russian-Cyrillic) : RU // http://www.cctld.ru/en/docs/rulesrf.php xn--p1ai // xn--wgbl6a ("Qatar", Arabic) : QA // http://www.ict.gov.qa/ xn--wgbl6a // xn--mgberp4a5d4ar ("AlSaudiah", Arabic) : SA // http://www.nic.net.sa/ xn--mgberp4a5d4ar // xn--mgberp4a5d4a87g ("AlSaudiah", Arabic, variant) : SA xn--mgberp4a5d4a87g // xn--mgbqly7c0a67fbc ("AlSaudiah", Arabic, variant) : SA xn--mgbqly7c0a67fbc // xn--mgbqly7cvafr ("AlSaudiah", Arabic, variant) : SA xn--mgbqly7cvafr // xn--mgbpl2fh ("sudan", Arabic) : SD // Operated by .sd registry xn--mgbpl2fh // xn--yfro4i67o Singapore ("Singapore", Chinese) : SG xn--yfro4i67o // xn--clchc0ea0b2g2a9gcd ("Singapore", Tamil) : SG xn--clchc0ea0b2g2a9gcd // xn--ogbpf8fl ("Syria", Arabic) : SY xn--ogbpf8fl // xn--mgbtf8fl ("Syria", Arabic, variant) : SY xn--mgbtf8fl // xn--o3cw4h ("Thai", Thai) : TH // http://www.thnic.co.th xn--o3cw4h xn--12c1fe0br.xn--o3cw4h xn--12co0c3b4eva.xn--o3cw4h xn--h3cuzk1di.xn--o3cw4h xn--o3cyx2a.xn--o3cw4h xn--m3ch0j3a.xn--o3cw4h xn--12cfi8ixb8l.xn--o3cw4h // xn--pgbs0dh ("Tunisia", Arabic) : TN // http://nic.tn xn--pgbs0dh // xn--kpry57d ("Taiwan", Chinese, Traditional) : TW // http://www.twnic.net/english/dn/dn_07a.htm xn--kpry57d // xn--kprw13d ("Taiwan", Chinese, Simplified) : TW // http://www.twnic.net/english/dn/dn_07a.htm xn--kprw13d // xn--nnx388a ("Taiwan", Chinese, variant) : TW xn--nnx388a // xn--j1amh ("ukr", Cyrillic) : UA xn--j1amh // xn--mgb2ddes ("AlYemen", Arabic) : YE xn--mgb2ddes // xxx : http://icmregistry.com xxx // ye : http://www.y.net.ye/services/domain_name.htm *.ye // za : http://www.zadna.org.za/content/page/domain-information ac.za agric.za alt.za co.za edu.za gov.za grondar.za law.za mil.za net.za ngo.za nis.za nom.za org.za school.za tm.za web.za // zm : https://zicta.zm/ // Submitted by registry zm ac.zm biz.zm co.zm com.zm edu.zm gov.zm info.zm mil.zm net.zm org.zm sch.zm // zw : https://www.potraz.gov.zw/ // Confirmed by registry 2017-01-25 zw ac.zw co.zw gov.zw mil.zw org.zw // newGTLDs // List of new gTLDs imported from https://newgtlds.icann.org/newgtlds.csv on 2018-05-08T19:40:37Z // This list is auto-generated, don't edit it manually. // aaa : 2015-02-26 American Automobile Association, Inc. aaa // aarp : 2015-05-21 AARP aarp // abarth : 2015-07-30 Fiat Chrysler Automobiles N.V. abarth // abb : 2014-10-24 ABB Ltd abb // abbott : 2014-07-24 Abbott Laboratories, Inc. abbott // abbvie : 2015-07-30 AbbVie Inc. abbvie // abc : 2015-07-30 Disney Enterprises, Inc. abc // able : 2015-06-25 Able Inc. able // abogado : 2014-04-24 Minds + Machines Group Limited abogado // abudhabi : 2015-07-30 Abu Dhabi Systems and Information Centre abudhabi // academy : 2013-11-07 Binky Moon, LLC academy // accenture : 2014-08-15 Accenture plc accenture // accountant : 2014-11-20 dot Accountant Limited accountant // accountants : 2014-03-20 Binky Moon, LLC accountants // aco : 2015-01-08 ACO Severin Ahlmann GmbH & Co. KG aco // active : 2014-05-01 Active Network, LLC active // actor : 2013-12-12 United TLD Holdco Ltd. actor // adac : 2015-07-16 Allgemeiner Deutscher Automobil-Club e.V. (ADAC) adac // ads : 2014-12-04 Charleston Road Registry Inc. ads // adult : 2014-10-16 ICM Registry AD LLC adult // aeg : 2015-03-19 Aktiebolaget Electrolux aeg // aetna : 2015-05-21 Aetna Life Insurance Company aetna // afamilycompany : 2015-07-23 Johnson Shareholdings, Inc. afamilycompany // afl : 2014-10-02 Australian Football League afl // africa : 2014-03-24 ZA Central Registry NPC trading as Registry.Africa africa // agakhan : 2015-04-23 Fondation Aga Khan (Aga Khan Foundation) agakhan // agency : 2013-11-14 Binky Moon, LLC agency // aig : 2014-12-18 American International Group, Inc. aig // aigo : 2015-08-06 aigo Digital Technology Co,Ltd. aigo // airbus : 2015-07-30 Airbus S.A.S. airbus // airforce : 2014-03-06 United TLD Holdco Ltd. airforce // airtel : 2014-10-24 Bharti Airtel Limited airtel // akdn : 2015-04-23 Fondation Aga Khan (Aga Khan Foundation) akdn // alfaromeo : 2015-07-31 Fiat Chrysler Automobiles N.V. alfaromeo // alibaba : 2015-01-15 Alibaba Group Holding Limited alibaba // alipay : 2015-01-15 Alibaba Group Holding Limited alipay // allfinanz : 2014-07-03 Allfinanz Deutsche Vermögensberatung Aktiengesellschaft allfinanz // allstate : 2015-07-31 Allstate Fire and Casualty Insurance Company allstate // ally : 2015-06-18 Ally Financial Inc. ally // alsace : 2014-07-02 Region Grand Est alsace // alstom : 2015-07-30 ALSTOM alstom // americanexpress : 2015-07-31 American Express Travel Related Services Company, Inc. americanexpress // americanfamily : 2015-07-23 AmFam, Inc. americanfamily // amex : 2015-07-31 American Express Travel Related Services Company, Inc. amex // amfam : 2015-07-23 AmFam, Inc. amfam // amica : 2015-05-28 Amica Mutual Insurance Company amica // amsterdam : 2014-07-24 Gemeente Amsterdam amsterdam // analytics : 2014-12-18 Campus IP LLC analytics // android : 2014-08-07 Charleston Road Registry Inc. android // anquan : 2015-01-08 QIHOO 360 TECHNOLOGY CO. LTD. anquan // anz : 2015-07-31 Australia and New Zealand Banking Group Limited anz // aol : 2015-09-17 Oath Inc. aol // apartments : 2014-12-11 Binky Moon, LLC apartments // app : 2015-05-14 Charleston Road Registry Inc. app // apple : 2015-05-14 Apple Inc. apple // aquarelle : 2014-07-24 Aquarelle.com aquarelle // arab : 2015-11-12 League of Arab States arab // aramco : 2014-11-20 Aramco Services Company aramco // archi : 2014-02-06 Afilias plc archi // army : 2014-03-06 United TLD Holdco Ltd. army // art : 2016-03-24 UK Creative Ideas Limited art // arte : 2014-12-11 Association Relative à la Télévision Européenne G.E.I.E. arte // asda : 2015-07-31 Wal-Mart Stores, Inc. asda // associates : 2014-03-06 Binky Moon, LLC associates // athleta : 2015-07-30 The Gap, Inc. athleta // attorney : 2014-03-20 United TLD Holdco Ltd. attorney // auction : 2014-03-20 United TLD Holdco Ltd. auction // audi : 2015-05-21 AUDI Aktiengesellschaft audi // audible : 2015-06-25 Amazon Registry Services, Inc. audible // audio : 2014-03-20 Uniregistry, Corp. audio // auspost : 2015-08-13 Australian Postal Corporation auspost // author : 2014-12-18 Amazon Registry Services, Inc. author // auto : 2014-11-13 Cars Registry Limited auto // autos : 2014-01-09 DERAutos, LLC autos // avianca : 2015-01-08 Aerovias del Continente Americano S.A. Avianca avianca // aws : 2015-06-25 Amazon Registry Services, Inc. aws // axa : 2013-12-19 AXA SA axa // azure : 2014-12-18 Microsoft Corporation azure // baby : 2015-04-09 Johnson & Johnson Services, Inc. baby // baidu : 2015-01-08 Baidu, Inc. baidu // banamex : 2015-07-30 Citigroup Inc. banamex // bananarepublic : 2015-07-31 The Gap, Inc. bananarepublic // band : 2014-06-12 United TLD Holdco Ltd. band // bank : 2014-09-25 fTLD Registry Services LLC bank // bar : 2013-12-12 Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable bar // barcelona : 2014-07-24 Municipi de Barcelona barcelona // barclaycard : 2014-11-20 Barclays Bank PLC barclaycard // barclays : 2014-11-20 Barclays Bank PLC barclays // barefoot : 2015-06-11 Gallo Vineyards, Inc. barefoot // bargains : 2013-11-14 Binky Moon, LLC bargains // baseball : 2015-10-29 MLB Advanced Media DH, LLC baseball // basketball : 2015-08-20 Fédération Internationale de Basketball (FIBA) basketball // bauhaus : 2014-04-17 Werkhaus GmbH bauhaus // bayern : 2014-01-23 Bayern Connect GmbH bayern // bbc : 2014-12-18 British Broadcasting Corporation bbc // bbt : 2015-07-23 BB&T Corporation bbt // bbva : 2014-10-02 BANCO BILBAO VIZCAYA ARGENTARIA, S.A. bbva // bcg : 2015-04-02 The Boston Consulting Group, Inc. bcg // bcn : 2014-07-24 Municipi de Barcelona bcn // beats : 2015-05-14 Beats Electronics, LLC beats // beauty : 2015-12-03 L'Oréal beauty // beer : 2014-01-09 Minds + Machines Group Limited beer // bentley : 2014-12-18 Bentley Motors Limited bentley // berlin : 2013-10-31 dotBERLIN GmbH & Co. KG berlin // best : 2013-12-19 BestTLD Pty Ltd best // bestbuy : 2015-07-31 BBY Solutions, Inc. bestbuy // bet : 2015-05-07 Afilias plc bet // bharti : 2014-01-09 Bharti Enterprises (Holding) Private Limited bharti // bible : 2014-06-19 American Bible Society bible // bid : 2013-12-19 dot Bid Limited bid // bike : 2013-08-27 Binky Moon, LLC bike // bing : 2014-12-18 Microsoft Corporation bing // bingo : 2014-12-04 Binky Moon, LLC bingo // bio : 2014-03-06 Afilias plc bio // black : 2014-01-16 Afilias plc black // blackfriday : 2014-01-16 Uniregistry, Corp. blackfriday // blockbuster : 2015-07-30 Dish DBS Corporation blockbuster // blog : 2015-05-14 Knock Knock WHOIS There, LLC blog // bloomberg : 2014-07-17 Bloomberg IP Holdings LLC bloomberg // blue : 2013-11-07 Afilias plc blue // bms : 2014-10-30 Bristol-Myers Squibb Company bms // bmw : 2014-01-09 Bayerische Motoren Werke Aktiengesellschaft bmw // bnl : 2014-07-24 Banca Nazionale del Lavoro bnl // bnpparibas : 2014-05-29 BNP Paribas bnpparibas // boats : 2014-12-04 DERBoats, LLC boats // boehringer : 2015-07-09 Boehringer Ingelheim International GmbH boehringer // bofa : 2015-07-31 Bank of America Corporation bofa // bom : 2014-10-16 Núcleo de Informação e Coordenação do Ponto BR - NIC.br bom // bond : 2014-06-05 Bond University Limited bond // boo : 2014-01-30 Charleston Road Registry Inc. boo // book : 2015-08-27 Amazon Registry Services, Inc. book // booking : 2015-07-16 Booking.com B.V. booking // bosch : 2015-06-18 Robert Bosch GMBH bosch // bostik : 2015-05-28 Bostik SA bostik // boston : 2015-12-10 Boston TLD Management, LLC boston // bot : 2014-12-18 Amazon Registry Services, Inc. bot // boutique : 2013-11-14 Binky Moon, LLC boutique // box : 2015-11-12 NS1 Limited box // bradesco : 2014-12-18 Banco Bradesco S.A. bradesco // bridgestone : 2014-12-18 Bridgestone Corporation bridgestone // broadway : 2014-12-22 Celebrate Broadway, Inc. broadway // broker : 2014-12-11 Dotbroker Registry Limited broker // brother : 2015-01-29 Brother Industries, Ltd. brother // brussels : 2014-02-06 DNS.be vzw brussels // budapest : 2013-11-21 Minds + Machines Group Limited budapest // bugatti : 2015-07-23 Bugatti International SA bugatti // build : 2013-11-07 Plan Bee LLC build // builders : 2013-11-07 Binky Moon, LLC builders // business : 2013-11-07 Binky Moon, LLC business // buy : 2014-12-18 Amazon Registry Services, Inc. buy // buzz : 2013-10-02 DOTSTRATEGY CO. buzz // bzh : 2014-02-27 Association www.bzh bzh // cab : 2013-10-24 Binky Moon, LLC cab // cafe : 2015-02-11 Binky Moon, LLC cafe // cal : 2014-07-24 Charleston Road Registry Inc. cal // call : 2014-12-18 Amazon Registry Services, Inc. call // calvinklein : 2015-07-30 PVH gTLD Holdings LLC calvinklein // cam : 2016-04-21 AC Webconnecting Holding B.V. cam // camera : 2013-08-27 Binky Moon, LLC camera // camp : 2013-11-07 Binky Moon, LLC camp // cancerresearch : 2014-05-15 Australian Cancer Research Foundation cancerresearch // canon : 2014-09-12 Canon Inc. canon // capetown : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry capetown // capital : 2014-03-06 Binky Moon, LLC capital // capitalone : 2015-08-06 Capital One Financial Corporation capitalone // car : 2015-01-22 Cars Registry Limited car // caravan : 2013-12-12 Caravan International, Inc. caravan // cards : 2013-12-05 Binky Moon, LLC cards // care : 2014-03-06 Binky Moon, LLC care // career : 2013-10-09 dotCareer LLC career // careers : 2013-10-02 Binky Moon, LLC careers // cars : 2014-11-13 Cars Registry Limited cars // cartier : 2014-06-23 Richemont DNS Inc. cartier // casa : 2013-11-21 Minds + Machines Group Limited casa // case : 2015-09-03 CNH Industrial N.V. case // caseih : 2015-09-03 CNH Industrial N.V. caseih // cash : 2014-03-06 Binky Moon, LLC cash // casino : 2014-12-18 Binky Moon, LLC casino // catering : 2013-12-05 Binky Moon, LLC catering // catholic : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) catholic // cba : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA cba // cbn : 2014-08-22 The Christian Broadcasting Network, Inc. cbn // cbre : 2015-07-02 CBRE, Inc. cbre // cbs : 2015-08-06 CBS Domains Inc. cbs // ceb : 2015-04-09 The Corporate Executive Board Company ceb // center : 2013-11-07 Binky Moon, LLC center // ceo : 2013-11-07 CEOTLD Pty Ltd ceo // cern : 2014-06-05 European Organization for Nuclear Research ("CERN") cern // cfa : 2014-08-28 CFA Institute cfa // cfd : 2014-12-11 DotCFD Registry Limited cfd // chanel : 2015-04-09 Chanel International B.V. chanel // channel : 2014-05-08 Charleston Road Registry Inc. channel // charity : 2018-04-11 Corn Lake, LLC charity // chase : 2015-04-30 JPMorgan Chase Bank, National Association chase // chat : 2014-12-04 Binky Moon, LLC chat // cheap : 2013-11-14 Binky Moon, LLC cheap // chintai : 2015-06-11 CHINTAI Corporation chintai // christmas : 2013-11-21 Uniregistry, Corp. christmas // chrome : 2014-07-24 Charleston Road Registry Inc. chrome // chrysler : 2015-07-30 FCA US LLC. chrysler // church : 2014-02-06 Binky Moon, LLC church // cipriani : 2015-02-19 Hotel Cipriani Srl cipriani // circle : 2014-12-18 Amazon Registry Services, Inc. circle // cisco : 2014-12-22 Cisco Technology, Inc. cisco // citadel : 2015-07-23 Citadel Domain LLC citadel // citi : 2015-07-30 Citigroup Inc. citi // citic : 2014-01-09 CITIC Group Corporation citic // city : 2014-05-29 Binky Moon, LLC city // cityeats : 2014-12-11 Lifestyle Domain Holdings, Inc. cityeats // claims : 2014-03-20 Binky Moon, LLC claims // cleaning : 2013-12-05 Binky Moon, LLC cleaning // click : 2014-06-05 Uniregistry, Corp. click // clinic : 2014-03-20 Binky Moon, LLC clinic // clinique : 2015-10-01 The Estée Lauder Companies Inc. clinique // clothing : 2013-08-27 Binky Moon, LLC clothing // cloud : 2015-04-16 Aruba PEC S.p.A. cloud // club : 2013-11-08 .CLUB DOMAINS, LLC club // clubmed : 2015-06-25 Club Méditerranée S.A. clubmed // coach : 2014-10-09 Binky Moon, LLC coach // codes : 2013-10-31 Binky Moon, LLC codes // coffee : 2013-10-17 Binky Moon, LLC coffee // college : 2014-01-16 XYZ.COM LLC college // cologne : 2014-02-05 punkt.wien GmbH cologne // comcast : 2015-07-23 Comcast IP Holdings I, LLC comcast // commbank : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA commbank // community : 2013-12-05 Binky Moon, LLC community // company : 2013-11-07 Binky Moon, LLC company // compare : 2015-10-08 iSelect Ltd compare // computer : 2013-10-24 Binky Moon, LLC computer // comsec : 2015-01-08 VeriSign, Inc. comsec // condos : 2013-12-05 Binky Moon, LLC condos // construction : 2013-09-16 Binky Moon, LLC construction // consulting : 2013-12-05 United TLD Holdco Ltd. consulting // contact : 2015-01-08 Top Level Spectrum, Inc. contact // contractors : 2013-09-10 Binky Moon, LLC contractors // cooking : 2013-11-21 Minds + Machines Group Limited cooking // cookingchannel : 2015-07-02 Lifestyle Domain Holdings, Inc. cookingchannel // cool : 2013-11-14 Binky Moon, LLC cool // corsica : 2014-09-25 Collectivité de Corse corsica // country : 2013-12-19 DotCountry LLC country // coupon : 2015-02-26 Amazon Registry Services, Inc. coupon // coupons : 2015-03-26 Binky Moon, LLC coupons // courses : 2014-12-04 OPEN UNIVERSITIES AUSTRALIA PTY LTD courses // credit : 2014-03-20 Binky Moon, LLC credit // creditcard : 2014-03-20 Binky Moon, LLC creditcard // creditunion : 2015-01-22 CUNA Performance Resources, LLC creditunion // cricket : 2014-10-09 dot Cricket Limited cricket // crown : 2014-10-24 Crown Equipment Corporation crown // crs : 2014-04-03 Federated Co-operatives Limited crs // cruise : 2015-12-10 Viking River Cruises (Bermuda) Ltd. cruise // cruises : 2013-12-05 Binky Moon, LLC cruises // csc : 2014-09-25 Alliance-One Services, Inc. csc // cuisinella : 2014-04-03 SALM S.A.S. cuisinella // cymru : 2014-05-08 Nominet UK cymru // cyou : 2015-01-22 Beijing Gamease Age Digital Technology Co., Ltd. cyou // dabur : 2014-02-06 Dabur India Limited dabur // dad : 2014-01-23 Charleston Road Registry Inc. dad // dance : 2013-10-24 United TLD Holdco Ltd. dance // data : 2016-06-02 Dish DBS Corporation data // date : 2014-11-20 dot Date Limited date // dating : 2013-12-05 Binky Moon, LLC dating // datsun : 2014-03-27 NISSAN MOTOR CO., LTD. datsun // day : 2014-01-30 Charleston Road Registry Inc. day // dclk : 2014-11-20 Charleston Road Registry Inc. dclk // dds : 2015-05-07 Minds + Machines Group Limited dds // deal : 2015-06-25 Amazon Registry Services, Inc. deal // dealer : 2014-12-22 Dealer Dot Com, Inc. dealer // deals : 2014-05-22 Binky Moon, LLC deals // degree : 2014-03-06 United TLD Holdco Ltd. degree // delivery : 2014-09-11 Binky Moon, LLC delivery // dell : 2014-10-24 Dell Inc. dell // deloitte : 2015-07-31 Deloitte Touche Tohmatsu deloitte // delta : 2015-02-19 Delta Air Lines, Inc. delta // democrat : 2013-10-24 United TLD Holdco Ltd. democrat // dental : 2014-03-20 Binky Moon, LLC dental // dentist : 2014-03-20 United TLD Holdco Ltd. dentist // desi : 2013-11-14 Desi Networks LLC desi // design : 2014-11-07 Top Level Design, LLC design // dev : 2014-10-16 Charleston Road Registry Inc. dev // dhl : 2015-07-23 Deutsche Post AG dhl // diamonds : 2013-09-22 Binky Moon, LLC diamonds // diet : 2014-06-26 Uniregistry, Corp. diet // digital : 2014-03-06 Binky Moon, LLC digital // direct : 2014-04-10 Binky Moon, LLC direct // directory : 2013-09-20 Binky Moon, LLC directory // discount : 2014-03-06 Binky Moon, LLC discount // discover : 2015-07-23 Discover Financial Services discover // dish : 2015-07-30 Dish DBS Corporation dish // diy : 2015-11-05 Lifestyle Domain Holdings, Inc. diy // dnp : 2013-12-13 Dai Nippon Printing Co., Ltd. dnp // docs : 2014-10-16 Charleston Road Registry Inc. docs // doctor : 2016-06-02 Binky Moon, LLC doctor // dodge : 2015-07-30 FCA US LLC. dodge // dog : 2014-12-04 Binky Moon, LLC dog // doha : 2014-09-18 Communications Regulatory Authority (CRA) doha // domains : 2013-10-17 Binky Moon, LLC domains // dot : 2015-05-21 Dish DBS Corporation dot // download : 2014-11-20 dot Support Limited download // drive : 2015-03-05 Charleston Road Registry Inc. drive // dtv : 2015-06-04 Dish DBS Corporation dtv // dubai : 2015-01-01 Dubai Smart Government Department dubai // duck : 2015-07-23 Johnson Shareholdings, Inc. duck // dunlop : 2015-07-02 The Goodyear Tire & Rubber Company dunlop // duns : 2015-08-06 The Dun & Bradstreet Corporation duns // dupont : 2015-06-25 E. I. du Pont de Nemours and Company dupont // durban : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry durban // dvag : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG dvag // dvr : 2016-05-26 Hughes Satellite Systems Corporation dvr // earth : 2014-12-04 Interlink Co., Ltd. earth // eat : 2014-01-23 Charleston Road Registry Inc. eat // eco : 2016-07-08 Big Room Inc. eco // edeka : 2014-12-18 EDEKA Verband kaufmännischer Genossenschaften e.V. edeka // education : 2013-11-07 Binky Moon, LLC education // email : 2013-10-31 Binky Moon, LLC email // emerck : 2014-04-03 Merck KGaA emerck // energy : 2014-09-11 Binky Moon, LLC energy // engineer : 2014-03-06 United TLD Holdco Ltd. engineer // engineering : 2014-03-06 Binky Moon, LLC engineering // enterprises : 2013-09-20 Binky Moon, LLC enterprises // epson : 2014-12-04 Seiko Epson Corporation epson // equipment : 2013-08-27 Binky Moon, LLC equipment // ericsson : 2015-07-09 Telefonaktiebolaget L M Ericsson ericsson // erni : 2014-04-03 ERNI Group Holding AG erni // esq : 2014-05-08 Charleston Road Registry Inc. esq // estate : 2013-08-27 Binky Moon, LLC estate // esurance : 2015-07-23 Esurance Insurance Company esurance // etisalat : 2015-09-03 Emirates Telecommunications Corporation (trading as Etisalat) etisalat // eurovision : 2014-04-24 European Broadcasting Union (EBU) eurovision // eus : 2013-12-12 Puntueus Fundazioa eus // events : 2013-12-05 Binky Moon, LLC events // everbank : 2014-05-15 EverBank everbank // exchange : 2014-03-06 Binky Moon, LLC exchange // expert : 2013-11-21 Binky Moon, LLC expert // exposed : 2013-12-05 Binky Moon, LLC exposed // express : 2015-02-11 Binky Moon, LLC express // extraspace : 2015-05-14 Extra Space Storage LLC extraspace // fage : 2014-12-18 Fage International S.A. fage // fail : 2014-03-06 Binky Moon, LLC fail // fairwinds : 2014-11-13 FairWinds Partners, LLC fairwinds // faith : 2014-11-20 dot Faith Limited faith // family : 2015-04-02 United TLD Holdco Ltd. family // fan : 2014-03-06 Asiamix Digital Limited fan // fans : 2014-11-07 Asiamix Digital Limited fans // farm : 2013-11-07 Binky Moon, LLC farm // farmers : 2015-07-09 Farmers Insurance Exchange farmers // fashion : 2014-07-03 Minds + Machines Group Limited fashion // fast : 2014-12-18 Amazon Registry Services, Inc. fast // fedex : 2015-08-06 Federal Express Corporation fedex // feedback : 2013-12-19 Top Level Spectrum, Inc. feedback // ferrari : 2015-07-31 Fiat Chrysler Automobiles N.V. ferrari // ferrero : 2014-12-18 Ferrero Trading Lux S.A. ferrero // fiat : 2015-07-31 Fiat Chrysler Automobiles N.V. fiat // fidelity : 2015-07-30 Fidelity Brokerage Services LLC fidelity // fido : 2015-08-06 Rogers Communications Canada Inc. fido // film : 2015-01-08 Motion Picture Domain Registry Pty Ltd film // final : 2014-10-16 Núcleo de Informação e Coordenação do Ponto BR - NIC.br final // finance : 2014-03-20 Binky Moon, LLC finance // financial : 2014-03-06 Binky Moon, LLC financial // fire : 2015-06-25 Amazon Registry Services, Inc. fire // firestone : 2014-12-18 Bridgestone Licensing Services, Inc firestone // firmdale : 2014-03-27 Firmdale Holdings Limited firmdale // fish : 2013-12-12 Binky Moon, LLC fish // fishing : 2013-11-21 Minds + Machines Group Limited fishing // fit : 2014-11-07 Minds + Machines Group Limited fit // fitness : 2014-03-06 Binky Moon, LLC fitness // flickr : 2015-04-02 Yahoo! Domain Services Inc. flickr // flights : 2013-12-05 Binky Moon, LLC flights // flir : 2015-07-23 FLIR Systems, Inc. flir // florist : 2013-11-07 Binky Moon, LLC florist // flowers : 2014-10-09 Uniregistry, Corp. flowers // fly : 2014-05-08 Charleston Road Registry Inc. fly // foo : 2014-01-23 Charleston Road Registry Inc. foo // food : 2016-04-21 Lifestyle Domain Holdings, Inc. food // foodnetwork : 2015-07-02 Lifestyle Domain Holdings, Inc. foodnetwork // football : 2014-12-18 Binky Moon, LLC football // ford : 2014-11-13 Ford Motor Company ford // forex : 2014-12-11 Dotforex Registry Limited forex // forsale : 2014-05-22 United TLD Holdco Ltd. forsale // forum : 2015-04-02 Fegistry, LLC forum // foundation : 2013-12-05 Binky Moon, LLC foundation // fox : 2015-09-11 FOX Registry, LLC fox // free : 2015-12-10 Amazon Registry Services, Inc. free // fresenius : 2015-07-30 Fresenius Immobilien-Verwaltungs-GmbH fresenius // frl : 2014-05-15 FRLregistry B.V. frl // frogans : 2013-12-19 OP3FT frogans // frontdoor : 2015-07-02 Lifestyle Domain Holdings, Inc. frontdoor // frontier : 2015-02-05 Frontier Communications Corporation frontier // ftr : 2015-07-16 Frontier Communications Corporation ftr // fujitsu : 2015-07-30 Fujitsu Limited fujitsu // fujixerox : 2015-07-23 Xerox DNHC LLC fujixerox // fun : 2016-01-14 DotSpace Inc. fun // fund : 2014-03-20 Binky Moon, LLC fund // furniture : 2014-03-20 Binky Moon, LLC furniture // futbol : 2013-09-20 United TLD Holdco Ltd. futbol // fyi : 2015-04-02 Binky Moon, LLC fyi // gal : 2013-11-07 Asociación puntoGAL gal // gallery : 2013-09-13 Binky Moon, LLC gallery // gallo : 2015-06-11 Gallo Vineyards, Inc. gallo // gallup : 2015-02-19 Gallup, Inc. gallup // game : 2015-05-28 Uniregistry, Corp. game // games : 2015-05-28 United TLD Holdco Ltd. games // gap : 2015-07-31 The Gap, Inc. gap // garden : 2014-06-26 Minds + Machines Group Limited garden // gbiz : 2014-07-17 Charleston Road Registry Inc. gbiz // gdn : 2014-07-31 Joint Stock Company "Navigation-information systems" gdn // gea : 2014-12-04 GEA Group Aktiengesellschaft gea // gent : 2014-01-23 COMBELL NV gent // genting : 2015-03-12 Resorts World Inc Pte. Ltd. genting // george : 2015-07-31 Wal-Mart Stores, Inc. george // ggee : 2014-01-09 GMO Internet, Inc. ggee // gift : 2013-10-17 DotGift, LLC gift // gifts : 2014-07-03 Binky Moon, LLC gifts // gives : 2014-03-06 United TLD Holdco Ltd. gives // giving : 2014-11-13 Giving Limited giving // glade : 2015-07-23 Johnson Shareholdings, Inc. glade // glass : 2013-11-07 Binky Moon, LLC glass // gle : 2014-07-24 Charleston Road Registry Inc. gle // global : 2014-04-17 Dot Global Domain Registry Limited global // globo : 2013-12-19 Globo Comunicação e Participações S.A globo // gmail : 2014-05-01 Charleston Road Registry Inc. gmail // gmbh : 2016-01-29 Binky Moon, LLC gmbh // gmo : 2014-01-09 GMO Internet Pte. Ltd. gmo // gmx : 2014-04-24 1&1 Mail & Media GmbH gmx // godaddy : 2015-07-23 Go Daddy East, LLC godaddy // gold : 2015-01-22 Binky Moon, LLC gold // goldpoint : 2014-11-20 YODOBASHI CAMERA CO.,LTD. goldpoint // golf : 2014-12-18 Binky Moon, LLC golf // goo : 2014-12-18 NTT Resonant Inc. goo // goodyear : 2015-07-02 The Goodyear Tire & Rubber Company goodyear // goog : 2014-11-20 Charleston Road Registry Inc. goog // google : 2014-07-24 Charleston Road Registry Inc. google // gop : 2014-01-16 Republican State Leadership Committee, Inc. gop // got : 2014-12-18 Amazon Registry Services, Inc. got // grainger : 2015-05-07 Grainger Registry Services, LLC grainger // graphics : 2013-09-13 Binky Moon, LLC graphics // gratis : 2014-03-20 Binky Moon, LLC gratis // green : 2014-05-08 Afilias plc green // gripe : 2014-03-06 Binky Moon, LLC gripe // grocery : 2016-06-16 Wal-Mart Stores, Inc. grocery // group : 2014-08-15 Binky Moon, LLC group // guardian : 2015-07-30 The Guardian Life Insurance Company of America guardian // gucci : 2014-11-13 Guccio Gucci S.p.a. gucci // guge : 2014-08-28 Charleston Road Registry Inc. guge // guide : 2013-09-13 Binky Moon, LLC guide // guitars : 2013-11-14 Uniregistry, Corp. guitars // guru : 2013-08-27 Binky Moon, LLC guru // hair : 2015-12-03 L'Oréal hair // hamburg : 2014-02-20 Hamburg Top-Level-Domain GmbH hamburg // hangout : 2014-11-13 Charleston Road Registry Inc. hangout // haus : 2013-12-05 United TLD Holdco Ltd. haus // hbo : 2015-07-30 HBO Registry Services, Inc. hbo // hdfc : 2015-07-30 HOUSING DEVELOPMENT FINANCE CORPORATION LIMITED hdfc // hdfcbank : 2015-02-12 HDFC Bank Limited hdfcbank // health : 2015-02-11 DotHealth, LLC health // healthcare : 2014-06-12 Binky Moon, LLC healthcare // help : 2014-06-26 Uniregistry, Corp. help // helsinki : 2015-02-05 City of Helsinki helsinki // here : 2014-02-06 Charleston Road Registry Inc. here // hermes : 2014-07-10 HERMES INTERNATIONAL hermes // hgtv : 2015-07-02 Lifestyle Domain Holdings, Inc. hgtv // hiphop : 2014-03-06 Uniregistry, Corp. hiphop // hisamitsu : 2015-07-16 Hisamitsu Pharmaceutical Co.,Inc. hisamitsu // hitachi : 2014-10-31 Hitachi, Ltd. hitachi // hiv : 2014-03-13 Uniregistry, Corp. hiv // hkt : 2015-05-14 PCCW-HKT DataCom Services Limited hkt // hockey : 2015-03-19 Binky Moon, LLC hockey // holdings : 2013-08-27 Binky Moon, LLC holdings // holiday : 2013-11-07 Binky Moon, LLC holiday // homedepot : 2015-04-02 Home Depot Product Authority, LLC homedepot // homegoods : 2015-07-16 The TJX Companies, Inc. homegoods // homes : 2014-01-09 DERHomes, LLC homes // homesense : 2015-07-16 The TJX Companies, Inc. homesense // honda : 2014-12-18 Honda Motor Co., Ltd. honda // honeywell : 2015-07-23 Honeywell GTLD LLC honeywell // horse : 2013-11-21 Minds + Machines Group Limited horse // hospital : 2016-10-20 Binky Moon, LLC hospital // host : 2014-04-17 DotHost Inc. host // hosting : 2014-05-29 Uniregistry, Corp. hosting // hot : 2015-08-27 Amazon Registry Services, Inc. hot // hoteles : 2015-03-05 Travel Reservations SRL hoteles // hotels : 2016-04-07 Booking.com B.V. hotels // hotmail : 2014-12-18 Microsoft Corporation hotmail // house : 2013-11-07 Binky Moon, LLC house // how : 2014-01-23 Charleston Road Registry Inc. how // hsbc : 2014-10-24 HSBC Global Services (UK) Limited hsbc // hughes : 2015-07-30 Hughes Satellite Systems Corporation hughes // hyatt : 2015-07-30 Hyatt GTLD, L.L.C. hyatt // hyundai : 2015-07-09 Hyundai Motor Company hyundai // ibm : 2014-07-31 International Business Machines Corporation ibm // icbc : 2015-02-19 Industrial and Commercial Bank of China Limited icbc // ice : 2014-10-30 IntercontinentalExchange, Inc. ice // icu : 2015-01-08 ShortDot SA icu // ieee : 2015-07-23 IEEE Global LLC ieee // ifm : 2014-01-30 ifm electronic gmbh ifm // ikano : 2015-07-09 Ikano S.A. ikano // imamat : 2015-08-06 Fondation Aga Khan (Aga Khan Foundation) imamat // imdb : 2015-06-25 Amazon Registry Services, Inc. imdb // immo : 2014-07-10 Binky Moon, LLC immo // immobilien : 2013-11-07 United TLD Holdco Ltd. immobilien // inc : 2018-03-10 GTLD Limited inc // industries : 2013-12-05 Binky Moon, LLC industries // infiniti : 2014-03-27 NISSAN MOTOR CO., LTD. infiniti // ing : 2014-01-23 Charleston Road Registry Inc. ing // ink : 2013-12-05 Top Level Design, LLC ink // institute : 2013-11-07 Binky Moon, LLC institute // insurance : 2015-02-19 fTLD Registry Services LLC insurance // insure : 2014-03-20 Binky Moon, LLC insure // intel : 2015-08-06 Intel Corporation intel // international : 2013-11-07 Binky Moon, LLC international // intuit : 2015-07-30 Intuit Administrative Services, Inc. intuit // investments : 2014-03-20 Binky Moon, LLC investments // ipiranga : 2014-08-28 Ipiranga Produtos de Petroleo S.A. ipiranga // irish : 2014-08-07 Binky Moon, LLC irish // iselect : 2015-02-11 iSelect Ltd iselect // ismaili : 2015-08-06 Fondation Aga Khan (Aga Khan Foundation) ismaili // ist : 2014-08-28 Istanbul Metropolitan Municipality ist // istanbul : 2014-08-28 Istanbul Metropolitan Municipality istanbul // itau : 2014-10-02 Itau Unibanco Holding S.A. itau // itv : 2015-07-09 ITV Services Limited itv // iveco : 2015-09-03 CNH Industrial N.V. iveco // jaguar : 2014-11-13 Jaguar Land Rover Ltd jaguar // java : 2014-06-19 Oracle Corporation java // jcb : 2014-11-20 JCB Co., Ltd. jcb // jcp : 2015-04-23 JCP Media, Inc. jcp // jeep : 2015-07-30 FCA US LLC. jeep // jetzt : 2014-01-09 Binky Moon, LLC jetzt // jewelry : 2015-03-05 Binky Moon, LLC jewelry // jio : 2015-04-02 Reliance Industries Limited jio // jll : 2015-04-02 Jones Lang LaSalle Incorporated jll // jmp : 2015-03-26 Matrix IP LLC jmp // jnj : 2015-06-18 Johnson & Johnson Services, Inc. jnj // joburg : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry joburg // jot : 2014-12-18 Amazon Registry Services, Inc. jot // joy : 2014-12-18 Amazon Registry Services, Inc. joy // jpmorgan : 2015-04-30 JPMorgan Chase Bank, National Association jpmorgan // jprs : 2014-09-18 Japan Registry Services Co., Ltd. jprs // juegos : 2014-03-20 Uniregistry, Corp. juegos // juniper : 2015-07-30 JUNIPER NETWORKS, INC. juniper // kaufen : 2013-11-07 United TLD Holdco Ltd. kaufen // kddi : 2014-09-12 KDDI CORPORATION kddi // kerryhotels : 2015-04-30 Kerry Trading Co. Limited kerryhotels // kerrylogistics : 2015-04-09 Kerry Trading Co. Limited kerrylogistics // kerryproperties : 2015-04-09 Kerry Trading Co. Limited kerryproperties // kfh : 2014-12-04 Kuwait Finance House kfh // kia : 2015-07-09 KIA MOTORS CORPORATION kia // kim : 2013-09-23 Afilias plc kim // kinder : 2014-11-07 Ferrero Trading Lux S.A. kinder // kindle : 2015-06-25 Amazon Registry Services, Inc. kindle // kitchen : 2013-09-20 Binky Moon, LLC kitchen // kiwi : 2013-09-20 DOT KIWI LIMITED kiwi // koeln : 2014-01-09 punkt.wien GmbH koeln // komatsu : 2015-01-08 Komatsu Ltd. komatsu // kosher : 2015-08-20 Kosher Marketing Assets LLC kosher // kpmg : 2015-04-23 KPMG International Cooperative (KPMG International Genossenschaft) kpmg // kpn : 2015-01-08 Koninklijke KPN N.V. kpn // krd : 2013-12-05 KRG Department of Information Technology krd // kred : 2013-12-19 KredTLD Pty Ltd kred // kuokgroup : 2015-04-09 Kerry Trading Co. Limited kuokgroup // kyoto : 2014-11-07 Academic Institution: Kyoto Jyoho Gakuen kyoto // lacaixa : 2014-01-09 Fundación Bancaria Caixa d’Estalvis i Pensions de Barcelona, “la Caixa” lacaixa // ladbrokes : 2015-08-06 LADBROKES INTERNATIONAL PLC ladbrokes // lamborghini : 2015-06-04 Automobili Lamborghini S.p.A. lamborghini // lamer : 2015-10-01 The Estée Lauder Companies Inc. lamer // lancaster : 2015-02-12 LANCASTER lancaster // lancia : 2015-07-31 Fiat Chrysler Automobiles N.V. lancia // lancome : 2015-07-23 L'Oréal lancome // land : 2013-09-10 Binky Moon, LLC land // landrover : 2014-11-13 Jaguar Land Rover Ltd landrover // lanxess : 2015-07-30 LANXESS Corporation lanxess // lasalle : 2015-04-02 Jones Lang LaSalle Incorporated lasalle // lat : 2014-10-16 ECOM-LAC Federaciòn de Latinoamèrica y el Caribe para Internet y el Comercio Electrònico lat // latino : 2015-07-30 Dish DBS Corporation latino // latrobe : 2014-06-16 La Trobe University latrobe // law : 2015-01-22 Minds + Machines Group Limited law // lawyer : 2014-03-20 United TLD Holdco Ltd. lawyer // lds : 2014-03-20 IRI Domain Management, LLC ("Applicant") lds // lease : 2014-03-06 Binky Moon, LLC lease // leclerc : 2014-08-07 A.C.D. LEC Association des Centres Distributeurs Edouard Leclerc leclerc // lefrak : 2015-07-16 LeFrak Organization, Inc. lefrak // legal : 2014-10-16 Binky Moon, LLC legal // lego : 2015-07-16 LEGO Juris A/S lego // lexus : 2015-04-23 TOYOTA MOTOR CORPORATION lexus // lgbt : 2014-05-08 Afilias plc lgbt // liaison : 2014-10-02 Liaison Technologies, Incorporated liaison // lidl : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG lidl // life : 2014-02-06 Binky Moon, LLC life // lifeinsurance : 2015-01-15 American Council of Life Insurers lifeinsurance // lifestyle : 2014-12-11 Lifestyle Domain Holdings, Inc. lifestyle // lighting : 2013-08-27 Binky Moon, LLC lighting // like : 2014-12-18 Amazon Registry Services, Inc. like // lilly : 2015-07-31 Eli Lilly and Company lilly // limited : 2014-03-06 Binky Moon, LLC limited // limo : 2013-10-17 Binky Moon, LLC limo // lincoln : 2014-11-13 Ford Motor Company lincoln // linde : 2014-12-04 Linde Aktiengesellschaft linde // link : 2013-11-14 Uniregistry, Corp. link // lipsy : 2015-06-25 Lipsy Ltd lipsy // live : 2014-12-04 United TLD Holdco Ltd. live // living : 2015-07-30 Lifestyle Domain Holdings, Inc. living // lixil : 2015-03-19 LIXIL Group Corporation lixil // llc : 2017-12-14 Afilias plc llc // loan : 2014-11-20 dot Loan Limited loan // loans : 2014-03-20 Binky Moon, LLC loans // locker : 2015-06-04 Dish DBS Corporation locker // locus : 2015-06-25 Locus Analytics LLC locus // loft : 2015-07-30 Annco, Inc. loft // lol : 2015-01-30 Uniregistry, Corp. lol // london : 2013-11-14 Dot London Domains Limited london // lotte : 2014-11-07 Lotte Holdings Co., Ltd. lotte // lotto : 2014-04-10 Afilias plc lotto // love : 2014-12-22 Merchant Law Group LLP love // lpl : 2015-07-30 LPL Holdings, Inc. lpl // lplfinancial : 2015-07-30 LPL Holdings, Inc. lplfinancial // ltd : 2014-09-25 Binky Moon, LLC ltd // ltda : 2014-04-17 InterNetX, Corp ltda // lundbeck : 2015-08-06 H. Lundbeck A/S lundbeck // lupin : 2014-11-07 LUPIN LIMITED lupin // luxe : 2014-01-09 Minds + Machines Group Limited luxe // luxury : 2013-10-17 Luxury Partners, LLC luxury // macys : 2015-07-31 Macys, Inc. macys // madrid : 2014-05-01 Comunidad de Madrid madrid // maif : 2014-10-02 Mutuelle Assurance Instituteur France (MAIF) maif // maison : 2013-12-05 Binky Moon, LLC maison // makeup : 2015-01-15 L'Oréal makeup // man : 2014-12-04 MAN SE man // management : 2013-11-07 Binky Moon, LLC management // mango : 2013-10-24 PUNTO FA S.L. mango // map : 2016-06-09 Charleston Road Registry Inc. map // market : 2014-03-06 United TLD Holdco Ltd. market // marketing : 2013-11-07 Binky Moon, LLC marketing // markets : 2014-12-11 Dotmarkets Registry Limited markets // marriott : 2014-10-09 Marriott Worldwide Corporation marriott // marshalls : 2015-07-16 The TJX Companies, Inc. marshalls // maserati : 2015-07-31 Fiat Chrysler Automobiles N.V. maserati // mattel : 2015-08-06 Mattel Sites, Inc. mattel // mba : 2015-04-02 Binky Moon, LLC mba // mckinsey : 2015-07-31 McKinsey Holdings, Inc. mckinsey // med : 2015-08-06 Medistry LLC med // media : 2014-03-06 Binky Moon, LLC media // meet : 2014-01-16 Charleston Road Registry Inc. meet // melbourne : 2014-05-29 The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation melbourne // meme : 2014-01-30 Charleston Road Registry Inc. meme // memorial : 2014-10-16 Dog Beach, LLC memorial // men : 2015-02-26 Exclusive Registry Limited men // menu : 2013-09-11 Wedding TLD2, LLC menu // merckmsd : 2016-07-14 MSD Registry Holdings, Inc. merckmsd // metlife : 2015-05-07 MetLife Services and Solutions, LLC metlife // miami : 2013-12-19 Minds + Machines Group Limited miami // microsoft : 2014-12-18 Microsoft Corporation microsoft // mini : 2014-01-09 Bayerische Motoren Werke Aktiengesellschaft mini // mint : 2015-07-30 Intuit Administrative Services, Inc. mint // mit : 2015-07-02 Massachusetts Institute of Technology mit // mitsubishi : 2015-07-23 Mitsubishi Corporation mitsubishi // mlb : 2015-05-21 MLB Advanced Media DH, LLC mlb // mls : 2015-04-23 The Canadian Real Estate Association mls // mma : 2014-11-07 MMA IARD mma // mobile : 2016-06-02 Dish DBS Corporation mobile // mobily : 2014-12-18 GreenTech Consultancy Company W.L.L. mobily // moda : 2013-11-07 United TLD Holdco Ltd. moda // moe : 2013-11-13 Interlink Co., Ltd. moe // moi : 2014-12-18 Amazon Registry Services, Inc. moi // mom : 2015-04-16 Uniregistry, Corp. mom // monash : 2013-09-30 Monash University monash // money : 2014-10-16 Binky Moon, LLC money // monster : 2015-09-11 Monster Worldwide, Inc. monster // mopar : 2015-07-30 FCA US LLC. mopar // mormon : 2013-12-05 IRI Domain Management, LLC ("Applicant") mormon // mortgage : 2014-03-20 United TLD Holdco Ltd. mortgage // moscow : 2013-12-19 Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) moscow // moto : 2015-06-04 Motorola Trademark Holdings, LLC moto // motorcycles : 2014-01-09 DERMotorcycles, LLC motorcycles // mov : 2014-01-30 Charleston Road Registry Inc. mov // movie : 2015-02-05 Binky Moon, LLC movie // movistar : 2014-10-16 Telefónica S.A. movistar // msd : 2015-07-23 MSD Registry Holdings, Inc. msd // mtn : 2014-12-04 MTN Dubai Limited mtn // mtr : 2015-03-12 MTR Corporation Limited mtr // mutual : 2015-04-02 Northwestern Mutual MU TLD Registry, LLC mutual // nab : 2015-08-20 National Australia Bank Limited nab // nadex : 2014-12-11 Nadex Domains, Inc. nadex // nagoya : 2013-10-24 GMO Registry, Inc. nagoya // nationwide : 2015-07-23 Nationwide Mutual Insurance Company nationwide // natura : 2015-03-12 NATURA COSMÉTICOS S.A. natura // navy : 2014-03-06 United TLD Holdco Ltd. navy // nba : 2015-07-31 NBA REGISTRY, LLC nba // nec : 2015-01-08 NEC Corporation nec // netbank : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA netbank // netflix : 2015-06-18 Netflix, Inc. netflix // network : 2013-11-14 Binky Moon, LLC network // neustar : 2013-12-05 Registry Services, LLC neustar // new : 2014-01-30 Charleston Road Registry Inc. new // newholland : 2015-09-03 CNH Industrial N.V. newholland // news : 2014-12-18 United TLD Holdco Ltd. news // next : 2015-06-18 Next plc next // nextdirect : 2015-06-18 Next plc nextdirect // nexus : 2014-07-24 Charleston Road Registry Inc. nexus // nfl : 2015-07-23 NFL Reg Ops LLC nfl // ngo : 2014-03-06 Public Interest Registry ngo // nhk : 2014-02-13 Japan Broadcasting Corporation (NHK) nhk // nico : 2014-12-04 DWANGO Co., Ltd. nico // nike : 2015-07-23 NIKE, Inc. nike // nikon : 2015-05-21 NIKON CORPORATION nikon // ninja : 2013-11-07 United TLD Holdco Ltd. ninja // nissan : 2014-03-27 NISSAN MOTOR CO., LTD. nissan // nissay : 2015-10-29 Nippon Life Insurance Company nissay // nokia : 2015-01-08 Nokia Corporation nokia // northwesternmutual : 2015-06-18 Northwestern Mutual Registry, LLC northwesternmutual // norton : 2014-12-04 Symantec Corporation norton // now : 2015-06-25 Amazon Registry Services, Inc. now // nowruz : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. nowruz // nowtv : 2015-05-14 Starbucks (HK) Limited nowtv // nra : 2014-05-22 NRA Holdings Company, INC. nra // nrw : 2013-11-21 Minds + Machines GmbH nrw // ntt : 2014-10-31 NIPPON TELEGRAPH AND TELEPHONE CORPORATION ntt // nyc : 2014-01-23 The City of New York by and through the New York City Department of Information Technology & Telecommunications nyc // obi : 2014-09-25 OBI Group Holding SE & Co. KGaA obi // observer : 2015-04-30 Top Level Spectrum, Inc. observer // off : 2015-07-23 Johnson Shareholdings, Inc. off // office : 2015-03-12 Microsoft Corporation office // okinawa : 2013-12-05 BRregistry, Inc. okinawa // olayan : 2015-05-14 Crescent Holding GmbH olayan // olayangroup : 2015-05-14 Crescent Holding GmbH olayangroup // oldnavy : 2015-07-31 The Gap, Inc. oldnavy // ollo : 2015-06-04 Dish DBS Corporation ollo // omega : 2015-01-08 The Swatch Group Ltd omega // one : 2014-11-07 One.com A/S one // ong : 2014-03-06 Public Interest Registry ong // onl : 2013-09-16 I-Registry Ltd. onl // online : 2015-01-15 DotOnline Inc. online // onyourside : 2015-07-23 Nationwide Mutual Insurance Company onyourside // ooo : 2014-01-09 INFIBEAM INCORPORATION LIMITED ooo // open : 2015-07-31 American Express Travel Related Services Company, Inc. open // oracle : 2014-06-19 Oracle Corporation oracle // orange : 2015-03-12 Orange Brand Services Limited orange // organic : 2014-03-27 Afilias plc organic // origins : 2015-10-01 The Estée Lauder Companies Inc. origins // osaka : 2014-09-04 Osaka Registry Co., Ltd. osaka // otsuka : 2013-10-11 Otsuka Holdings Co., Ltd. otsuka // ott : 2015-06-04 Dish DBS Corporation ott // ovh : 2014-01-16 OVH SAS ovh // page : 2014-12-04 Charleston Road Registry Inc. page // panasonic : 2015-07-30 Panasonic Corporation panasonic // paris : 2014-01-30 City of Paris paris // pars : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. pars // partners : 2013-12-05 Binky Moon, LLC partners // parts : 2013-12-05 Binky Moon, LLC parts // party : 2014-09-11 Blue Sky Registry Limited party // passagens : 2015-03-05 Travel Reservations SRL passagens // pay : 2015-08-27 Amazon Registry Services, Inc. pay // pccw : 2015-05-14 PCCW Enterprises Limited pccw // pet : 2015-05-07 Afilias plc pet // pfizer : 2015-09-11 Pfizer Inc. pfizer // pharmacy : 2014-06-19 National Association of Boards of Pharmacy pharmacy // phd : 2016-07-28 Charleston Road Registry Inc. phd // philips : 2014-11-07 Koninklijke Philips N.V. philips // phone : 2016-06-02 Dish DBS Corporation phone // photo : 2013-11-14 Uniregistry, Corp. photo // photography : 2013-09-20 Binky Moon, LLC photography // photos : 2013-10-17 Binky Moon, LLC photos // physio : 2014-05-01 PhysBiz Pty Ltd physio // piaget : 2014-10-16 Richemont DNS Inc. piaget // pics : 2013-11-14 Uniregistry, Corp. pics // pictet : 2014-06-26 Pictet Europe S.A. pictet // pictures : 2014-03-06 Binky Moon, LLC pictures // pid : 2015-01-08 Top Level Spectrum, Inc. pid // pin : 2014-12-18 Amazon Registry Services, Inc. pin // ping : 2015-06-11 Ping Registry Provider, Inc. ping // pink : 2013-10-01 Afilias plc pink // pioneer : 2015-07-16 Pioneer Corporation pioneer // pizza : 2014-06-26 Binky Moon, LLC pizza // place : 2014-04-24 Binky Moon, LLC place // play : 2015-03-05 Charleston Road Registry Inc. play // playstation : 2015-07-02 Sony Computer Entertainment Inc. playstation // plumbing : 2013-09-10 Binky Moon, LLC plumbing // plus : 2015-02-05 Binky Moon, LLC plus // pnc : 2015-07-02 PNC Domain Co., LLC pnc // pohl : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG pohl // poker : 2014-07-03 Afilias plc poker // politie : 2015-08-20 Politie Nederland politie // porn : 2014-10-16 ICM Registry PN LLC porn // pramerica : 2015-07-30 Prudential Financial, Inc. pramerica // praxi : 2013-12-05 Praxi S.p.A. praxi // press : 2014-04-03 DotPress Inc. press // prime : 2015-06-25 Amazon Registry Services, Inc. prime // prod : 2014-01-23 Charleston Road Registry Inc. prod // productions : 2013-12-05 Binky Moon, LLC productions // prof : 2014-07-24 Charleston Road Registry Inc. prof // progressive : 2015-07-23 Progressive Casualty Insurance Company progressive // promo : 2014-12-18 Afilias plc promo // properties : 2013-12-05 Binky Moon, LLC properties // property : 2014-05-22 Uniregistry, Corp. property // protection : 2015-04-23 XYZ.COM LLC protection // pru : 2015-07-30 Prudential Financial, Inc. pru // prudential : 2015-07-30 Prudential Financial, Inc. prudential // pub : 2013-12-12 United TLD Holdco Ltd. pub // pwc : 2015-10-29 PricewaterhouseCoopers LLP pwc // qpon : 2013-11-14 dotCOOL, Inc. qpon // quebec : 2013-12-19 PointQuébec Inc quebec // quest : 2015-03-26 Quest ION Limited quest // qvc : 2015-07-30 QVC, Inc. qvc // racing : 2014-12-04 Premier Registry Limited racing // radio : 2016-07-21 European Broadcasting Union (EBU) radio // raid : 2015-07-23 Johnson Shareholdings, Inc. raid // read : 2014-12-18 Amazon Registry Services, Inc. read // realestate : 2015-09-11 dotRealEstate LLC realestate // realtor : 2014-05-29 Real Estate Domains LLC realtor // realty : 2015-03-19 Fegistry, LLC realty // recipes : 2013-10-17 Binky Moon, LLC recipes // red : 2013-11-07 Afilias plc red // redstone : 2014-10-31 Redstone Haute Couture Co., Ltd. redstone // redumbrella : 2015-03-26 Travelers TLD, LLC redumbrella // rehab : 2014-03-06 United TLD Holdco Ltd. rehab // reise : 2014-03-13 Binky Moon, LLC reise // reisen : 2014-03-06 Binky Moon, LLC reisen // reit : 2014-09-04 National Association of Real Estate Investment Trusts, Inc. reit // reliance : 2015-04-02 Reliance Industries Limited reliance // ren : 2013-12-12 Beijing Qianxiang Wangjing Technology Development Co., Ltd. ren // rent : 2014-12-04 XYZ.COM LLC rent // rentals : 2013-12-05 Binky Moon, LLC rentals // repair : 2013-11-07 Binky Moon, LLC repair // report : 2013-12-05 Binky Moon, LLC report // republican : 2014-03-20 United TLD Holdco Ltd. republican // rest : 2013-12-19 Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable rest // restaurant : 2014-07-03 Binky Moon, LLC restaurant // review : 2014-11-20 dot Review Limited review // reviews : 2013-09-13 United TLD Holdco Ltd. reviews // rexroth : 2015-06-18 Robert Bosch GMBH rexroth // rich : 2013-11-21 I-Registry Ltd. rich // richardli : 2015-05-14 Pacific Century Asset Management (HK) Limited richardli // ricoh : 2014-11-20 Ricoh Company, Ltd. ricoh // rightathome : 2015-07-23 Johnson Shareholdings, Inc. rightathome // ril : 2015-04-02 Reliance Industries Limited ril // rio : 2014-02-27 Empresa Municipal de Informática SA - IPLANRIO rio // rip : 2014-07-10 United TLD Holdco Ltd. rip // rmit : 2015-11-19 Royal Melbourne Institute of Technology rmit // rocher : 2014-12-18 Ferrero Trading Lux S.A. rocher // rocks : 2013-11-14 United TLD Holdco Ltd. rocks // rodeo : 2013-12-19 Minds + Machines Group Limited rodeo // rogers : 2015-08-06 Rogers Communications Canada Inc. rogers // room : 2014-12-18 Amazon Registry Services, Inc. room // rsvp : 2014-05-08 Charleston Road Registry Inc. rsvp // rugby : 2016-12-15 World Rugby Strategic Developments Limited rugby // ruhr : 2013-10-02 regiodot GmbH & Co. KG ruhr // run : 2015-03-19 Binky Moon, LLC run // rwe : 2015-04-02 RWE AG rwe // ryukyu : 2014-01-09 BRregistry, Inc. ryukyu // saarland : 2013-12-12 dotSaarland GmbH saarland // safe : 2014-12-18 Amazon Registry Services, Inc. safe // safety : 2015-01-08 Safety Registry Services, LLC. safety // sakura : 2014-12-18 SAKURA Internet Inc. sakura // sale : 2014-10-16 United TLD Holdco Ltd. sale // salon : 2014-12-11 Binky Moon, LLC salon // samsclub : 2015-07-31 Wal-Mart Stores, Inc. samsclub // samsung : 2014-04-03 SAMSUNG SDS CO., LTD samsung // sandvik : 2014-11-13 Sandvik AB sandvik // sandvikcoromant : 2014-11-07 Sandvik AB sandvikcoromant // sanofi : 2014-10-09 Sanofi sanofi // sap : 2014-03-27 SAP AG sap // sarl : 2014-07-03 Binky Moon, LLC sarl // sas : 2015-04-02 Research IP LLC sas // save : 2015-06-25 Amazon Registry Services, Inc. save // saxo : 2014-10-31 Saxo Bank A/S saxo // sbi : 2015-03-12 STATE BANK OF INDIA sbi // sbs : 2014-11-07 SPECIAL BROADCASTING SERVICE CORPORATION sbs // sca : 2014-03-13 SVENSKA CELLULOSA AKTIEBOLAGET SCA (publ) sca // scb : 2014-02-20 The Siam Commercial Bank Public Company Limited ("SCB") scb // schaeffler : 2015-08-06 Schaeffler Technologies AG & Co. KG schaeffler // schmidt : 2014-04-03 SALM S.A.S. schmidt // scholarships : 2014-04-24 Scholarships.com, LLC scholarships // school : 2014-12-18 Binky Moon, LLC school // schule : 2014-03-06 Binky Moon, LLC schule // schwarz : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG schwarz // science : 2014-09-11 dot Science Limited science // scjohnson : 2015-07-23 Johnson Shareholdings, Inc. scjohnson // scor : 2014-10-31 SCOR SE scor // scot : 2014-01-23 Dot Scot Registry Limited scot // search : 2016-06-09 Charleston Road Registry Inc. search // seat : 2014-05-22 SEAT, S.A. (Sociedad Unipersonal) seat // secure : 2015-08-27 Amazon Registry Services, Inc. secure // security : 2015-05-14 XYZ.COM LLC security // seek : 2014-12-04 Seek Limited seek // select : 2015-10-08 iSelect Ltd select // sener : 2014-10-24 Sener Ingeniería y Sistemas, S.A. sener // services : 2014-02-27 Binky Moon, LLC services // ses : 2015-07-23 SES ses // seven : 2015-08-06 Seven West Media Ltd seven // sew : 2014-07-17 SEW-EURODRIVE GmbH & Co KG sew // sex : 2014-11-13 ICM Registry SX LLC sex // sexy : 2013-09-11 Uniregistry, Corp. sexy // sfr : 2015-08-13 Societe Francaise du Radiotelephone - SFR sfr // shangrila : 2015-09-03 Shangri‐La International Hotel Management Limited shangrila // sharp : 2014-05-01 Sharp Corporation sharp // shaw : 2015-04-23 Shaw Cablesystems G.P. shaw // shell : 2015-07-30 Shell Information Technology International Inc shell // shia : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. shia // shiksha : 2013-11-14 Afilias plc shiksha // shoes : 2013-10-02 Binky Moon, LLC shoes // shop : 2016-04-08 GMO Registry, Inc. shop // shopping : 2016-03-31 Binky Moon, LLC shopping // shouji : 2015-01-08 QIHOO 360 TECHNOLOGY CO. LTD. shouji // show : 2015-03-05 Binky Moon, LLC show // showtime : 2015-08-06 CBS Domains Inc. showtime // shriram : 2014-01-23 Shriram Capital Ltd. shriram // silk : 2015-06-25 Amazon Registry Services, Inc. silk // sina : 2015-03-12 Sina Corporation sina // singles : 2013-08-27 Binky Moon, LLC singles // site : 2015-01-15 DotSite Inc. site // ski : 2015-04-09 Afilias plc ski // skin : 2015-01-15 L'Oréal skin // sky : 2014-06-19 Sky International AG sky // skype : 2014-12-18 Microsoft Corporation skype // sling : 2015-07-30 Hughes Satellite Systems Corporation sling // smart : 2015-07-09 Smart Communications, Inc. (SMART) smart // smile : 2014-12-18 Amazon Registry Services, Inc. smile // sncf : 2015-02-19 Société Nationale des Chemins de fer Francais S N C F sncf // soccer : 2015-03-26 Binky Moon, LLC soccer // social : 2013-11-07 United TLD Holdco Ltd. social // softbank : 2015-07-02 SoftBank Corp. softbank // software : 2014-03-20 United TLD Holdco Ltd. software // sohu : 2013-12-19 Sohu.com Limited sohu // solar : 2013-11-07 Binky Moon, LLC solar // solutions : 2013-11-07 Binky Moon, LLC solutions // song : 2015-02-26 Amazon Registry Services, Inc. song // sony : 2015-01-08 Sony Corporation sony // soy : 2014-01-23 Charleston Road Registry Inc. soy // space : 2014-04-03 DotSpace Inc. space // sport : 2017-11-16 Global Association of International Sports Federations (GAISF) sport // spot : 2015-02-26 Amazon Registry Services, Inc. spot // spreadbetting : 2014-12-11 Dotspreadbetting Registry Limited spreadbetting // srl : 2015-05-07 InterNetX, Corp srl // srt : 2015-07-30 FCA US LLC. srt // stada : 2014-11-13 STADA Arzneimittel AG stada // staples : 2015-07-30 Staples, Inc. staples // star : 2015-01-08 Star India Private Limited star // starhub : 2015-02-05 StarHub Ltd starhub // statebank : 2015-03-12 STATE BANK OF INDIA statebank // statefarm : 2015-07-30 State Farm Mutual Automobile Insurance Company statefarm // stc : 2014-10-09 Saudi Telecom Company stc // stcgroup : 2014-10-09 Saudi Telecom Company stcgroup // stockholm : 2014-12-18 Stockholms kommun stockholm // storage : 2014-12-22 XYZ.COM LLC storage // store : 2015-04-09 DotStore Inc. store // stream : 2016-01-08 dot Stream Limited stream // studio : 2015-02-11 United TLD Holdco Ltd. studio // study : 2014-12-11 OPEN UNIVERSITIES AUSTRALIA PTY LTD study // style : 2014-12-04 Binky Moon, LLC style // sucks : 2014-12-22 Vox Populi Registry Ltd. sucks // supplies : 2013-12-19 Binky Moon, LLC supplies // supply : 2013-12-19 Binky Moon, LLC supply // support : 2013-10-24 Binky Moon, LLC support // surf : 2014-01-09 Minds + Machines Group Limited surf // surgery : 2014-03-20 Binky Moon, LLC surgery // suzuki : 2014-02-20 SUZUKI MOTOR CORPORATION suzuki // swatch : 2015-01-08 The Swatch Group Ltd swatch // swiftcover : 2015-07-23 Swiftcover Insurance Services Limited swiftcover // swiss : 2014-10-16 Swiss Confederation swiss // sydney : 2014-09-18 State of New South Wales, Department of Premier and Cabinet sydney // symantec : 2014-12-04 Symantec Corporation symantec // systems : 2013-11-07 Binky Moon, LLC systems // tab : 2014-12-04 Tabcorp Holdings Limited tab // taipei : 2014-07-10 Taipei City Government taipei // talk : 2015-04-09 Amazon Registry Services, Inc. talk // taobao : 2015-01-15 Alibaba Group Holding Limited taobao // target : 2015-07-31 Target Domain Holdings, LLC target // tatamotors : 2015-03-12 Tata Motors Ltd tatamotors // tatar : 2014-04-24 Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic" tatar // tattoo : 2013-08-30 Uniregistry, Corp. tattoo // tax : 2014-03-20 Binky Moon, LLC tax // taxi : 2015-03-19 Binky Moon, LLC taxi // tci : 2014-09-12 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. tci // tdk : 2015-06-11 TDK Corporation tdk // team : 2015-03-05 Binky Moon, LLC team // tech : 2015-01-30 Personals TLD Inc. tech // technology : 2013-09-13 Binky Moon, LLC technology // telefonica : 2014-10-16 Telefónica S.A. telefonica // temasek : 2014-08-07 Temasek Holdings (Private) Limited temasek // tennis : 2014-12-04 Binky Moon, LLC tennis // teva : 2015-07-02 Teva Pharmaceutical Industries Limited teva // thd : 2015-04-02 Home Depot Product Authority, LLC thd // theater : 2015-03-19 Binky Moon, LLC theater // theatre : 2015-05-07 XYZ.COM LLC theatre // tiaa : 2015-07-23 Teachers Insurance and Annuity Association of America tiaa // tickets : 2015-02-05 Accent Media Limited tickets // tienda : 2013-11-14 Binky Moon, LLC tienda // tiffany : 2015-01-30 Tiffany and Company tiffany // tips : 2013-09-20 Binky Moon, LLC tips // tires : 2014-11-07 Binky Moon, LLC tires // tirol : 2014-04-24 punkt Tirol GmbH tirol // tjmaxx : 2015-07-16 The TJX Companies, Inc. tjmaxx // tjx : 2015-07-16 The TJX Companies, Inc. tjx // tkmaxx : 2015-07-16 The TJX Companies, Inc. tkmaxx // tmall : 2015-01-15 Alibaba Group Holding Limited tmall // today : 2013-09-20 Binky Moon, LLC today // tokyo : 2013-11-13 GMO Registry, Inc. tokyo // tools : 2013-11-21 Binky Moon, LLC tools // top : 2014-03-20 .TOP Registry top // toray : 2014-12-18 Toray Industries, Inc. toray // toshiba : 2014-04-10 TOSHIBA Corporation toshiba // total : 2015-08-06 Total SA total // tours : 2015-01-22 Binky Moon, LLC tours // town : 2014-03-06 Binky Moon, LLC town // toyota : 2015-04-23 TOYOTA MOTOR CORPORATION toyota // toys : 2014-03-06 Binky Moon, LLC toys // trade : 2014-01-23 Elite Registry Limited trade // trading : 2014-12-11 Dottrading Registry Limited trading // training : 2013-11-07 Binky Moon, LLC training // travel : Dog Beach, LLC travel // travelchannel : 2015-07-02 Lifestyle Domain Holdings, Inc. travelchannel // travelers : 2015-03-26 Travelers TLD, LLC travelers // travelersinsurance : 2015-03-26 Travelers TLD, LLC travelersinsurance // trust : 2014-10-16 NCC Group Inc. trust // trv : 2015-03-26 Travelers TLD, LLC trv // tube : 2015-06-11 Latin American Telecom LLC tube // tui : 2014-07-03 TUI AG tui // tunes : 2015-02-26 Amazon Registry Services, Inc. tunes // tushu : 2014-12-18 Amazon Registry Services, Inc. tushu // tvs : 2015-02-19 T V SUNDRAM IYENGAR & SONS LIMITED tvs // ubank : 2015-08-20 National Australia Bank Limited ubank // ubs : 2014-12-11 UBS AG ubs // uconnect : 2015-07-30 FCA US LLC. uconnect // unicom : 2015-10-15 China United Network Communications Corporation Limited unicom // university : 2014-03-06 Binky Moon, LLC university // uno : 2013-09-11 Dot Latin LLC uno // uol : 2014-05-01 UBN INTERNET LTDA. uol // ups : 2015-06-25 UPS Market Driver, Inc. ups // vacations : 2013-12-05 Binky Moon, LLC vacations // vana : 2014-12-11 Lifestyle Domain Holdings, Inc. vana // vanguard : 2015-09-03 The Vanguard Group, Inc. vanguard // vegas : 2014-01-16 Dot Vegas, Inc. vegas // ventures : 2013-08-27 Binky Moon, LLC ventures // verisign : 2015-08-13 VeriSign, Inc. verisign // versicherung : 2014-03-20 TLD-BOX Registrydienstleistungen GmbH versicherung // vet : 2014-03-06 United TLD Holdco Ltd. vet // viajes : 2013-10-17 Binky Moon, LLC viajes // video : 2014-10-16 United TLD Holdco Ltd. video // vig : 2015-05-14 VIENNA INSURANCE GROUP AG Wiener Versicherung Gruppe vig // viking : 2015-04-02 Viking River Cruises (Bermuda) Ltd. viking // villas : 2013-12-05 Binky Moon, LLC villas // vin : 2015-06-18 Binky Moon, LLC vin // vip : 2015-01-22 Minds + Machines Group Limited vip // virgin : 2014-09-25 Virgin Enterprises Limited virgin // visa : 2015-07-30 Visa Worldwide Pte. Limited visa // vision : 2013-12-05 Binky Moon, LLC vision // vistaprint : 2014-09-18 Vistaprint Limited vistaprint // viva : 2014-11-07 Saudi Telecom Company viva // vivo : 2015-07-31 Telefonica Brasil S.A. vivo // vlaanderen : 2014-02-06 DNS.be vzw vlaanderen // vodka : 2013-12-19 Minds + Machines Group Limited vodka // volkswagen : 2015-05-14 Volkswagen Group of America Inc. volkswagen // volvo : 2015-11-12 Volvo Holding Sverige Aktiebolag volvo // vote : 2013-11-21 Monolith Registry LLC vote // voting : 2013-11-13 Valuetainment Corp. voting // voto : 2013-11-21 Monolith Registry LLC voto // voyage : 2013-08-27 Binky Moon, LLC voyage // vuelos : 2015-03-05 Travel Reservations SRL vuelos // wales : 2014-05-08 Nominet UK wales // walmart : 2015-07-31 Wal-Mart Stores, Inc. walmart // walter : 2014-11-13 Sandvik AB walter // wang : 2013-10-24 Zodiac Wang Limited wang // wanggou : 2014-12-18 Amazon Registry Services, Inc. wanggou // warman : 2015-06-18 Weir Group IP Limited warman // watch : 2013-11-14 Binky Moon, LLC watch // watches : 2014-12-22 Richemont DNS Inc. watches // weather : 2015-01-08 International Business Machines Corporation weather // weatherchannel : 2015-03-12 International Business Machines Corporation weatherchannel // webcam : 2014-01-23 dot Webcam Limited webcam // weber : 2015-06-04 Saint-Gobain Weber SA weber // website : 2014-04-03 DotWebsite Inc. website // wed : 2013-10-01 Atgron, Inc. wed // wedding : 2014-04-24 Minds + Machines Group Limited wedding // weibo : 2015-03-05 Sina Corporation weibo // weir : 2015-01-29 Weir Group IP Limited weir // whoswho : 2014-02-20 Who's Who Registry whoswho // wien : 2013-10-28 punkt.wien GmbH wien // wiki : 2013-11-07 Top Level Design, LLC wiki // williamhill : 2014-03-13 William Hill Organization Limited williamhill // win : 2014-11-20 First Registry Limited win // windows : 2014-12-18 Microsoft Corporation windows // wine : 2015-06-18 Binky Moon, LLC wine // winners : 2015-07-16 The TJX Companies, Inc. winners // wme : 2014-02-13 William Morris Endeavor Entertainment, LLC wme // wolterskluwer : 2015-08-06 Wolters Kluwer N.V. wolterskluwer // woodside : 2015-07-09 Woodside Petroleum Limited woodside // work : 2013-12-19 Minds + Machines Group Limited work // works : 2013-11-14 Binky Moon, LLC works // world : 2014-06-12 Binky Moon, LLC world // wow : 2015-10-08 Amazon Registry Services, Inc. wow // wtc : 2013-12-19 World Trade Centers Association, Inc. wtc // wtf : 2014-03-06 Binky Moon, LLC wtf // xbox : 2014-12-18 Microsoft Corporation xbox // xerox : 2014-10-24 Xerox DNHC LLC xerox // xfinity : 2015-07-09 Comcast IP Holdings I, LLC xfinity // xihuan : 2015-01-08 QIHOO 360 TECHNOLOGY CO. LTD. xihuan // xin : 2014-12-11 Elegant Leader Limited xin // xn--11b4c3d : 2015-01-15 VeriSign Sarl xn--11b4c3d // xn--1ck2e1b : 2015-02-26 Amazon Registry Services, Inc. xn--1ck2e1b // xn--1qqw23a : 2014-01-09 Guangzhou YU Wei Information Technology Co., Ltd. xn--1qqw23a // xn--30rr7y : 2014-06-12 Excellent First Limited xn--30rr7y // xn--3bst00m : 2013-09-13 Eagle Horizon Limited xn--3bst00m // xn--3ds443g : 2013-09-08 TLD REGISTRY LIMITED xn--3ds443g // xn--3oq18vl8pn36a : 2015-07-02 Volkswagen (China) Investment Co., Ltd. xn--3oq18vl8pn36a // xn--3pxu8k : 2015-01-15 VeriSign Sarl xn--3pxu8k // xn--42c2d9a : 2015-01-15 VeriSign Sarl xn--42c2d9a // xn--45q11c : 2013-11-21 Zodiac Gemini Ltd xn--45q11c // xn--4gbrim : 2013-10-04 Suhub Electronic Establishment xn--4gbrim // xn--55qw42g : 2013-11-08 China Organizational Name Administration Center xn--55qw42g // xn--55qx5d : 2013-11-14 China Internet Network Information Center (CNNIC) xn--55qx5d // xn--5su34j936bgsg : 2015-09-03 Shangri‐La International Hotel Management Limited xn--5su34j936bgsg // xn--5tzm5g : 2014-12-22 Global Website TLD Asia Limited xn--5tzm5g // xn--6frz82g : 2013-09-23 Afilias plc xn--6frz82g // xn--6qq986b3xl : 2013-09-13 Tycoon Treasure Limited xn--6qq986b3xl // xn--80adxhks : 2013-12-19 Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) xn--80adxhks // xn--80aqecdr1a : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) xn--80aqecdr1a // xn--80asehdb : 2013-07-14 CORE Association xn--80asehdb // xn--80aswg : 2013-07-14 CORE Association xn--80aswg // xn--8y0a063a : 2015-03-26 China United Network Communications Corporation Limited xn--8y0a063a // xn--9dbq2a : 2015-01-15 VeriSign Sarl xn--9dbq2a // xn--9et52u : 2014-06-12 RISE VICTORY LIMITED xn--9et52u // xn--9krt00a : 2015-03-12 Sina Corporation xn--9krt00a // xn--b4w605ferd : 2014-08-07 Temasek Holdings (Private) Limited xn--b4w605ferd // xn--bck1b9a5dre4c : 2015-02-26 Amazon Registry Services, Inc. xn--bck1b9a5dre4c // xn--c1avg : 2013-11-14 Public Interest Registry xn--c1avg // xn--c2br7g : 2015-01-15 VeriSign Sarl xn--c2br7g // xn--cck2b3b : 2015-02-26 Amazon Registry Services, Inc. xn--cck2b3b // xn--cg4bki : 2013-09-27 SAMSUNG SDS CO., LTD xn--cg4bki // xn--czr694b : 2014-01-16 Dot Trademark TLD Holding Company Limited xn--czr694b // xn--czrs0t : 2013-12-19 Binky Moon, LLC xn--czrs0t // xn--czru2d : 2013-11-21 Zodiac Aquarius Limited xn--czru2d // xn--d1acj3b : 2013-11-20 The Foundation for Network Initiatives “The Smart Internet” xn--d1acj3b // xn--eckvdtc9d : 2014-12-18 Amazon Registry Services, Inc. xn--eckvdtc9d // xn--efvy88h : 2014-08-22 Guangzhou YU Wei Information Technology Co., Ltd. xn--efvy88h // xn--estv75g : 2015-02-19 Industrial and Commercial Bank of China Limited xn--estv75g // xn--fct429k : 2015-04-09 Amazon Registry Services, Inc. xn--fct429k // xn--fhbei : 2015-01-15 VeriSign Sarl xn--fhbei // xn--fiq228c5hs : 2013-09-08 TLD REGISTRY LIMITED xn--fiq228c5hs // xn--fiq64b : 2013-10-14 CITIC Group Corporation xn--fiq64b // xn--fjq720a : 2014-05-22 Binky Moon, LLC xn--fjq720a // xn--flw351e : 2014-07-31 Charleston Road Registry Inc. xn--flw351e // xn--fzys8d69uvgm : 2015-05-14 PCCW Enterprises Limited xn--fzys8d69uvgm // xn--g2xx48c : 2015-01-30 Minds + Machines Group Limited xn--g2xx48c // xn--gckr3f0f : 2015-02-26 Amazon Registry Services, Inc. xn--gckr3f0f // xn--gk3at1e : 2015-10-08 Amazon Registry Services, Inc. xn--gk3at1e // xn--hxt814e : 2014-05-15 Zodiac Taurus Limited xn--hxt814e // xn--i1b6b1a6a2e : 2013-11-14 Public Interest Registry xn--i1b6b1a6a2e // xn--imr513n : 2014-12-11 Dot Trademark TLD Holding Company Limited xn--imr513n // xn--io0a7i : 2013-11-14 China Internet Network Information Center (CNNIC) xn--io0a7i // xn--j1aef : 2015-01-15 VeriSign Sarl xn--j1aef // xn--jlq61u9w7b : 2015-01-08 Nokia Corporation xn--jlq61u9w7b // xn--jvr189m : 2015-02-26 Amazon Registry Services, Inc. xn--jvr189m // xn--kcrx77d1x4a : 2014-11-07 Koninklijke Philips N.V. xn--kcrx77d1x4a // xn--kpu716f : 2014-12-22 Richemont DNS Inc. xn--kpu716f // xn--kput3i : 2014-02-13 Beijing RITT-Net Technology Development Co., Ltd xn--kput3i // xn--mgba3a3ejt : 2014-11-20 Aramco Services Company xn--mgba3a3ejt // xn--mgba7c0bbn0a : 2015-05-14 Crescent Holding GmbH xn--mgba7c0bbn0a // xn--mgbaakc7dvf : 2015-09-03 Emirates Telecommunications Corporation (trading as Etisalat) xn--mgbaakc7dvf // xn--mgbab2bd : 2013-10-31 CORE Association xn--mgbab2bd // xn--mgbb9fbpob : 2014-12-18 GreenTech Consultancy Company W.L.L. xn--mgbb9fbpob // xn--mgbca7dzdo : 2015-07-30 Abu Dhabi Systems and Information Centre xn--mgbca7dzdo // xn--mgbi4ecexp : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) xn--mgbi4ecexp // xn--mgbt3dhd : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti. xn--mgbt3dhd // xn--mk1bu44c : 2015-01-15 VeriSign Sarl xn--mk1bu44c // xn--mxtq1m : 2014-03-06 Net-Chinese Co., Ltd. xn--mxtq1m // xn--ngbc5azd : 2013-07-13 International Domain Registry Pty. Ltd. xn--ngbc5azd // xn--ngbe9e0a : 2014-12-04 Kuwait Finance House xn--ngbe9e0a // xn--ngbrx : 2015-11-12 League of Arab States xn--ngbrx // xn--nqv7f : 2013-11-14 Public Interest Registry xn--nqv7f // xn--nqv7fs00ema : 2013-11-14 Public Interest Registry xn--nqv7fs00ema // xn--nyqy26a : 2014-11-07 Stable Tone Limited xn--nyqy26a // xn--otu796d : 2017-08-06 Dot Trademark TLD Holding Company Limited xn--otu796d // xn--p1acf : 2013-12-12 Rusnames Limited xn--p1acf // xn--pbt977c : 2014-12-22 Richemont DNS Inc. xn--pbt977c // xn--pssy2u : 2015-01-15 VeriSign Sarl xn--pssy2u // xn--q9jyb4c : 2013-09-17 Charleston Road Registry Inc. xn--q9jyb4c // xn--qcka1pmc : 2014-07-31 Charleston Road Registry Inc. xn--qcka1pmc // xn--rhqv96g : 2013-09-11 Stable Tone Limited xn--rhqv96g // xn--rovu88b : 2015-02-26 Amazon Registry Services, Inc. xn--rovu88b // xn--ses554g : 2014-01-16 KNET Co., Ltd. xn--ses554g // xn--t60b56a : 2015-01-15 VeriSign Sarl xn--t60b56a // xn--tckwe : 2015-01-15 VeriSign Sarl xn--tckwe // xn--tiq49xqyj : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) xn--tiq49xqyj // xn--unup4y : 2013-07-14 Binky Moon, LLC xn--unup4y // xn--vermgensberater-ctb : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG xn--vermgensberater-ctb // xn--vermgensberatung-pwb : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG xn--vermgensberatung-pwb // xn--vhquv : 2013-08-27 Binky Moon, LLC xn--vhquv // xn--vuq861b : 2014-10-16 Beijing Tele-info Network Technology Co., Ltd. xn--vuq861b // xn--w4r85el8fhu5dnra : 2015-04-30 Kerry Trading Co. Limited xn--w4r85el8fhu5dnra // xn--w4rs40l : 2015-07-30 Kerry Trading Co. Limited xn--w4rs40l // xn--xhq521b : 2013-11-14 Guangzhou YU Wei Information Technology Co., Ltd. xn--xhq521b // xn--zfr164b : 2013-11-08 China Organizational Name Administration Center xn--zfr164b // xyz : 2013-12-05 XYZ.COM LLC xyz // yachts : 2014-01-09 DERYachts, LLC yachts // yahoo : 2015-04-02 Yahoo! Domain Services Inc. yahoo // yamaxun : 2014-12-18 Amazon Registry Services, Inc. yamaxun // yandex : 2014-04-10 YANDEX, LLC yandex // yodobashi : 2014-11-20 YODOBASHI CAMERA CO.,LTD. yodobashi // yoga : 2014-05-29 Minds + Machines Group Limited yoga // yokohama : 2013-12-12 GMO Registry, Inc. yokohama // you : 2015-04-09 Amazon Registry Services, Inc. you // youtube : 2014-05-01 Charleston Road Registry Inc. youtube // yun : 2015-01-08 QIHOO 360 TECHNOLOGY CO. LTD. yun // zappos : 2015-06-25 Amazon Registry Services, Inc. zappos // zara : 2014-11-07 Industria de Diseño Textil, S.A. (INDITEX, S.A.) zara // zero : 2014-12-18 Amazon Registry Services, Inc. zero // zip : 2014-05-08 Charleston Road Registry Inc. zip // zone : 2013-11-14 Binky Moon, LLC zone // zuerich : 2014-11-07 Kanton Zürich (Canton of Zurich) zuerich // ===END ICANN DOMAINS=== // ===BEGIN PRIVATE DOMAINS=== // (Note: these are in alphabetical order by company name) // 1GB LLC : https://www.1gb.ua/ // Submitted by 1GB LLC cc.ua inf.ua ltd.ua // Agnat sp. z o.o. : https://domena.pl // Submitted by Przemyslaw Plewa beep.pl // Alces Software Ltd : http://alces-software.com // Submitted by Mark J. Titorenko *.compute.estate *.alces.network // alwaysdata : https://www.alwaysdata.com // Submitted by Cyril alwaysdata.net // Amazon CloudFront : https://aws.amazon.com/cloudfront/ // Submitted by Donavan Miller cloudfront.net // Amazon Elastic Compute Cloud : https://aws.amazon.com/ec2/ // Submitted by Luke Wells *.compute.amazonaws.com *.compute-1.amazonaws.com *.compute.amazonaws.com.cn us-east-1.amazonaws.com // Amazon Elastic Beanstalk : https://aws.amazon.com/elasticbeanstalk/ // Submitted by Luke Wells cn-north-1.eb.amazonaws.com.cn cn-northwest-1.eb.amazonaws.com.cn elasticbeanstalk.com ap-northeast-1.elasticbeanstalk.com ap-northeast-2.elasticbeanstalk.com ap-northeast-3.elasticbeanstalk.com ap-south-1.elasticbeanstalk.com ap-southeast-1.elasticbeanstalk.com ap-southeast-2.elasticbeanstalk.com ca-central-1.elasticbeanstalk.com eu-central-1.elasticbeanstalk.com eu-west-1.elasticbeanstalk.com eu-west-2.elasticbeanstalk.com eu-west-3.elasticbeanstalk.com sa-east-1.elasticbeanstalk.com us-east-1.elasticbeanstalk.com us-east-2.elasticbeanstalk.com us-gov-west-1.elasticbeanstalk.com us-west-1.elasticbeanstalk.com us-west-2.elasticbeanstalk.com // Amazon Elastic Load Balancing : https://aws.amazon.com/elasticloadbalancing/ // Submitted by Luke Wells *.elb.amazonaws.com *.elb.amazonaws.com.cn // Amazon S3 : https://aws.amazon.com/s3/ // Submitted by Luke Wells s3.amazonaws.com s3-ap-northeast-1.amazonaws.com s3-ap-northeast-2.amazonaws.com s3-ap-south-1.amazonaws.com s3-ap-southeast-1.amazonaws.com s3-ap-southeast-2.amazonaws.com s3-ca-central-1.amazonaws.com s3-eu-central-1.amazonaws.com s3-eu-west-1.amazonaws.com s3-eu-west-2.amazonaws.com s3-eu-west-3.amazonaws.com s3-external-1.amazonaws.com s3-fips-us-gov-west-1.amazonaws.com s3-sa-east-1.amazonaws.com s3-us-gov-west-1.amazonaws.com s3-us-east-2.amazonaws.com s3-us-west-1.amazonaws.com s3-us-west-2.amazonaws.com s3.ap-northeast-2.amazonaws.com s3.ap-south-1.amazonaws.com s3.cn-north-1.amazonaws.com.cn s3.ca-central-1.amazonaws.com s3.eu-central-1.amazonaws.com s3.eu-west-2.amazonaws.com s3.eu-west-3.amazonaws.com s3.us-east-2.amazonaws.com s3.dualstack.ap-northeast-1.amazonaws.com s3.dualstack.ap-northeast-2.amazonaws.com s3.dualstack.ap-south-1.amazonaws.com s3.dualstack.ap-southeast-1.amazonaws.com s3.dualstack.ap-southeast-2.amazonaws.com s3.dualstack.ca-central-1.amazonaws.com s3.dualstack.eu-central-1.amazonaws.com s3.dualstack.eu-west-1.amazonaws.com s3.dualstack.eu-west-2.amazonaws.com s3.dualstack.eu-west-3.amazonaws.com s3.dualstack.sa-east-1.amazonaws.com s3.dualstack.us-east-1.amazonaws.com s3.dualstack.us-east-2.amazonaws.com s3-website-us-east-1.amazonaws.com s3-website-us-west-1.amazonaws.com s3-website-us-west-2.amazonaws.com s3-website-ap-northeast-1.amazonaws.com s3-website-ap-southeast-1.amazonaws.com s3-website-ap-southeast-2.amazonaws.com s3-website-eu-west-1.amazonaws.com s3-website-sa-east-1.amazonaws.com s3-website.ap-northeast-2.amazonaws.com s3-website.ap-south-1.amazonaws.com s3-website.ca-central-1.amazonaws.com s3-website.eu-central-1.amazonaws.com s3-website.eu-west-2.amazonaws.com s3-website.eu-west-3.amazonaws.com s3-website.us-east-2.amazonaws.com // Amune : https://amune.org/ // Submitted by Team Amune t3l3p0rt.net tele.amune.org // Apigee : https://apigee.com/ // Submitted by Apigee Security Team apigee.io // Aptible : https://www.aptible.com/ // Submitted by Thomas Orozco on-aptible.com // Asociación Amigos de la Informática "Euskalamiga" : http://encounter.eus/ // Submitted by Hector Martin user.party.eus // Association potager.org : https://potager.org/ // Submitted by Lunar pimienta.org poivron.org potager.org sweetpepper.org // ASUSTOR Inc. : http://www.asustor.com // Submitted by Vincent Tseng myasustor.com // Automattic Inc. : https://automattic.com/ // Submitted by Alex Concha go-vip.co wpcomstaging.com // AVM : https://avm.de // Submitted by Andreas Weise myfritz.net // AW AdvisorWebsites.com Software Inc : https://advisorwebsites.com // Submitted by James Kennedy *.awdev.ca *.advisor.ws // backplane : https://www.backplane.io // Submitted by Anthony Voutas backplaneapp.io // BetaInABox // Submitted by Adrian betainabox.com // BinaryLane : http://www.binarylane.com // Submitted by Nathan O'Sullivan bnr.la // Blackbaud, Inc. : https://www.blackbaud.com // Submitted by Paul Crowder blackbaudcdn.net // Boomla : https://boomla.com // Submitted by Tibor Halter boomla.net // Boxfuse : https://boxfuse.com // Submitted by Axel Fontaine boxfuse.io // bplaced : https://www.bplaced.net/ // Submitted by Miroslav Bozic square7.ch bplaced.com bplaced.de square7.de bplaced.net square7.net // BrowserSafetyMark // Submitted by Dave Tharp browsersafetymark.io // Bytemark Hosting : https://www.bytemark.co.uk // Submitted by Paul Cammish dh.bytemark.co.uk vm.bytemark.co.uk // callidomus : https://www.callidomus.com/ // Submitted by Marcus Popp mycd.eu // CentralNic : http://www.centralnic.com/names/domains // Submitted by registry ae.org ar.com br.com cn.com com.de com.se de.com eu.com gb.com gb.net hu.com hu.net jp.net jpn.com kr.com mex.com no.com qc.com ru.com sa.com se.net uk.com uk.net us.com uy.com za.bz za.com // Africa.com Web Solutions Ltd : https://registry.africa.com // Submitted by Gavin Brown africa.com // iDOT Services Limited : http://www.domain.gr.com // Submitted by Gavin Brown gr.com // Radix FZC : http://domains.in.net // Submitted by Gavin Brown in.net // US REGISTRY LLC : http://us.org // Submitted by Gavin Brown us.org // co.com Registry, LLC : https://registry.co.com // Submitted by Gavin Brown co.com // c.la : http://www.c.la/ c.la // certmgr.org : https://certmgr.org // Submitted by B. Blechschmidt certmgr.org // Citrix : https://citrix.com // Submitted by Alex Stoddard xenapponazure.com // ClearVox : http://www.clearvox.nl/ // Submitted by Leon Rowland virtueeldomein.nl // Clever Cloud : https://www.clever-cloud.com/ // Submitted by Quentin Adam cleverapps.io // Cloud66 : https://www.cloud66.com/ // Submitted by Khash Sajadi c66.me cloud66.ws // CloudAccess.net : https://www.cloudaccess.net/ // Submitted by Pawel Panek jdevcloud.com wpdevcloud.com cloudaccess.host freesite.host cloudaccess.net // cloudControl : https://www.cloudcontrol.com/ // Submitted by Tobias Wilken cloudcontrolled.com cloudcontrolapp.com // co.ca : http://registry.co.ca/ co.ca // Co & Co : https://co-co.nl/ // Submitted by Govert Versluis *.otap.co // i-registry s.r.o. : http://www.i-registry.cz/ // Submitted by Martin Semrad co.cz // CDN77.com : http://www.cdn77.com // Submitted by Jan Krpes c.cdn77.org cdn77-ssl.net r.cdn77.net rsc.cdn77.org ssl.origin.cdn77-secure.org // Cloud DNS Ltd : http://www.cloudns.net // Submitted by Aleksander Hristov cloudns.asia cloudns.biz cloudns.club cloudns.cc cloudns.eu cloudns.in cloudns.info cloudns.org cloudns.pro cloudns.pw cloudns.us // Cloudeity Inc : https://cloudeity.com // Submitted by Stefan Dimitrov cloudeity.net // CNPY : https://cnpy.gdn // Submitted by Angelo Gladding cnpy.gdn // CoDNS B.V. co.nl co.no // Combell.com : https://www.combell.com // Submitted by Thomas Wouters webhosting.be hosting-cluster.nl // COSIMO GmbH : http://www.cosimo.de // Submitted by Rene Marticke dyn.cosidns.de dynamisches-dns.de dnsupdater.de internet-dns.de l-o-g-i-n.de dynamic-dns.info feste-ip.net knx-server.net static-access.net // Craynic, s.r.o. : http://www.craynic.com/ // Submitted by Ales Krajnik realm.cz // Cryptonomic : https://cryptonomic.net/ // Submitted by Andrew Cady *.cryptonomic.net // Cupcake : https://cupcake.io/ // Submitted by Jonathan Rudenberg cupcake.is // cyon GmbH : https://www.cyon.ch/ // Submitted by Dominic Luechinger cyon.link cyon.site // Daplie, Inc : https://daplie.com // Submitted by AJ ONeal daplie.me localhost.daplie.me // Datto, Inc. : https://www.datto.com/ // Submitted by Philipp Heckel dattolocal.com dattorelay.com dattoweb.com mydatto.com dattolocal.net mydatto.net // Dansk.net : http://www.dansk.net/ // Submitted by Anani Voule biz.dk co.dk firm.dk reg.dk store.dk // dapps.earth : https://dapps.earth/ // Submitted by Daniil Burdakov *.dapps.earth *.bzz.dapps.earth // Debian : https://www.debian.org/ // Submitted by Peter Palfrader / Debian Sysadmin Team debian.net // deSEC : https://desec.io/ // Submitted by Peter Thomassen dedyn.io // DNShome : https://www.dnshome.de/ // Submitted by Norbert Auler dnshome.de // DotArai : https://www.dotarai.com/ // Submitted by Atsadawat Netcharadsang online.th shop.th // DrayTek Corp. : https://www.draytek.com/ // Submitted by Paul Fang drayddns.com // DreamHost : http://www.dreamhost.com/ // Submitted by Andrew Farmer dreamhosters.com // Drobo : http://www.drobo.com/ // Submitted by Ricardo Padilha mydrobo.com // Drud Holdings, LLC. : https://www.drud.com/ // Submitted by Kevin Bridges drud.io drud.us // DuckDNS : http://www.duckdns.org/ // Submitted by Richard Harper duckdns.org // dy.fi : http://dy.fi/ // Submitted by Heikki Hannikainen dy.fi tunk.org // DynDNS.com : http://www.dyndns.com/services/dns/dyndns/ dyndns-at-home.com dyndns-at-work.com dyndns-blog.com dyndns-free.com dyndns-home.com dyndns-ip.com dyndns-mail.com dyndns-office.com dyndns-pics.com dyndns-remote.com dyndns-server.com dyndns-web.com dyndns-wiki.com dyndns-work.com dyndns.biz dyndns.info dyndns.org dyndns.tv at-band-camp.net ath.cx barrel-of-knowledge.info barrell-of-knowledge.info better-than.tv blogdns.com blogdns.net blogdns.org blogsite.org boldlygoingnowhere.org broke-it.net buyshouses.net cechire.com dnsalias.com dnsalias.net dnsalias.org dnsdojo.com dnsdojo.net dnsdojo.org does-it.net doesntexist.com doesntexist.org dontexist.com dontexist.net dontexist.org doomdns.com doomdns.org dvrdns.org dyn-o-saur.com dynalias.com dynalias.net dynalias.org dynathome.net dyndns.ws endofinternet.net endofinternet.org endoftheinternet.org est-a-la-maison.com est-a-la-masion.com est-le-patron.com est-mon-blogueur.com for-better.biz for-more.biz for-our.info for-some.biz for-the.biz forgot.her.name forgot.his.name from-ak.com from-al.com from-ar.com from-az.net from-ca.com from-co.net from-ct.com from-dc.com from-de.com from-fl.com from-ga.com from-hi.com from-ia.com from-id.com from-il.com from-in.com from-ks.com from-ky.com from-la.net from-ma.com from-md.com from-me.org from-mi.com from-mn.com from-mo.com from-ms.com from-mt.com from-nc.com from-nd.com from-ne.com from-nh.com from-nj.com from-nm.com from-nv.com from-ny.net from-oh.com from-ok.com from-or.com from-pa.com from-pr.com from-ri.com from-sc.com from-sd.com from-tn.com from-tx.com from-ut.com from-va.com from-vt.com from-wa.com from-wi.com from-wv.com from-wy.com ftpaccess.cc fuettertdasnetz.de game-host.org game-server.cc getmyip.com gets-it.net go.dyndns.org gotdns.com gotdns.org groks-the.info groks-this.info ham-radio-op.net here-for-more.info hobby-site.com hobby-site.org home.dyndns.org homedns.org homeftp.net homeftp.org homeip.net homelinux.com homelinux.net homelinux.org homeunix.com homeunix.net homeunix.org iamallama.com in-the-band.net is-a-anarchist.com is-a-blogger.com is-a-bookkeeper.com is-a-bruinsfan.org is-a-bulls-fan.com is-a-candidate.org is-a-caterer.com is-a-celticsfan.org is-a-chef.com is-a-chef.net is-a-chef.org is-a-conservative.com is-a-cpa.com is-a-cubicle-slave.com is-a-democrat.com is-a-designer.com is-a-doctor.com is-a-financialadvisor.com is-a-geek.com is-a-geek.net is-a-geek.org is-a-green.com is-a-guru.com is-a-hard-worker.com is-a-hunter.com is-a-knight.org is-a-landscaper.com is-a-lawyer.com is-a-liberal.com is-a-libertarian.com is-a-linux-user.org is-a-llama.com is-a-musician.com is-a-nascarfan.com is-a-nurse.com is-a-painter.com is-a-patsfan.org is-a-personaltrainer.com is-a-photographer.com is-a-player.com is-a-republican.com is-a-rockstar.com is-a-socialist.com is-a-soxfan.org is-a-student.com is-a-teacher.com is-a-techie.com is-a-therapist.com is-an-accountant.com is-an-actor.com is-an-actress.com is-an-anarchist.com is-an-artist.com is-an-engineer.com is-an-entertainer.com is-by.us is-certified.com is-found.org is-gone.com is-into-anime.com is-into-cars.com is-into-cartoons.com is-into-games.com is-leet.com is-lost.org is-not-certified.com is-saved.org is-slick.com is-uberleet.com is-very-bad.org is-very-evil.org is-very-good.org is-very-nice.org is-very-sweet.org is-with-theband.com isa-geek.com isa-geek.net isa-geek.org isa-hockeynut.com issmarterthanyou.com isteingeek.de istmein.de kicks-ass.net kicks-ass.org knowsitall.info land-4-sale.us lebtimnetz.de leitungsen.de likes-pie.com likescandy.com merseine.nu mine.nu misconfused.org mypets.ws myphotos.cc neat-url.com office-on-the.net on-the-web.tv podzone.net podzone.org readmyblog.org saves-the-whales.com scrapper-site.net scrapping.cc selfip.biz selfip.com selfip.info selfip.net selfip.org sells-for-less.com sells-for-u.com sells-it.net sellsyourhome.org servebbs.com servebbs.net servebbs.org serveftp.net serveftp.org servegame.org shacknet.nu simple-url.com space-to-rent.com stuff-4-sale.org stuff-4-sale.us teaches-yoga.com thruhere.net traeumtgerade.de webhop.biz webhop.info webhop.net webhop.org worse-than.tv writesthisblog.com // ddnss.de : https://www.ddnss.de/ // Submitted by Robert Niedziela ddnss.de dyn.ddnss.de dyndns.ddnss.de dyndns1.de dyn-ip24.de home-webserver.de dyn.home-webserver.de myhome-server.de ddnss.org // Definima : http://www.definima.com/ // Submitted by Maxence Bitterli definima.net definima.io // dnstrace.pro : https://dnstrace.pro/ // Submitted by Chris Partridge bci.dnstrace.pro // Dynu.com : https://www.dynu.com/ // Submitted by Sue Ye ddnsfree.com ddnsgeek.com giize.com gleeze.com kozow.com loseyourip.com ooguy.com theworkpc.com casacam.net dynu.net accesscam.org camdvr.org freeddns.org mywire.org webredirect.org myddns.rocks blogsite.xyz // dynv6 : https://dynv6.com // Submitted by Dominik Menke dynv6.net // E4YOU spol. s.r.o. : https://e4you.cz/ // Submitted by Vladimir Dudr e4.cz // Enalean SAS: https://www.enalean.com // Submitted by Thomas Cottier mytuleap.com // Enonic : http://enonic.com/ // Submitted by Erik Kaareng-Sunde enonic.io customer.enonic.io // EU.org https://eu.org/ // Submitted by Pierre Beyssac eu.org al.eu.org asso.eu.org at.eu.org au.eu.org be.eu.org bg.eu.org ca.eu.org cd.eu.org ch.eu.org cn.eu.org cy.eu.org cz.eu.org de.eu.org dk.eu.org edu.eu.org ee.eu.org es.eu.org fi.eu.org fr.eu.org gr.eu.org hr.eu.org hu.eu.org ie.eu.org il.eu.org in.eu.org int.eu.org is.eu.org it.eu.org jp.eu.org kr.eu.org lt.eu.org lu.eu.org lv.eu.org mc.eu.org me.eu.org mk.eu.org mt.eu.org my.eu.org net.eu.org ng.eu.org nl.eu.org no.eu.org nz.eu.org paris.eu.org pl.eu.org pt.eu.org q-a.eu.org ro.eu.org ru.eu.org se.eu.org si.eu.org sk.eu.org tr.eu.org uk.eu.org us.eu.org // Evennode : http://www.evennode.com/ // Submitted by Michal Kralik eu-1.evennode.com eu-2.evennode.com eu-3.evennode.com eu-4.evennode.com us-1.evennode.com us-2.evennode.com us-3.evennode.com us-4.evennode.com // eDirect Corp. : https://hosting.url.com.tw/ // Submitted by C.S. chang twmail.cc twmail.net twmail.org mymailer.com.tw url.tw // Facebook, Inc. // Submitted by Peter Ruibal apps.fbsbx.com // FAITID : https://faitid.org/ // Submitted by Maxim Alzoba // https://www.flexireg.net/stat_info ru.net adygeya.ru bashkiria.ru bir.ru cbg.ru com.ru dagestan.ru grozny.ru kalmykia.ru kustanai.ru marine.ru mordovia.ru msk.ru mytis.ru nalchik.ru nov.ru pyatigorsk.ru spb.ru vladikavkaz.ru vladimir.ru abkhazia.su adygeya.su aktyubinsk.su arkhangelsk.su armenia.su ashgabad.su azerbaijan.su balashov.su bashkiria.su bryansk.su bukhara.su chimkent.su dagestan.su east-kazakhstan.su exnet.su georgia.su grozny.su ivanovo.su jambyl.su kalmykia.su kaluga.su karacol.su karaganda.su karelia.su khakassia.su krasnodar.su kurgan.su kustanai.su lenug.su mangyshlak.su mordovia.su msk.su murmansk.su nalchik.su navoi.su north-kazakhstan.su nov.su obninsk.su penza.su pokrovsk.su sochi.su spb.su tashkent.su termez.su togliatti.su troitsk.su tselinograd.su tula.su tuva.su vladikavkaz.su vladimir.su vologda.su // Fancy Bits, LLC : http://getchannels.com // Submitted by Aman Gupta channelsdvr.net // Fastly Inc. : http://www.fastly.com/ // Submitted by Fastly Security fastly-terrarium.com fastlylb.net map.fastlylb.net freetls.fastly.net map.fastly.net a.prod.fastly.net global.prod.fastly.net a.ssl.fastly.net b.ssl.fastly.net global.ssl.fastly.net // FASTVPS EESTI OU : https://fastvps.ru/ // Submitted by Likhachev Vasiliy fastpanel.direct fastvps-server.com // Featherhead : https://featherhead.xyz/ // Submitted by Simon Menke fhapp.xyz // Fedora : https://fedoraproject.org/ // submitted by Patrick Uiterwijk fedorainfracloud.org fedorapeople.org cloud.fedoraproject.org app.os.fedoraproject.org app.os.stg.fedoraproject.org // Fermax : https://fermax.com/ // submitted by Koen Van Isterdael mydobiss.com // Filegear Inc. : https://www.filegear.com // Submitted by Jason Zhu filegear.me filegear-au.me filegear-de.me filegear-gb.me filegear-ie.me filegear-jp.me filegear-sg.me // Firebase, Inc. // Submitted by Chris Raynor firebaseapp.com // Flynn : https://flynn.io // Submitted by Jonathan Rudenberg flynnhub.com flynnhosting.net // Freebox : http://www.freebox.fr // Submitted by Romain Fliedel freebox-os.com freeboxos.com fbx-os.fr fbxos.fr freebox-os.fr freeboxos.fr // freedesktop.org : https://www.freedesktop.org // Submitted by Daniel Stone freedesktop.org // Futureweb OG : http://www.futureweb.at // Submitted by Andreas Schnederle-Wagner *.futurecms.at *.ex.futurecms.at *.in.futurecms.at futurehosting.at futuremailing.at *.ex.ortsinfo.at *.kunden.ortsinfo.at *.statics.cloud // GDS : https://www.gov.uk/service-manual/operations/operating-servicegovuk-subdomains // Submitted by David Illsley service.gov.uk // GitHub, Inc. // Submitted by Patrick Toomey github.io githubusercontent.com // GitLab, Inc. // Submitted by Alex Hanselka gitlab.io // UKHomeOffice : https://www.gov.uk/government/organisations/home-office // Submitted by Jon Shanks homeoffice.gov.uk // GlobeHosting, Inc. // Submitted by Zoltan Egresi ro.im shop.ro // GoIP DNS Services : http://www.goip.de // Submitted by Christian Poulter goip.de // Google, Inc. // Submitted by Eduardo Vela run.app a.run.app *.0emm.com appspot.com blogspot.ae blogspot.al blogspot.am blogspot.ba blogspot.be blogspot.bg blogspot.bj blogspot.ca blogspot.cf blogspot.ch blogspot.cl blogspot.co.at blogspot.co.id blogspot.co.il blogspot.co.ke blogspot.co.nz blogspot.co.uk blogspot.co.za blogspot.com blogspot.com.ar blogspot.com.au blogspot.com.br blogspot.com.by blogspot.com.co blogspot.com.cy blogspot.com.ee blogspot.com.eg blogspot.com.es blogspot.com.mt blogspot.com.ng blogspot.com.tr blogspot.com.uy blogspot.cv blogspot.cz blogspot.de blogspot.dk blogspot.fi blogspot.fr blogspot.gr blogspot.hk blogspot.hr blogspot.hu blogspot.ie blogspot.in blogspot.is blogspot.it blogspot.jp blogspot.kr blogspot.li blogspot.lt blogspot.lu blogspot.md blogspot.mk blogspot.mr blogspot.mx blogspot.my blogspot.nl blogspot.no blogspot.pe blogspot.pt blogspot.qa blogspot.re blogspot.ro blogspot.rs blogspot.ru blogspot.se blogspot.sg blogspot.si blogspot.sk blogspot.sn blogspot.td blogspot.tw blogspot.ug blogspot.vn cloudfunctions.net cloud.goog codespot.com googleapis.com googlecode.com pagespeedmobilizer.com publishproxy.com withgoogle.com withyoutube.com // Hashbang : https://hashbang.sh hashbang.sh // Hasura : https://hasura.io // Submitted by Shahidh K Muhammed hasura.app hasura-app.io // Hepforge : https://www.hepforge.org // Submitted by David Grellscheid hepforge.org // Heroku : https://www.heroku.com/ // Submitted by Tom Maher herokuapp.com herokussl.com // Hibernating Rhinos // Submitted by Oren Eini myravendb.com ravendb.community ravendb.me development.run ravendb.run // Ici la Lune : http://www.icilalune.com/ // Submitted by Simon Morvan moonscale.net // iki.fi // Submitted by Hannu Aronsson iki.fi // Individual Network Berlin e.V. : https://www.in-berlin.de/ // Submitted by Christian Seitz dyn-berlin.de in-berlin.de in-brb.de in-butter.de in-dsl.de in-dsl.net in-dsl.org in-vpn.de in-vpn.net in-vpn.org // info.at : http://www.info.at/ biz.at info.at // info.cx : http://info.cx // Submitted by Jacob Slater info.cx // Interlegis : http://www.interlegis.leg.br // Submitted by Gabriel Ferreira ac.leg.br al.leg.br am.leg.br ap.leg.br ba.leg.br ce.leg.br df.leg.br es.leg.br go.leg.br ma.leg.br mg.leg.br ms.leg.br mt.leg.br pa.leg.br pb.leg.br pe.leg.br pi.leg.br pr.leg.br rj.leg.br rn.leg.br ro.leg.br rr.leg.br rs.leg.br sc.leg.br se.leg.br sp.leg.br to.leg.br // intermetrics GmbH : https://pixolino.com/ // Submitted by Wolfgang Schwarz pixolino.com // IPiFony Systems, Inc. : https://www.ipifony.com/ // Submitted by Matthew Hardeman ipifony.net // IServ GmbH : https://iserv.eu // Submitted by Kim-Alexander Brodowski mein-iserv.de test-iserv.de // Jino : https://www.jino.ru // Submitted by Sergey Ulyashin myjino.ru *.hosting.myjino.ru *.landing.myjino.ru *.spectrum.myjino.ru *.vps.myjino.ru // Joyent : https://www.joyent.com/ // Submitted by Brian Bennett *.triton.zone *.cns.joyent.com // JS.ORG : http://dns.js.org // Submitted by Stefan Keim js.org // Keyweb AG : https://www.keyweb.de // Submitted by Martin Dannehl keymachine.de // KnightPoint Systems, LLC : http://www.knightpoint.com/ // Submitted by Roy Keene knightpoint.systems // .KRD : http://nic.krd/data/krd/Registration%20Policy.pdf co.krd edu.krd // LCube - Professional hosting e.K. : https://www.lcube-webhosting.de // Submitted by Lars Laehn git-repos.de lcube-server.de svn-repos.de // Leadpages : https://www.leadpages.net // Submitted by Greg Dallavalle leadpages.co lpages.co lpusercontent.com // Lifetime Hosting : https://Lifetime.Hosting/ // Submitted by Mike Fillator co.business co.education co.events co.financial co.network co.place co.technology // Lightmaker Property Manager, Inc. : https://app.lmpm.com/ // Submitted by Greg Holland app.lmpm.com // Linki Tools UG : https://linki.tools // Submitted by Paulo Matos linkitools.space // linkyard ldt: https://www.linkyard.ch/ // Submitted by Mario Siegenthaler linkyard.cloud linkyard-cloud.ch // LiquidNet Ltd : http://www.liquidnetlimited.com/ // Submitted by Victor Velchev we.bs // LubMAN UMCS Sp. z o.o : https://lubman.pl/ // Submitted by Ireneusz Maliszewski krasnik.pl leczna.pl lubartow.pl lublin.pl poniatowa.pl swidnik.pl // Lug.org.uk : https://lug.org.uk // Submitted by Jon Spriggs uklugs.org glug.org.uk lug.org.uk lugs.org.uk // Lukanet Ltd : https://lukanet.com // Submitted by Anton Avramov barsy.bg barsy.co.uk barsyonline.co.uk barsycenter.com barsyonline.com barsy.club barsy.de barsy.eu barsy.in barsy.info barsy.io barsy.me barsy.menu barsy.mobi barsy.net barsy.online barsy.org barsy.pro barsy.pub barsy.shop barsy.site barsy.support barsy.uk // Magento Commerce // Submitted by Damien Tournoud *.magentosite.cloud // May First - People Link : https://mayfirst.org/ // Submitted by Jamie McClelland mayfirst.info mayfirst.org // Mail.Ru Group : https://hb.cldmail.ru // Submitted by Ilya Zaretskiy hb.cldmail.ru // Memset hosting : https://www.memset.com // Submitted by Tom Whitwell miniserver.com memset.net // MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/ // Submitted by Zdeněk Šustr cloud.metacentrum.cz custom.metacentrum.cz // MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/ // Submitted by Radim Janča flt.cloud.muni.cz usr.cloud.muni.cz // Meteor Development Group : https://www.meteor.com/hosting // Submitted by Pierre Carrier meteorapp.com eu.meteorapp.com // Michau Enterprises Limited : http://www.co.pl/ co.pl // Microsoft Corporation : http://microsoft.com // Submitted by Justin Luk azurecontainer.io azurewebsites.net azure-mobile.net cloudapp.net // Mozilla Corporation : https://mozilla.com // Submitted by Ben Francis mozilla-iot.org // Mozilla Foundation : https://mozilla.org/ // Submitted by glob bmoattachments.org // MSK-IX : https://www.msk-ix.ru/ // Submitted by Khannanov Roman net.ru org.ru pp.ru // Netlify : https://www.netlify.com // Submitted by Jessica Parsons bitballoon.com netlify.com // Neustar Inc. // Submitted by Trung Tran 4u.com // ngrok : https://ngrok.com/ // Submitted by Alan Shreve ngrok.io // Nimbus Hosting Ltd. : https://www.nimbushosting.co.uk/ // Submitted by Nicholas Ford nh-serv.co.uk // NFSN, Inc. : https://www.NearlyFreeSpeech.NET/ // Submitted by Jeff Wheelhouse nfshost.com // Now-DNS : https://now-dns.com // Submitted by Steve Russell dnsking.ch mypi.co n4t.co 001www.com ddnslive.com myiphost.com forumz.info 16-b.it 32-b.it 64-b.it soundcast.me tcp4.me dnsup.net hicam.net now-dns.net ownip.net vpndns.net dynserv.org now-dns.org x443.pw now-dns.top ntdll.top freeddns.us crafting.xyz zapto.xyz // nsupdate.info : https://www.nsupdate.info/ // Submitted by Thomas Waldmann nsupdate.info nerdpol.ovh // No-IP.com : https://noip.com/ // Submitted by Deven Reza blogsyte.com brasilia.me cable-modem.org ciscofreak.com collegefan.org couchpotatofries.org damnserver.com ddns.me ditchyourip.com dnsfor.me dnsiskinky.com dvrcam.info dynns.com eating-organic.net fantasyleague.cc geekgalaxy.com golffan.us health-carereform.com homesecuritymac.com homesecuritypc.com hopto.me ilovecollege.info loginto.me mlbfan.org mmafan.biz myactivedirectory.com mydissent.net myeffect.net mymediapc.net mypsx.net mysecuritycamera.com mysecuritycamera.net mysecuritycamera.org net-freaks.com nflfan.org nhlfan.net no-ip.ca no-ip.co.uk no-ip.net noip.us onthewifi.com pgafan.net point2this.com pointto.us privatizehealthinsurance.net quicksytes.com read-books.org securitytactics.com serveexchange.com servehumour.com servep2p.com servesarcasm.com stufftoread.com ufcfan.org unusualperson.com workisboring.com 3utilities.com bounceme.net ddns.net ddnsking.com gotdns.ch hopto.org myftp.biz myftp.org myvnc.com no-ip.biz no-ip.info no-ip.org noip.me redirectme.net servebeer.com serveblog.net servecounterstrike.com serveftp.com servegame.com servehalflife.com servehttp.com serveirc.com serveminecraft.net servemp3.com servepics.com servequake.com sytes.net webhop.me zapto.org // NodeArt : https://nodeart.io // Submitted by Konstantin Nosov stage.nodeart.io // Nodum B.V. : https://nodum.io/ // Submitted by Wietse Wind nodum.co nodum.io // Nucleos Inc. : https://nucleos.com // Submitted by Piotr Zduniak pcloud.host // NYC.mn : http://www.information.nyc.mn // Submitted by Matthew Brown nyc.mn // NymNom : https://nymnom.com/ // Submitted by Dave McCormack nom.ae nom.af nom.ai nom.al nym.by nym.bz nom.cl nom.gd nom.ge nom.gl nym.gr nom.gt nym.gy nom.hn nym.ie nom.im nom.ke nym.kz nym.la nym.lc nom.li nym.li nym.lt nym.lu nym.me nom.mk nym.mn nym.mx nom.nu nym.nz nym.pe nym.pt nom.pw nom.qa nym.ro nom.rs nom.si nym.sk nom.st nym.su nym.sx nom.tj nym.tw nom.ug nom.uy nom.vc nom.vg // Octopodal Solutions, LLC. : https://ulterius.io/ // Submitted by Andrew Sampson cya.gg // Omnibond Systems, LLC. : https://www.omnibond.com // Submitted by Cole Estep cloudycluster.net // One Fold Media : http://www.onefoldmedia.com/ // Submitted by Eddie Jones nid.io // OpenCraft GmbH : http://opencraft.com/ // Submitted by Sven Marnach opencraft.hosting // Opera Software, A.S.A. // Submitted by Yngve Pettersen operaunite.com // OutSystems // Submitted by Duarte Santos outsystemscloud.com // OwnProvider GmbH: http://www.ownprovider.com // Submitted by Jan Moennich ownprovider.com own.pm // OX : http://www.ox.rs // Submitted by Adam Grand ox.rs // oy.lc // Submitted by Charly Coste oy.lc // Pagefog : https://pagefog.com/ // Submitted by Derek Myers pgfog.com // Pagefront : https://www.pagefronthq.com/ // Submitted by Jason Kriss pagefrontapp.com // .pl domains (grandfathered) art.pl gliwice.pl krakow.pl poznan.pl wroc.pl zakopane.pl // Pantheon Systems, Inc. : https://pantheon.io/ // Submitted by Gary Dylina pantheonsite.io gotpantheon.com // Peplink | Pepwave : http://peplink.com/ // Submitted by Steve Leung mypep.link // Planet-Work : https://www.planet-work.com/ // Submitted by Frédéric VANNIÈRE on-web.fr // Platform.sh : https://platform.sh // Submitted by Nikola Kotur *.platform.sh *.platformsh.site // prgmr.com : https://prgmr.com/ // Submitted by Sarah Newman xen.prgmr.com // priv.at : http://www.nic.priv.at/ // Submitted by registry priv.at // Protonet GmbH : http://protonet.io // Submitted by Martin Meier protonet.io // Publication Presse Communication SARL : https://ppcom.fr // Submitted by Yaacov Akiba Slama chirurgiens-dentistes-en-france.fr byen.site // Redstar Consultants : https://www.redstarconsultants.com/ // Submitted by Jons Slemmer instantcloud.cn // Russian Academy of Sciences // Submitted by Tech Support ras.ru // QA2 // Submitted by Daniel Dent (https://www.danieldent.com/) qa2.com // QNAP System Inc : https://www.qnap.com // Submitted by Nick Chang dev-myqnapcloud.com alpha-myqnapcloud.com myqnapcloud.com // Quip : https://quip.com // Submitted by Patrick Linehan *.quipelements.com // Qutheory LLC : http://qutheory.io // Submitted by Jonas Schwartz vapor.cloud vaporcloud.io // Rackmaze LLC : https://www.rackmaze.com // Submitted by Kirill Pertsev rackmaze.com rackmaze.net // Read The Docs, Inc : https://www.readthedocs.org // Submitted by David Fischer readthedocs.io // Red Hat, Inc. OpenShift : https://openshift.redhat.com/ // Submitted by Tim Kramer rhcloud.com // Resin.io : https://resin.io // Submitted by Tim Perry resindevice.io devices.resinstaging.io // RethinkDB : https://www.rethinkdb.com/ // Submitted by Chris Kastorff hzc.io // Revitalised Limited : http://www.revitalised.co.uk // Submitted by Jack Price wellbeingzone.eu ptplus.fit wellbeingzone.co.uk // Sandstorm Development Group, Inc. : https://sandcats.io/ // Submitted by Asheesh Laroia sandcats.io // SBE network solutions GmbH : https://www.sbe.de/ // Submitted by Norman Meilick logoip.de logoip.com // schokokeks.org GbR : https://schokokeks.org/ // Submitted by Hanno Böck schokokeks.net // Scry Security : http://www.scrysec.com // Submitted by Shante Adam scrysec.com // Securepoint GmbH : https://www.securepoint.de // Submitted by Erik Anders firewall-gateway.com firewall-gateway.de my-gateway.de my-router.de spdns.de spdns.eu firewall-gateway.net my-firewall.org myfirewall.org spdns.org // SensioLabs, SAS : https://sensiolabs.com/ // Submitted by Fabien Potencier *.s5y.io *.sensiosite.cloud // Service Online LLC : http://drs.ua/ // Submitted by Serhii Bulakh biz.ua co.ua pp.ua // ShiftEdit : https://shiftedit.net/ // Submitted by Adam Jimenez shiftedit.io // Shopblocks : http://www.shopblocks.com/ // Submitted by Alex Bowers myshopblocks.com // SinaAppEngine : http://sae.sina.com.cn/ // Submitted by SinaAppEngine 1kapp.com appchizi.com applinzi.com sinaapp.com vipsinaapp.com // Siteleaf : https://www.siteleaf.com/ // Submitted by Skylar Challand siteleaf.net // Skyhat : http://www.skyhat.io // Submitted by Shante Adam bounty-full.com alpha.bounty-full.com beta.bounty-full.com // staticland : https://static.land // Submitted by Seth Vincent static.land dev.static.land sites.static.land // SourceLair PC : https://www.sourcelair.com // Submitted by Antonis Kalipetis apps.lair.io *.stolos.io // SpaceKit : https://www.spacekit.io/ // Submitted by Reza Akhavan spacekit.io // SpeedPartner GmbH: https://www.speedpartner.de/ // Submitted by Stefan Neufeind customer.speedpartner.de // Standard Library : https://stdlib.com // Submitted by Jacob Lee api.stdlib.com // Storj Labs Inc. : https://storj.io/ // Submitted by Philip Hutchins storj.farm // Studenten Net Twente : http://www.snt.utwente.nl/ // Submitted by Silke Hofstra utwente.io // Sub 6 Limited: http://www.sub6.com // Submitted by Dan Miller temp-dns.com // Swisscom Application Cloud: https://developer.swisscom.com // Submitted by Matthias.Winzeler applicationcloud.io scapp.io // Synology, Inc. : https://www.synology.com/ // Submitted by Rony Weng diskstation.me dscloud.biz dscloud.me dscloud.mobi dsmynas.com dsmynas.net dsmynas.org familyds.com familyds.net familyds.org i234.me myds.me synology.me vpnplus.to // TAIFUN Software AG : http://taifun-software.de // Submitted by Bjoern Henke taifun-dns.de // TASK geographical domains (www.task.gda.pl/uslugi/dns) gda.pl gdansk.pl gdynia.pl med.pl sopot.pl // Telebit : https://telebit.cloud // Submitted by AJ ONeal telebit.app telebit.io *.telebit.xyz // The Gwiddle Foundation : https://gwiddlefoundation.org.uk // Submitted by Joshua Bayfield gwiddle.co.uk // Thingdust AG : https://thingdust.com/ // Submitted by Adrian Imboden cust.dev.thingdust.io cust.disrec.thingdust.io cust.prod.thingdust.io cust.testing.thingdust.io // TownNews.com : http://www.townnews.com // Submitted by Dustin Ward bloxcms.com townnews-staging.com // TrafficPlex GmbH : https://www.trafficplex.de/ // Submitted by Phillipp Röll 12hp.at 2ix.at 4lima.at lima-city.at 12hp.ch 2ix.ch 4lima.ch lima-city.ch trafficplex.cloud de.cool 12hp.de 2ix.de 4lima.de lima-city.de 1337.pictures clan.rip lima-city.rocks webspace.rocks lima.zone // TransIP : https://www.transip.nl // Submitted by Rory Breuk *.transurl.be *.transurl.eu *.transurl.nl // TuxFamily : http://tuxfamily.org // Submitted by TuxFamily administrators tuxfamily.org // TwoDNS : https://www.twodns.de/ // Submitted by TwoDNS-Support dd-dns.de diskstation.eu diskstation.org dray-dns.de draydns.de dyn-vpn.de dynvpn.de mein-vigor.de my-vigor.de my-wan.de syno-ds.de synology-diskstation.de synology-ds.de // Uberspace : https://uberspace.de // Submitted by Moritz Werner uber.space *.uberspace.de // UDR Limited : http://www.udr.hk.com // Submitted by registry hk.com hk.org ltd.hk inc.hk // United Gameserver GmbH : https://united-gameserver.de // Submitted by Stefan Schwarz virtualuser.de virtual-user.de // .US // Submitted by Ed Moore lib.de.us // VeryPositive SIA : http://very.lv // Submitted by Danko Aleksejevs 2038.io // Viprinet Europe GmbH : http://www.viprinet.com // Submitted by Simon Kissel router.management // Virtual-Info : https://www.virtual-info.info/ // Submitted by Adnan RIHAN v-info.info // WeDeploy by Liferay, Inc. : https://www.wedeploy.com // Submitted by Henrique Vicente wedeploy.io wedeploy.me wedeploy.sh // Western Digital Technologies, Inc : https://www.wdc.com // Submitted by Jung Jin remotewd.com // Wikimedia Labs : https://wikitech.wikimedia.org // Submitted by Yuvi Panda wmflabs.org // XenonCloud GbR: https://xenoncloud.net // Submitted by Julian Uphoff half.host // XnBay Technology : http://www.xnbay.com/ // Submitted by XnBay Developer xnbay.com u2.xnbay.com u2-local.xnbay.com // XS4ALL Internet bv : https://www.xs4all.nl/ // Submitted by Daniel Mostertman cistron.nl demon.nl xs4all.space // YesCourse Pty Ltd : https://yescourse.com // Submitted by Atul Bhouraskar official.academy // Yola : https://www.yola.com/ // Submitted by Stefano Rivera yolasite.com // Yombo : https://yombo.net // Submitted by Mitch Schwenk ybo.faith yombo.me homelink.one ybo.party ybo.review ybo.science ybo.trade // Yunohost : https://yunohost.org // Submitted by Valentin Grimaud nohost.me noho.st // ZaNiC : http://www.za.net/ // Submitted by registry za.net za.org // Zeit, Inc. : https://zeit.domains/ // Submitted by Olli Vanhoja now.sh // Zine EOOD : https://zine.bg/ // Submitted by Martin Angelov bss.design // Zone.id : https://zone.id/ // Submitted by Su Hendro zone.id // ===END PRIVATE DOMAINS=== END_BUILTIN_DATA 1; PKH]'s,s,Socket/SSL/Intercept.pmnu[ package IO::Socket::SSL::Intercept; use strict; use warnings; use Carp 'croak'; use IO::Socket::SSL::Utils; use Net::SSLeay; our $VERSION = '2.056'; sub new { my ($class,%args) = @_; my $cacert = delete $args{proxy_cert}; if ( ! $cacert ) { if ( my $f = delete $args{proxy_cert_file} ) { $cacert = PEM_file2cert($f); } else { croak "no proxy_cert or proxy_cert_file given"; } } my $cakey = delete $args{proxy_key}; if ( ! $cakey ) { if ( my $f = delete $args{proxy_key_file} ) { $cakey = PEM_file2key($f); } else { croak "no proxy_cert or proxy_cert_file given"; } } my $certkey = delete $args{cert_key}; if ( ! $certkey ) { if ( my $f = delete $args{cert_key_file} ) { $certkey = PEM_file2key($f); } } my $cache = delete $args{cache} || {}; if (ref($cache) eq 'CODE') { # check cache type my $type = $cache->('type'); if (!$type) { # old cache interface - change into new interface # get: $cache->(fp) # set: $cache->(fp,cert,key) my $oc = $cache; $cache = sub { my ($fp,$create_cb) = @_; my @ck = $oc->($fp); $oc->($fp, @ck = &$create_cb) if !@ck; return @ck; }; } elsif ($type == 1) { # current interface: # get/set: $cache->(fp,cb_create) } else { die "invalid type of cache: $type"; } } my $self = bless { cacert => $cacert, cakey => $cakey, certkey => $certkey, cache => $cache, serial => delete $args{serial}, }; return $self; } sub DESTROY { # call various ssl _free routines my $self = shift or return; for ( \$self->{cacert}, map { \$_->{cert} } ref($self->{cache}) ne 'CODE' ? values %{$self->{cache}} :()) { $$_ or next; CERT_free($$_); $$_ = undef; } for ( \$self->{cakey}, \$self->{pubkey} ) { $$_ or next; KEY_free($$_); $$_ = undef; } } sub clone_cert { my ($self,$old_cert,$clone_key) = @_; my $hash = CERT_asHash($old_cert); my $create_cb = sub { # if not in cache create new certificate based on original # copy most but not all extensions if (my $ext = $hash->{ext}) { @$ext = grep { defined($_->{sn}) && $_->{sn} !~m{^(?: authorityInfoAccess | subjectKeyIdentifier | authorityKeyIdentifier | certificatePolicies | crlDistributionPoints )$}x } @$ext; } my ($clone,$key) = CERT_create( %$hash, issuer_cert => $self->{cacert}, issuer_key => $self->{cakey}, key => $self->{certkey}, serial => ! defined($self->{serial}) ? (unpack('L',$hash->{x509_digest_sha256}))[0] : ref($self->{serial}) eq 'CODE' ? $self->{serial}($old_cert,$hash) : ++$self->{serial}, ); return ($clone,$key); }; $clone_key ||= substr(unpack("H*", $hash->{x509_digest_sha256}),0,32); my $c = $self->{cache}; return $c->($clone_key,$create_cb) if ref($c) eq 'CODE'; my $e = $c->{$clone_key} ||= do { my ($cert,$key) = &$create_cb; { cert => $cert, key => $key }; }; $e->{atime} = time(); return ($e->{cert},$e->{key}); } sub STORABLE_freeze { my $self = shift; $self->serialize() } sub STORABLE_thaw { my ($class,undef,$data) = @_; $class->unserialize($data) } sub serialize { my $self = shift; my $data = pack("N",2); # version $data .= pack("N/a", PEM_cert2string($self->{cacert})); $data .= pack("N/a", PEM_key2string($self->{cakey})); if ( $self->{certkey} ) { $data .= pack("N/a", PEM_key2string($self->{certkey})); } else { $data .= pack("N/a", ''); } $data .= pack("N",$self->{serial}); if ( ref($self->{cache}) eq 'HASH' ) { while ( my($k,$v) = each %{ $self->{cache}} ) { $data .= pack("N/aN/aN/aN", $k, PEM_cert2string($k->{cert}), $k->{key} ? PEM_key2string($k->{key}) : '', $k->{atime}); } } return $data; } sub unserialize { my ($class,$data) = @_; unpack("N",substr($data,0,4,'')) == 2 or croak("serialized with wrong version"); ( my $cacert,my $cakey,my $certkey,my $serial,$data) = unpack("N/aN/aN/aNa*",$data); my $self = bless { serial => $serial, cacert => PEM_string2cert($cacert), cakey => PEM_string2key($cakey), $certkey ? ( certkey => PEM_string2key($certkey)):(), }, ref($class)||$class; $self->{cache} = {} if $data ne ''; while ( $data ne '' ) { (my $key,my $cert,my $certkey, my $atime,$data) = unpack("N/aN/aNa*",$data); $self->{cache}{$key} = { cert => PEM_string2cert($cert), $key ? ( key => PEM_string2key($certkey)):(), atime => $atime }; } return $self; } 1; __END__ =head1 NAME IO::Socket::SSL::Intercept -- SSL interception (man in the middle) =head1 SYNOPSIS use IO::Socket::SSL::Intercept; # create interceptor with proxy certificates my $mitm = IO::Socket::SSL::Intercept->new( proxy_cert_file => 'proxy_cert.pem', proxy_key_file => 'proxy_key.pem', ... ); my $listen = IO::Socket::INET->new( LocalAddr => .., Listen => .. ); while (1) { # TCP accept new client my $client = $listen->accept or next; # SSL connect to server my $server = IO::Socket::SSL->new( PeerAddr => .., SSL_verify_mode => ..., ... ) or die "ssl connect failed: $!,$SSL_ERROR"; # clone server certificate my ($cert,$key) = $mitm->clone_cert( $server->peer_certificate ); # and upgrade client side to SSL with cloned certificate IO::Socket::SSL->start_SSL($client, SSL_server => 1, SSL_cert => $cert, SSL_key => $key ) or die "upgrade failed: $SSL_ERROR"; # now transfer data between $client and $server and analyze # the unencrypted data ... } =head1 DESCRIPTION This module provides functionality to clone certificates and sign them with a proxy certificate, thus making it easy to intercept SSL connections (man in the middle). It also manages a cache of the generated certificates. =head1 How Intercepting SSL Works Intercepting SSL connections is useful for analyzing encrypted traffic for security reasons or for testing. It does not break the end-to-end security of SSL, e.g. a properly written client will notice the interception unless you explicitly configure the client to trust your interceptor. Intercepting SSL works the following way: =over 4 =item * Create a new CA certificate, which will be used to sign the cloned certificates. This proxy CA certificate should be trusted by the client, or (a properly written client) will throw error messages or deny the connections because it detected a man in the middle attack. Due to the way the interception works there no support for client side certificates is possible. Using openssl such a proxy CA certificate and private key can be created with: openssl genrsa -out proxy_key.pem 1024 openssl req -new -x509 -extensions v3_ca -key proxy_key.pem -out proxy_cert.pem # export as PKCS12 for import into browser openssl pkcs12 -export -in proxy_cert.pem -inkey proxy_key.pem -out proxy_cert.p12 =item * Configure client to connect to use intercepting proxy or somehow redirect connections from client to the proxy (e.g. packet filter redirects, ARP or DNS spoofing etc). =item * Accept the TCP connection from the client, e.g. don't do any SSL handshakes with the client yet. =item * Establish the SSL connection to the server and verify the servers certificate as usually. Then create a new certificate based on the original servers certificate, but signed by your proxy CA. This is the step where IO::Socket::SSL::Intercept helps. =item * Upgrade the TCP connection to the client to SSL using the cloned certificate from the server. If the client trusts your proxy CA it will accept the upgrade to SSL. =item * Transfer data between client and server. While the connections to client and server are both encrypted with SSL you will read/write the unencrypted data in your proxy application. =back =head1 METHODS IO::Socket::SSL::Intercept helps creating the cloned certificate with the following methods: =over 4 =item B<< $mitm = IO::Socket::SSL::Intercept->new(%args) >> This creates a new interceptor object. C<%args> should be =over 8 =item proxy_cert X509 | proxy_cert_file filename This is the proxy certificate. It can be either given by an X509 object from Ls internal representation, or using a file in PEM format. =item proxy_key EVP_PKEY | proxy_key_file filename This is the key for the proxy certificate. It can be either given by an EVP_PKEY object from Ls internal representation, or using a file in PEM format. The key should not have a passphrase. =item pubkey EVP_PKEY | pubkey_file filename This optional argument specifies the public key used for the cloned certificate. It can be either given by an EVP_PKEY object from Ls internal representation, or using a file in PEM format. If not given it will create a new public key on each call of C. =item serial INTEGER|CODE This optional argument gives the starting point for the serial numbers of the newly created certificates. If not set the serial number will be created based on the digest of the original certificate. If the value is code it will be called with C<< serial(original_cert,CERT_asHash(original_cert)) >> and should return the new serial number. =item cache HASH | SUBROUTINE This optional argument gives a way to cache created certificates, so that they don't get recreated on future accesses to the same host. If the argument ist not given an internal HASH ist used. If the argument is a hash it will store for each generated certificate a hash reference with C and C in the hash, where C is the time of last access (to expire unused entries) and C is the certificate. Please note, that the certificate is in Ls internal X509 format and can thus not be simply dumped and restored. The key for the hash is an C either given to C or generated from the original certificate. If the argument is a subroutine it will be called as C<< $cache->(ident,sub) >>. This call should return either an existing (cached) C<< (cert,key) >> or call C without arguments to create a new C<< (cert,key) >>, store it and return it. If called with C<< $cache->('type') >> the function should just return 1 to signal that it supports the current type of cache. If it reutrns nothing instead the older cache interface is assumed for compatibility reasons. =back =item B<< ($clone_cert,$key) = $mitm->clone_cert($original_cert,[ $ident ]) >> This clones the given certificate. An ident as the key into the cache can be given (like C), if not it will be created from the properties of the original certificate. It returns the cloned certificate and its key (which is the same for alle created certificates). =item B<< $string = $mitm->serialize >> This creates a serialized version of the object (e.g. a string) which can then be used to persistantly store created certificates over restarts of the application. The cache will only be serialized if it is a HASH. To work together with L the C function is defined to call C. =item B<< $mitm = IO::Socket::SSL::Intercept->unserialize($string) >> This restores an Intercept object from a serialized string. To work together with L the C function is defined to call C. =back =head1 AUTHOR Steffen Ullrich PKH]9 mEmEHTML.pmnu[#--------------------------------------------------------------------- package IO::HTML; # # Copyright 2014 Christopher J. Madsen # # Author: Christopher J. Madsen # Created: 14 Jan 2012 # # This program is free software; you can redistribute it and/or modify # it under the same terms as Perl itself. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the # GNU General Public License or the Artistic License for more details. # # ABSTRACT: Open an HTML file with automatic charset detection #--------------------------------------------------------------------- use 5.008; use strict; use warnings; use Carp 'croak'; use Encode 2.10 qw(decode find_encoding); # need utf-8-strict encoding use Exporter 5.57 'import'; our $VERSION = '1.001'; # This file is part of IO-HTML 1.001 (June 28, 2014) our $default_encoding ||= 'cp1252'; our @EXPORT = qw(html_file); our @EXPORT_OK = qw(find_charset_in html_file_and_encoding html_outfile sniff_encoding); our %EXPORT_TAGS = ( rw => [qw( html_file html_file_and_encoding html_outfile )], all => [ @EXPORT, @EXPORT_OK ], ); #===================================================================== sub html_file { (&html_file_and_encoding)[0]; # return just the filehandle } # end html_file # Note: I made html_file and html_file_and_encoding separate functions # (instead of making html_file context-sensitive) because I wanted to # use html_file in function calls (i.e. list context) without having # to write "scalar html_file" all the time. sub html_file_and_encoding { my ($filename, $options) = @_; $options ||= {}; open(my $in, '<:raw', $filename) or croak "Failed to open $filename: $!"; my ($encoding, $bom) = sniff_encoding($in, $filename, $options); if (not defined $encoding) { croak "No default encoding specified" unless defined($encoding = $default_encoding); $encoding = find_encoding($encoding) if $options->{encoding}; } # end if we didn't find an encoding binmode $in, sprintf(":encoding(%s):crlf", $options->{encoding} ? $encoding->name : $encoding); return ($in, $encoding, $bom); } # end html_file_and_encoding #--------------------------------------------------------------------- sub html_outfile { my ($filename, $encoding, $bom) = @_; if (not defined $encoding) { croak "No default encoding specified" unless defined($encoding = $default_encoding); } # end if we didn't find an encoding elsif (ref $encoding) { $encoding = $encoding->name; } open(my $out, ">:encoding($encoding)", $filename) or croak "Failed to open $filename: $!"; print $out "\x{FeFF}" if $bom; return $out; } # end html_outfile #--------------------------------------------------------------------- sub sniff_encoding { my ($in, $filename, $options) = @_; $filename = 'file' unless defined $filename; $options ||= {}; my $pos = tell $in; croak "Could not seek $filename: $!" if $pos < 0; croak "Could not read $filename: $!" unless defined read $in, my $buf, 1024; seek $in, $pos, 0 or croak "Could not seek $filename: $!"; # Check for BOM: my $bom; my $encoding = do { if ($buf =~ /^\xFe\xFF/) { $bom = 2; 'UTF-16BE'; } elsif ($buf =~ /^\xFF\xFe/) { $bom = 2; 'UTF-16LE'; } elsif ($buf =~ /^\xEF\xBB\xBF/) { $bom = 3; 'utf-8-strict'; } else { find_charset_in($buf, $options); # check for } }; # end $encoding if ($bom) { seek $in, $bom, 1 or croak "Could not seek $filename: $!"; $bom = 1; } elsif (not defined $encoding) { # try decoding as UTF-8 my $test = decode('utf-8-strict', $buf, Encode::FB_QUIET); if ($buf =~ /^(?: # nothing left over | [\xC2-\xDF] # incomplete 2-byte char | [\xE0-\xEF] [\x80-\xBF]? # incomplete 3-byte char | [\xF0-\xF4] [\x80-\xBF]{0,2} # incomplete 4-byte char )\z/x and $test =~ /[^\x00-\x7F]/) { $encoding = 'utf-8-strict'; } # end if valid UTF-8 with at least one multi-byte character: } # end if testing for UTF-8 if (defined $encoding and $options->{encoding} and not ref $encoding) { $encoding = find_encoding($encoding); } # end if $encoding is a string and we want an object return wantarray ? ($encoding, $bom) : $encoding; } # end sniff_encoding #===================================================================== # Based on HTML5 8.2.2.2 Determining the character encoding: # Get attribute from current position of $_ sub _get_attribute { m!\G[\x09\x0A\x0C\x0D /]+!gc; # skip whitespace or / return if /\G>/gc or not /\G(=?[^\x09\x0A\x0C\x0D =]*)/gc; my ($name, $value) = (lc $1, ''); if (/\G[\x09\x0A\x0C\x0D ]*=[\x09\x0A\x0C\x0D ]*/gc and (/\G"([^"]*)"?/gc or /\G'([^']*)'?/gc or /\G([^\x09\x0A\x0C\x0D >]*)/gc)) { $value = lc $1; } # end if attribute has value return wantarray ? ($name, $value) : 1; } # end _get_attribute # Examine a meta value for a charset: sub _get_charset_from_meta { for (shift) { while (/charset[\x09\x0A\x0C\x0D ]*=[\x09\x0A\x0C\x0D ]*/ig) { return $1 if (/\G"([^"]*)"/gc or /\G'([^']*)'/gc or /\G(?!['"])([^\x09\x0A\x0C\x0D ;]+)/gc); } } # end for value return undef; } # end _get_charset_from_meta #--------------------------------------------------------------------- sub find_charset_in { for (shift) { my $options = shift || {}; my $stop = length > 1024 ? 1024 : length; # search first 1024 bytes my $expect_pragma = (defined $options->{need_pragma} ? $options->{need_pragma} : 1); pos() = 0; while (pos() < $stop) { if (/\G