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
29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/bnet/authenticator.rb', line 29 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) @serial = self.class.prettify_serial(normalized_serial) @secret = secret @region = self.class.extract_region(normalized_serial) restorecode_bin = Digest::SHA1.digest(normalized_serial + secret.as_hex_to_bin) @restorecode = self.class.encode_restorecode(restorecode_bin.split(//).last(10).join) end |
Instance Attribute Details
#region ⇒ Symbol (readonly)
Returns region.
24 25 26 |
# File 'lib/bnet/authenticator.rb', line 24 def region @region end |
#restorecode ⇒ String (readonly)
Returns restoration code.
20 21 22 |
# File 'lib/bnet/authenticator.rb', line 20 def restorecode @restorecode end |
#secret ⇒ String (readonly)
Returns hexified secret.
16 17 18 |
# File 'lib/bnet/authenticator.rb', line 16 def secret @secret end |
#serial ⇒ String (readonly)
Returns serial.
12 13 14 |
# File 'lib/bnet/authenticator.rb', line 12 def serial @serial end |
Class Method Details
.get_token(secret, timestamp = nil) ⇒ String, Integer
Get token from given secret and timestamp
102 103 104 105 106 107 108 109 110 111 |
# File 'lib/bnet/authenticator.rb', line 102 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 = '%08d' % (digest[start_position, 4].as_bin_to_i % 100000000) return token, (current + 1) * 30 end |
.request_authenticator(region) ⇒ Bnet::Authenticator
Request a new authenticator from server
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/bnet/authenticator.rb', line 46 def self.request_authenticator(region) region = region.to_s.upcase.to_sym 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_encrypted(payload_plain.as_bin_to_i) 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 |
# File 'lib/bnet/authenticator.rb', line 93 def self.request_server_time(region) request_for('server time', region, TIME_REQUEST_PATH).as_bin_to_i.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_encrypted((digest + key).as_bin_to_i) 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
117 118 119 |
# File 'lib/bnet/authenticator.rb', line 117 def get_token( = nil) self.class.get_token(@secret, ) end |
#to_hash ⇒ Hash
Hash representation of this authenticator
123 124 125 126 127 128 129 |
# File 'lib/bnet/authenticator.rb', line 123 def to_hash { :serial => serial, :secret => secret, :restorecode => restorecode, } end |
#to_s ⇒ String
String representation of this authenticator
133 134 135 |
# File 'lib/bnet/authenticator.rb', line 133 def to_s to_hash.to_s end |