Paste number 26800: authmod

Paste number 26800: authmod
Pasted by: Cynos
When:8 years, 1 month ago
Share:Tweet this! | http://paste.lisp.org/+KOG
Channel:None
Paste contents:
Raw Source | XML | Display As
-module(authmod).
-export([go/0, authCreate/0]).


go() ->
    % Start inets process - makes HTTP requests
    % SSL process is exactly that - a process to handle the SSL stuff
    % Needed for HTTP request. Call it now due to start up lag.
    application:start(inets),
    application:start(ssl),
    
    % Spawn new process running authCreate and return process ID.
    spawn(authmod, authCreate, []).

authCreate() ->
    % Create socket handler process then enter main loop.
    ConProcess = spawn_link(sockmod,conCreate, [self()]),
    authLoop(ConProcess).


authLoop(Con) ->
    % Wait for command from client end.
    receive
	{authenticate, User, Pwd} ->
	    %Query dispatch server for IP of notification server

	    case connect(Con, "messenger.hotmail.com", 1863) of
		true ->
		    %Connected, so begin authentication.
		    authenticated = auth(Con, User, Pwd),
		    io:format("Authenticated with notification server~n", []);
                
             	false ->
		    exit({connect_error, "Connection to messenger.hotmail.com failed"})
	    end;
        
	%%These two messages are for testing - they expose the socket.
    	{cmd, Command} ->
            Con ! {send, Command ++ "\r\n"};
        
        {data_received, Data} ->
	    io:format("~s~n", [Data])                
    end,
    %Erlang does tail-call optimisation
    authLoop(Con).


connect(Con, Server, Port) ->
    Con ! {connect, Server, Port},
    receive
	{error, connect, Reason} ->
	    exit({connection_error, Reason});        
	ok ->
	    true
    end.


auth(Con,User,Pwd) ->
    % Start handshaking and discussing versions.
    VerStr = "VER 1 MSNP9 CVR0\r\n",
    CvrStr = "CVR 2 0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS " ++ User ++ "\r\n",
    VerStr = send_get(VerStr, Con), %Success for these will result in string being echoed
    CvrStr = send_get(CvrStr, Con),
    
    case send_get("USR 3 TWN I " ++ User ++ "\r\n", Con) of

	%Message to connect to new server, so parse out new ip and port and then reconnect
	"XFR 3 NS " ++ NewServer ->
	    [Server, Port] = parseServer(NewServer),                                     
	    Con ! disconnect,
	    receive
		ok -> ok
	    end,
	    connect(Con,Server, Port),
	    auth(Con, User, Pwd);
		
	%Connection has been accepted by a notification server, and a authentication token returned.
	"USR 3 TWN S " ++ AuthString ->
	    
	    %Now I need to submit the token to MS to get another token
	    case httpmod:get_key(User, Pwd, AuthString) of
		
		{ok, Token} ->
		    %FinalSend is the last security token
		    FinalSend = "USR 4 TWN S " ++ Token ++ "\r\n",
		    send_get(FinalSend, Con);

		{error, Body} ->
		    %If an error occurred, MS sends me some XML which I stare at blindly.
		    exit({connection_error, Body})
	    end;

	Other ->
	    %Error has occurred.
	    exit({unknown_response, Other})
    end,
    authenticated.

    




			
parseServer(NewServer) ->
    %NewServer will equal "new.ip.address:port 0 old.ip.address:port\r\n"
    %[A|B] is equivalent to a_list[0] and a_list[1:] in Python 
    %or (car a_list) and (cdr a_list) in Lisp
	
    {ok, [XfrTo|_T]} = regexp:split(NewServer, " 0 "),       
    {ok, [Server, StrPort]} = regexp:split(XfrTo, ":"),
						
    %Below function converts a string (which is a list of integers) to an actual integer.
    Port = list_to_integer(StrPort),			
    [Server, Port].
    
    
send_get(Data, Con) ->
    Con ! {send, Data},
    receive
	ok -> 
	    recv_data();
          
        {error, Type, Reason} -> 
            exit({send_error, Type, Reason});
      

	Unknown ->	
	    %Debugging catchall.
	    exit({unexpected_response, Unknown})
    end.


recv_data() ->
    receive
	{data_received, Data} -> Data;
	
	Unknown->
	    exit({unexpected_response, Unknown})

    end.


This paste has no annotations.

Colorize as:
Show Line Numbers

Lisppaste pastes can be made by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively.