Skip to content

Commit

Permalink
Handle login failures and disconnections
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite committed Nov 7, 2012
1 parent 90239ed commit 625b196
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 17 deletions.
1 change: 1 addition & 0 deletions em-msn.gemspec
Expand Up @@ -14,6 +14,7 @@ Gem::Specification.new do |s|

s.files = [
"lib/em-msn.rb",
"lib/msn/authentication_error.rb",
"lib/msn/message.rb",
"lib/msn/contact.rb",
"lib/msn/nexus.rb",
Expand Down
1 change: 1 addition & 0 deletions lib/em-msn.rb
Expand Up @@ -14,6 +14,7 @@ module Msn
require "nokogiri"
require 'rexml/text'

require_relative 'msn/authentication_error'
require_relative 'msn/protocol'
require_relative 'msn/message'
require_relative 'msn/contact'
Expand Down
2 changes: 2 additions & 0 deletions lib/msn/authentication_error.rb
@@ -0,0 +1,2 @@
class Msn::AuthenticationError < StandardError
end
32 changes: 24 additions & 8 deletions lib/msn/messenger.rb
Expand Up @@ -61,6 +61,14 @@ def on_ready(&handler)
@on_ready_handler = handler
end

def on_login_failed(&handler)
@on_login_failed = handler
end

def on_disconnect(&handler)
@on_disconnect = handler
end

def on_message(&handler)
@on_message_handler = handler
end
Expand All @@ -74,20 +82,28 @@ def send_message(email, text)
end

def accept_message(message)
if @on_message_handler
Fiber.new { @on_message_handler.call(message) }.resume
end
call_handler @on_message_handler, message
end

def contact_request(email, display_name)
if @on_contact_request
Fiber.new { @on_contact_request.call(email, display_name) }.resume
end
call_handler @on_contact_request, email, display_name
end

def ready
if @on_ready_handler
Fiber.new { @on_ready_handler.call }.resume
call_handler @on_ready_handler
end

def login_failed(message)
call_handler @on_login_failed, message
end

def disconnected
call_handler @on_disconnect
end

def call_handler(handler, *args)
if handler
Fiber.new { handler.call(*args) }.resume
end
end

Expand Down
9 changes: 9 additions & 0 deletions lib/msn/nexus.rb
Expand Up @@ -8,6 +8,7 @@ class Msn::Nexus
"wst" => "http://schemas.xmlsoap.org/ws/2004/04/trust",
"wsp" => "http://schemas.xmlsoap.org/ws/2002/12/policy",
"wsa" => "http://schemas.xmlsoap.org/ws/2004/03/addressing",
"S" => "http://schemas.xmlsoap.org/soap/envelope/",
}

def initialize(messenger, policy, nonce)
Expand Down Expand Up @@ -36,6 +37,7 @@ def fetch_data
@fetched_data = true

@sso_token, secret, @ticket_token = get_binary_secret messenger.username, messenger.password

@secret = compute_return_value secret
end

Expand All @@ -45,8 +47,15 @@ def get_binary_secret(username, password)
soap = msn_sso_template.result(binding)

response = RestClient.post "https://login.live.com/RST.srf", soap

xml = Nokogiri::XML(response)

# Check invalid login
fault = xml.xpath("//S:Fault/faultstring")
if fault
raise Msn::AuthenticationError.new(fault.text)
end

rstr = xml.xpath "//wst:RequestSecurityTokenResponse[wsp:AppliesTo/wsa:EndpointReference/wsa:Address='messengerclear.live.com']", Namespaces
token = rstr.xpath("wst:RequestedSecurityToken/wsse:BinarySecurityToken[@Id='Compact1']", Namespaces).first.text
secret = rstr.xpath("wst:RequestedProofToken/wst:BinarySecret", Namespaces).first.text
Expand Down
25 changes: 16 additions & 9 deletions lib/msn/notification_server.rb
Expand Up @@ -94,15 +94,20 @@ def post_init

def login
Fiber.new do
ver "MSNP18", "CVR0"
cvr "0x0409", "winnt", "5.1", "i386", "MSNMSGR", "8.5.1302", "BC01", username
response = usr "SSO", "I", username
if response[0] == "XFR" && response[2] == "NS"
host, port = response[3].split ':'
@reconnect_host, @reconnect_port = response[3].split ':'
begin
ver "MSNP18", "CVR0"
cvr "0x0409", "winnt", "5.1", "i386", "MSNMSGR", "8.5.1302", "BC01", username
response = usr "SSO", "I", username
if response[0] == "XFR" && response[2] == "NS"
host, port = response[3].split ':'
@reconnect_host, @reconnect_port = response[3].split ':'
close_connection
else
login_to_nexus(response[4], response[5])
end
rescue Msn::AuthenticationError => ex
messenger.login_failed(ex.message)
close_connection
else
login_to_nexus(response[4], response[5])
end
end.resume
end
Expand All @@ -125,7 +130,7 @@ def login_to_nexus(policy, nonce)

response = usr "SSO", "S", @nexus.sso_token, @nexus.secret, guid
if response[2] != "OK"
raise "Login failed (3)"
raise Msn::AuthenticationError.new("Didn't receive OK from SSO")
end
end

Expand All @@ -148,6 +153,8 @@ def unbind
reconnect @reconnect_host, @reconnect_port.to_i
@reconnect_host = @reconnect_port = nil
login
else
messenger.disconnected
end
end
end

0 comments on commit 625b196

Please sign in to comment.