Class: Bnet::Authenticator
- Inherits:
-
Object
- Object
- Bnet::Authenticator
- Includes:
- AuthenticatorHelper
- Defined in:
- lib/bnet/authenticator.rb
Overview
The Battle.net authenticator
Instance Attribute Summary collapse
-
#region ⇒ Symbol
readonly
Region.
-
#restorecode ⇒ String
readonly
Restoration code.
-
#secret ⇒ String
readonly
Hexified secret.
-
#serial ⇒ String
readonly
Serial.
Class Method Summary collapse
-
.get_token(secret, timestamp = nil) ⇒ String, Integer
Get token from given secret and timestamp.
-
.request_authenticator(region) ⇒ Bnet::Authenticator
Request a new authenticator from server.
-
.request_server_time(region) ⇒ Integer
Get server’s time.
-
.restore_authenticator(serial, restorecode) ⇒ Bnet::Authenticator
Restore an authenticator from server.
Instance Method Summary collapse
-
#get_token(timestamp = nil) ⇒ String, Integer
Get authenticator’s token from given timestamp.
-
#initialize(serial, secret) ⇒ Authenticator
constructor
Create a new authenticator with given serial and secret.
-
#to_hash ⇒ Hash
Hash representation of this authenticator.
-
#to_s ⇒ String
String representation of this authenticator.
Constructor Details
#initialize(serial, secret) ⇒ Authenticator
Create a new authenticator with given serial and secret
36 37 38 39 40 41 42 |
# File 'lib/bnet/authenticator.rb', line 36 def initialize(serial, secret) raise BadInputError.new("bad serial #{serial}") unless self.class.is_valid_serial?(serial) raise BadInputError.new("bad secret #{secret}") unless self.class.is_valid_secret?(secret) @normalized_serial = self.class.normalize_serial(serial) @secret = secret end |
Instance Attribute Details
#region ⇒ Symbol (readonly)
Returns region.
29 30 31 |
# File 'lib/bnet/authenticator.rb', line 29 def region self.class.extract_region(@normalized_serial) end |
#restorecode ⇒ String (readonly)
Returns restoration code.
22 23 24 25 |
# File 'lib/bnet/authenticator.rb', line 22 def restorecode restorecode_bin = Digest::SHA1.digest(@normalized_serial + secret.as_hex_to_bin) self.class.encode_restorecode(restorecode_bin.split(//).last(10).join) end |
#secret ⇒ String (readonly)
Returns hexified secret.
18 19 20 |
# File 'lib/bnet/authenticator.rb', line 18 def secret @secret end |
#serial ⇒ String (readonly)
Returns serial.
12 13 14 |
# File 'lib/bnet/authenticator.rb', line 12 def serial self.class.prettify_serial(@normalized_serial) end |
Class Method Details
.get_token(secret, timestamp = nil) ⇒ String, Integer
Get token from given secret and timestamp
105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/bnet/authenticator.rb', line 105 def self.get_token(secret, = nil) raise BadInputError.new("bad seret #{secret}") unless is_valid_secret?(secret) current = ( || Time.now.getutc.to_i) / 30 digest = Digest::HMAC.digest([current].pack('Q>'), secret.as_hex_to_bin, Digest::SHA1) start_position = digest[19].ord & 0xf token = digest[start_position, 4].unpack('L>')[0] & 0x7fffffff return '%08d' % (token % 100000000), (current + 1) * 30 end |
.request_authenticator(region) ⇒ Bnet::Authenticator
Request a new authenticator from server
47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/bnet/authenticator.rb', line 47 def self.request_authenticator(region) raise BadInputError.new("bad region #{region}") unless is_valid_region?(region) k = create_one_time_pad(37) payload_plain = "\1" + k + region.to_s + CLIENT_MODEL.ljust(16, "\0")[0, 16] e = rsa_encrypt_bin(payload_plain) response_body = request_for('new serial', region, ENROLLMENT_REQUEST_PATH, e) decrypted = decrypt_response(response_body[8, 37], k) Authenticator.new(decrypted[20, 17], decrypted[0, 20].as_bin_to_hex) end |
.request_server_time(region) ⇒ Integer
Get server’s time
93 94 95 96 97 98 |
# File 'lib/bnet/authenticator.rb', line 93 def self.request_server_time(region) raise BadInputError.new("bad region #{region}") unless is_valid_region?(region) server_time_big_endian = request_for('server time', region, TIME_REQUEST_PATH) server_time_big_endian.unpack('Q>')[0].to_f / 1000 end |
.restore_authenticator(serial, restorecode) ⇒ Bnet::Authenticator
Restore an authenticator from server
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/bnet/authenticator.rb', line 66 def self.restore_authenticator(serial, restorecode) raise BadInputError.new("bad serial #{serial}") unless is_valid_serial?(serial) raise BadInputError.new("bad restoration code #{restorecode}") unless is_valid_restorecode?(restorecode) normalized_serial = normalize_serial(serial) region = extract_region(normalized_serial) # stage 1 challenge = request_for('restore (stage 1)', region, RESTORE_INIT_REQUEST_PATH, normalized_serial) # stage 2 key = create_one_time_pad(20) digest = Digest::HMAC.digest(normalized_serial + challenge, decode_restorecode(restorecode), Digest::SHA1) payload = normalized_serial + rsa_encrypt_bin(digest + key) response_body = request_for('restore (stage 2)', region, RESTORE_VALIDATE_REQUEST_PATH, payload) Authenticator.new(prettify_serial(normalized_serial), decrypt_response(response_body, key).as_bin_to_hex) end |
Instance Method Details
#get_token(timestamp = nil) ⇒ String, Integer
Get authenticator’s token from given timestamp
121 122 123 |
# File 'lib/bnet/authenticator.rb', line 121 def get_token( = nil) self.class.get_token(@secret, ) end |
#to_hash ⇒ Hash
Hash representation of this authenticator
127 128 129 130 131 132 133 134 |
# File 'lib/bnet/authenticator.rb', line 127 def to_hash { :serial => serial, :secret => secret, :restorecode => restorecode, :region => region, } end |
#to_s ⇒ String
String representation of this authenticator
138 139 140 |
# File 'lib/bnet/authenticator.rb', line 138 def to_s to_hash.to_s end |