epp-client-base 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +5 -0
- data/Gemfile +6 -0
- data/MIT-LICENSE +19 -0
- data/README +5 -0
- data/Rakefile +37 -0
- data/epp-client-base.gemspec +54 -0
- data/lib/epp-client/base.rb +113 -0
- data/lib/epp-client/connection.rb +78 -0
- data/lib/epp-client/contact.rb +398 -0
- data/lib/epp-client/domain.rb +394 -0
- data/lib/epp-client/exceptions.rb +21 -0
- data/lib/epp-client/poll.rb +69 -0
- data/lib/epp-client/session.rb +56 -0
- data/lib/epp-client/ssl.rb +46 -0
- data/lib/epp-client/version.rb +3 -0
- data/lib/epp-client/xml.rb +150 -0
- data/vendor/ietf/contact-1.0.xsd +388 -0
- data/vendor/ietf/domain-1.0.xsd +430 -0
- data/vendor/ietf/epp-1.0.xsd +444 -0
- data/vendor/ietf/eppcom-1.0.xsd +105 -0
- data/vendor/ietf/host-1.0.xsd +240 -0
- data/vendor/ietf/rfc4310.txt +1235 -0
- data/vendor/ietf/rfc5730.txt +3755 -0
- data/vendor/ietf/rfc5731.txt +2467 -0
- data/vendor/ietf/rfc5732.txt +1627 -0
- data/vendor/ietf/rfc5733.txt +2299 -0
- data/vendor/ietf/rfc5734.txt +731 -0
- data/vendor/ietf/rfc5910.txt +2019 -0
- metadata +143 -0
data/ChangeLog
ADDED
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (C) 2010 Mathieu Arnold, Absolight
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
8
|
+
so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require 'rake'
|
3
|
+
require 'rdoc/task'
|
4
|
+
require 'rubygems/package_task'
|
5
|
+
require "bundler/gem_helper"
|
6
|
+
|
7
|
+
MY_GEMS = Dir['*.gemspec'].map {|g| g.sub(/.*-(.*)\.gemspec/, '\1')}
|
8
|
+
|
9
|
+
MY_GEMS.each do |g|
|
10
|
+
namespace g do
|
11
|
+
Bundler::GemHelper.new(Dir.pwd, "epp-client-#{g}").install
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
namespace :all do
|
16
|
+
task :build => MY_GEMS.map { |f| "#{f}:build" }
|
17
|
+
task :install => MY_GEMS.map { |f| "#{f}:install" }
|
18
|
+
task :release => MY_GEMS.map { |f| "#{f}:release" }
|
19
|
+
end
|
20
|
+
|
21
|
+
task :build => 'all:build'
|
22
|
+
task :install => 'all:install'
|
23
|
+
task :release => 'all:release'
|
24
|
+
|
25
|
+
desc "Generate documentation for the Rails framework"
|
26
|
+
Rake::RDocTask.new do |rdoc|
|
27
|
+
rdoc.rdoc_dir = 'doc/rdoc'
|
28
|
+
rdoc.title = "Documentation"
|
29
|
+
|
30
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
31
|
+
rdoc.options << '--charset' << 'utf-8'
|
32
|
+
|
33
|
+
rdoc.rdoc_files.include('README')
|
34
|
+
rdoc.rdoc_files.include('ChangeLog')
|
35
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
36
|
+
end
|
37
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/epp-client/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = 'epp-client-base'
|
6
|
+
gem.version = EPPClient::VERSION
|
7
|
+
gem.date = '2010-05-14'
|
8
|
+
gem.authors = ['Mathieu Arnold']
|
9
|
+
gem.email = ['m@absolight.fr']
|
10
|
+
gem.description = 'An extensible EPP client library.'
|
11
|
+
gem.summary = 'An extensible EPP client library'
|
12
|
+
gem.homepage = "https://github.com/Absolight/epp-client"
|
13
|
+
|
14
|
+
gem.required_ruby_version = '>= 1.8.7'
|
15
|
+
gem.required_rubygems_version = ">= 1.3.6"
|
16
|
+
|
17
|
+
gem.files = [
|
18
|
+
'ChangeLog',
|
19
|
+
'Gemfile',
|
20
|
+
'MIT-LICENSE',
|
21
|
+
'README',
|
22
|
+
'Rakefile',
|
23
|
+
'epp-client-base.gemspec',
|
24
|
+
'lib/epp-client/base.rb',
|
25
|
+
'lib/epp-client/connection.rb',
|
26
|
+
'lib/epp-client/contact.rb',
|
27
|
+
'lib/epp-client/domain.rb',
|
28
|
+
'lib/epp-client/exceptions.rb',
|
29
|
+
'lib/epp-client/poll.rb',
|
30
|
+
'lib/epp-client/session.rb',
|
31
|
+
'lib/epp-client/ssl.rb',
|
32
|
+
'lib/epp-client/version.rb',
|
33
|
+
'lib/epp-client/xml.rb',
|
34
|
+
'vendor/ietf/contact-1.0.xsd',
|
35
|
+
'vendor/ietf/domain-1.0.xsd',
|
36
|
+
'vendor/ietf/epp-1.0.xsd',
|
37
|
+
'vendor/ietf/eppcom-1.0.xsd',
|
38
|
+
'vendor/ietf/host-1.0.xsd',
|
39
|
+
'vendor/ietf/rfc4310.txt',
|
40
|
+
'vendor/ietf/rfc5730.txt',
|
41
|
+
'vendor/ietf/rfc5731.txt',
|
42
|
+
'vendor/ietf/rfc5732.txt',
|
43
|
+
'vendor/ietf/rfc5733.txt',
|
44
|
+
'vendor/ietf/rfc5734.txt',
|
45
|
+
'vendor/ietf/rfc5910.txt',
|
46
|
+
]
|
47
|
+
|
48
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
49
|
+
gem.require_paths = ['lib']
|
50
|
+
|
51
|
+
gem.add_development_dependency "bundler", ">= 1.0.0"
|
52
|
+
gem.add_dependency('nokogiri', '~> 1.4')
|
53
|
+
gem.add_dependency('builder', '>= 2.1.2')
|
54
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'socket'
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'builder'
|
5
|
+
require 'date'
|
6
|
+
require "epp-client/version"
|
7
|
+
require 'epp-client/xml'
|
8
|
+
require 'epp-client/session'
|
9
|
+
require 'epp-client/connection'
|
10
|
+
require 'epp-client/exceptions'
|
11
|
+
require 'epp-client/ssl'
|
12
|
+
require 'epp-client/poll'
|
13
|
+
require 'epp-client/domain'
|
14
|
+
require 'epp-client/contact'
|
15
|
+
|
16
|
+
module EPPClient
|
17
|
+
class Base
|
18
|
+
|
19
|
+
SCHEMAS = %w[
|
20
|
+
epp-1.0
|
21
|
+
domain-1.0
|
22
|
+
host-1.0
|
23
|
+
contact-1.0
|
24
|
+
]
|
25
|
+
SCHEMAS_EXT_IETF = %w[
|
26
|
+
rgp-1.0
|
27
|
+
]
|
28
|
+
|
29
|
+
EPPClient::SCHEMAS_URL = SCHEMAS.inject({}) do |a,s|
|
30
|
+
a[s.sub(/-1\.0$/, '')] = "urn:ietf:params:xml:ns:#{s}" if s =~ /-1\.0$/
|
31
|
+
a[s] = "urn:ietf:params:xml:ns:#{s}"
|
32
|
+
a
|
33
|
+
end.merge!(SCHEMAS_EXT_IETF.inject({}) do |a,s|
|
34
|
+
a[s.sub(/-1\.0$/, '')] = "urn:ietf:params:xml:ns:#{s}" if s =~ /-1\.0$/
|
35
|
+
a[s] = "urn:ietf:params:xml:ns:#{s}"
|
36
|
+
a
|
37
|
+
end)
|
38
|
+
|
39
|
+
include EPPClient::XML
|
40
|
+
include EPPClient::Session
|
41
|
+
include EPPClient::Connection
|
42
|
+
include EPPClient::SSL
|
43
|
+
include EPPClient::Poll # keep before object definition modules.
|
44
|
+
include EPPClient::Domain
|
45
|
+
include EPPClient::Contact
|
46
|
+
|
47
|
+
attr_accessor :client_id, :password, :server, :port, :services, :lang, :extensions, :version, :context
|
48
|
+
attr_writer :clTRID
|
49
|
+
|
50
|
+
# ==== Required Attributes
|
51
|
+
#
|
52
|
+
# [<tt>:server</tt>] The EPP server to connect to
|
53
|
+
# [<tt>:client_id</tt>]
|
54
|
+
# The tag or username used with <tt><login></tt> requests.
|
55
|
+
# [<tt>:password</tt>] The password used with <tt><login></tt> requests.
|
56
|
+
#
|
57
|
+
# ==== Optional Attributes
|
58
|
+
#
|
59
|
+
# [<tt>:port</tt>]
|
60
|
+
# The EPP standard port is 700. However, you can choose a different port to
|
61
|
+
# use.
|
62
|
+
# [<tt>:clTRID</tt>]
|
63
|
+
# The client transaction identifier is an element that EPP specifies MAY be
|
64
|
+
# used to uniquely identify the command to the server. The string
|
65
|
+
# "-<index>" will be added to it, index being incremented at each command.
|
66
|
+
# Defaults to "test-<pid>-<random>"
|
67
|
+
# [<tt>:lang</tt>] Set custom language attribute. Default is 'en'.
|
68
|
+
# [<tt>:services</tt>]
|
69
|
+
# Use custom EPP services in the <login> frame. The defaults use the EPP
|
70
|
+
# standard domain, contact and host 1.0 services.
|
71
|
+
# [<tt>:extensions</tt>]
|
72
|
+
# URLs to custom extensions to standard EPP. Use these to extend the
|
73
|
+
# standard EPP (e.g., AFNIC, smallregistry uses extensions). Defaults to
|
74
|
+
# none.
|
75
|
+
# [<tt>:version</tt>] Set the EPP version. Defaults to "1.0".
|
76
|
+
# [<tt>:ssl_cert</tt>] The file containing the client certificate.
|
77
|
+
# [<tt>:ssl_key</tt>] The file containing the key of the certificate.
|
78
|
+
def initialize(attrs)
|
79
|
+
unless attrs.key?(:server) && attrs.key?(:client_id) && attrs.key?(:password)
|
80
|
+
raise ArgumentError, "server, client_id and password are required"
|
81
|
+
end
|
82
|
+
|
83
|
+
attrs.each do |k,v|
|
84
|
+
begin
|
85
|
+
self.send("#{k}=", v)
|
86
|
+
rescue NoMethodError
|
87
|
+
raise ArgumentError, "there is no #{k} argument"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
@port ||= 700
|
92
|
+
@lang ||= "en"
|
93
|
+
@services ||= EPPClient::SCHEMAS_URL.values_at('domain', 'contact', 'host')
|
94
|
+
@extensions ||= []
|
95
|
+
@version ||= "1.0"
|
96
|
+
@clTRID ||= "test-#{$$}-#{rand(1000)}"
|
97
|
+
@clTRID_index = 0
|
98
|
+
|
99
|
+
@context ||= OpenSSL::SSL::SSLContext.new
|
100
|
+
|
101
|
+
@logged_in = false
|
102
|
+
end
|
103
|
+
|
104
|
+
def clTRID # :nodoc:
|
105
|
+
@clTRID_index += 1
|
106
|
+
@clTRID + "-#{@clTRID_index}"
|
107
|
+
end
|
108
|
+
|
109
|
+
def debug
|
110
|
+
$DEBUG || ENV['EPP_CLIENT_DEBUG']
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module EPPClient
|
2
|
+
module Connection
|
3
|
+
|
4
|
+
attr_reader :sent_frame, :recv_frame, :srv_version, :srv_lang, :srv_ns, :srv_ext
|
5
|
+
|
6
|
+
# Establishes the connection to the server, if successful, will return the
|
7
|
+
# greeting frame.
|
8
|
+
def open_connection
|
9
|
+
@tcpserver = TCPSocket.new(server, port)
|
10
|
+
@socket = OpenSSL::SSL::SSLSocket.new(@tcpserver, @context)
|
11
|
+
|
12
|
+
# Synchronously close the connection & socket
|
13
|
+
@socket.sync_close
|
14
|
+
|
15
|
+
# Connect
|
16
|
+
@socket.connect
|
17
|
+
|
18
|
+
# Get the initial greeting frame
|
19
|
+
greeting_process(get_frame)
|
20
|
+
end
|
21
|
+
|
22
|
+
def greeting_process(xml)
|
23
|
+
@srv_version = xml.xpath('epp:epp/epp:greeting/epp:svcMenu/epp:version', EPPClient::SCHEMAS_URL).map {|n| n.text}
|
24
|
+
@srv_lang = xml.xpath('epp:epp/epp:greeting/epp:svcMenu/epp:lang', EPPClient::SCHEMAS_URL).map {|n| n.text}
|
25
|
+
@srv_ns = xml.xpath('epp:epp/epp:greeting/epp:svcMenu/epp:objURI', EPPClient::SCHEMAS_URL).map {|n| n.text}
|
26
|
+
if (ext = xml.xpath('epp:epp/epp:greeting/epp:svcMenu/epp:svcExtension/epp:extURI', EPPClient::SCHEMAS_URL)).size > 0
|
27
|
+
@srv_ext = ext.map {|n| n.text}
|
28
|
+
end
|
29
|
+
|
30
|
+
return xml
|
31
|
+
end
|
32
|
+
|
33
|
+
# Gracefully close the connection
|
34
|
+
def close_connection
|
35
|
+
if defined?(@socket) and @socket.is_a?(OpenSSL::SSL::SSLSocket)
|
36
|
+
@socket.close
|
37
|
+
@socket = nil
|
38
|
+
end
|
39
|
+
|
40
|
+
if defined?(@tcpserver) and @tcpserver.is_a?(TCPSocket)
|
41
|
+
@tcpserver.close
|
42
|
+
@tcpserver = nil
|
43
|
+
end
|
44
|
+
|
45
|
+
return true if @tcpserver.nil? and @socket.nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
# Sends a frame and returns the server's answer
|
49
|
+
def send_request(xml)
|
50
|
+
send_frame(xml)
|
51
|
+
get_frame
|
52
|
+
end
|
53
|
+
|
54
|
+
# sends a frame
|
55
|
+
def send_frame(xml)
|
56
|
+
@sent_frame = xml
|
57
|
+
@socket.write([xml.size + 4].pack("N") + xml)
|
58
|
+
sent_frame_to_xml
|
59
|
+
return
|
60
|
+
end
|
61
|
+
|
62
|
+
# gets a frame from the socket and returns the parsed response.
|
63
|
+
def get_frame
|
64
|
+
size = @socket.read(4)
|
65
|
+
if size.nil?
|
66
|
+
if @socket.eof?
|
67
|
+
raise SocketError, "Connection closed by remote server"
|
68
|
+
else
|
69
|
+
raise SocketError, "Error reading frame from remote server"
|
70
|
+
end
|
71
|
+
else
|
72
|
+
size = size.unpack('N')[0]
|
73
|
+
@recv_frame = @socket.read(size - 4)
|
74
|
+
recv_frame_to_xml
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|