Permalink
Browse files

Handle login failures and disconnections

  • Loading branch information...
asterite committed Nov 7, 2012
1 parent 90239ed commit 625b19692670172b2989cb35a4b4b44872ca9c79
Showing with 53 additions and 17 deletions.
  1. +1 −0 em-msn.gemspec
  2. +1 −0 lib/em-msn.rb
  3. +2 −0 lib/msn/authentication_error.rb
  4. +24 −8 lib/msn/messenger.rb
  5. +9 −0 lib/msn/nexus.rb
  6. +16 −9 lib/msn/notification_server.rb
View
@@ -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",
View
@@ -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'
@@ -0,0 +1,2 @@
+class Msn::AuthenticationError < StandardError
+end
View
@@ -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
@@ -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
View
@@ -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)
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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.