File Coverage

Msmgr.pm
Criterion Covered Total %
statement 51 78 65.3
branch 0 12 0.0
condition n/a
subroutine 17 19 89.4
pod 0 2 0.0
total 68 111 61.2


line stmt bran cond sub pod time code
1             package Net::Msmgr;
2              
3 1     1   12851 use 5.006;
  1         4  
  1         33  
4 1     1   6 use strict;
  1         1  
  1         31  
5 1     1   4 use warnings;
  1         7  
  1         43  
6              
7             require Exporter;
8              
9 1     1   1031 use LWP::UserAgent;
  1         53393  
  1         33  
10 1     1   12 use HTTP::Request;
  1         1  
  1         20  
11 1     1   4 use HTTP::Response;
  1         2  
  1         17  
12 1     1   5 use URI::Escape;
  1         2  
  1         76  
13              
14 1     1   4 use vars qw / $TRID $dalogin /;
  1         1  
  1         122  
15              
16             our @ISA = qw(Exporter);
17              
18             our %EXPORT_TAGS = ( 'debug' => [ qw ( DEBUG_PACKET_SEND
19             DEBUG_PACKET_RECV
20             DEBUG_COMMAND_SEND
21             DEBUG_COMMAND_RECV
22             DEBUG_OPEN
23             DEBUG_CLOSE
24             DEBUG_CONFUSED
25             DEBUG_HANDLER
26             DEBUG_NOTIFICATION) ] );
27              
28             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'debug'} }, qw { GetVersion8Response } );
29              
30             our @EXPORT = qw();
31             our $VERSION = substr(q$Revision: 0.16 $,10);
32              
33              
34 1     1   4 use constant DEBUG_PACKET_SEND => 1;
  1         2  
  1         58  
35 1     1   5 use constant DEBUG_PACKET_RECV => 2;
  1         1  
  1         52  
36 1     1   5 use constant DEBUG_COMMAND_SEND => 4;
  1         2  
  1         63  
37 1     1   6 use constant DEBUG_COMMAND_RECV => 8;
  1         2  
  1         51  
38 1     1   5 use constant DEBUG_OPEN => 16;
  1         1  
  1         46  
39 1     1   14 use constant DEBUG_CLOSE => 32;
  1         4  
  1         53  
40 1     1   5 use constant DEBUG_CONFUSED => 64;
  1         3  
  1         41  
41 1     1   5 use constant DEBUG_HANDLER => 128;
  1         1  
  1         44  
42 1     1   5 use constant DEBUG_NOTIFICATION => 256;
  1         1  
  1         755  
43              
44              
45              
46             $TRID = 0 ;
47             $dalogin = undef; # cache this for speedier connections
48              
49             sub TRID
50             {
51 0     0 0   $TRID++;
52 0           return $TRID;
53             }
54              
55             sub GetVersion8Response
56             {
57 0     0 0   my $user = shift;
58 0           my ($trid, $scheme, $state, $string ) = @_;
59 0           my %challenge_part = map { split '=' } split(',', $string) ;
  0            
60              
61              
62 0 0         unless ($dalogin)
63             {
64 0           my $ua = new LWP::UserAgent;
65 0           my $response = $ua->get('https://nexus.passport.com/rdr/pprdr.asp');
66 0           my %passport_urls =
67 0           map { split '=' } split(',',($response->headers->header('PassportURLs')));
68 0           $dalogin = $passport_urls{'DALogin'};
69             }
70              
71 0 0         warn "No dalogin" unless $dalogin;
72 0 0         return unless $dalogin;
73              
74 0           my $username = uri_escape($user->user);
75 0           my $password = uri_escape($user->password);
76 0           my $auth_string = 'Passport1.4 ' . join(',',
77             qq {OrgVerb=GET},
78             qq {OrgURL=$challenge_part{ru}} ,
79             qq {sign-in=$username},
80             qq {pwd=$password},
81             qq {lc=$challenge_part{lc}},
82             qq {id=$challenge_part{id}},
83             qq {tw=$challenge_part{tw}},
84             qq {fs=$challenge_part{fs}},
85             ## qq {ru=$challenge_part{ru}},
86             qq {ct=$challenge_part{ct}},
87             qq {kpp=$challenge_part{kpp}},
88             qq {kv=$challenge_part{kv}},
89             qq {ver=$challenge_part{ver}},
90             qq {tpf=$challenge_part{tpf}} );
91              
92 0           my $ua = new LWP::UserAgent;
93 0           my $request = new HTTP::Request ( GET => 'https://' . $dalogin );
94 0           $request->headers->header('Authorization' => $auth_string);
95              
96 0           my $response = $ua->request($request);
97 0 0         if ($response->is_success)
98             {
99 0 0         if (my $auth_info = $response->header('authentication-info'))
100             {
101 0           $auth_info =~ m/(t=.*\$\$\&p=.*\$\$)/;
102 0 0         if (my $magic_string = $1)
103             {
104 0           return $magic_string;
105             }
106             }
107             }
108 0           return undef;
109             }
110              
111             1;
112              
113             =pod
114              
115             =head1 NAME
116              
117             Net::Msmgr - Microsoft Network Chat Client Toolkit
118              
119             This is the documentation for $Revision: 0.16 $
120              
121             =head1 SYNOPSIS
122              
123             use Net::Msmgr;
124             use Net::Msmgr::Sesssion;
125             use Net::Msmgr::User;
126              
127             our $session = new Net::Msmgr::Session;
128             our $user = new Net::Msmgr::User ( user => 'username@msn.com',
129             password => 'my_password' ) ;
130              
131             $session->user($user);
132             $session->login_handler( sub { shift->Logout } ) ;
133             $session->connect_handler ( ... ) ;
134             $session->Login;
135              
136              
137             =head1 OVERVIEW
138              
139             This is a set of perl modules for encapsulating interactions with the
140             Microsoft Network "Messenger" chat system. You might use it to
141             develop clients, or robots. The components are, this module, Net::Msmgr,
142             which contains some non-object helper routines (mostly the
143             authentication chain for using MSNP8 (Protocol version 8) and a
144             handful of manifest constants for debugging.
145              
146             Other modules include:
147              
148             =over
149              
150             =item Net::Msmgr::Session
151              
152             Encapsulates the entirety of a session.
153              
154             =item Net::Msmgr::User
155              
156             Holds user authentication credentials.
157              
158             =item Net::Msmgr::Command
159              
160             Used to hold command objects sent to or received from the servers.
161              
162             =item Net::Msmgr::Connection
163              
164             Used to encapsulate server connections.
165              
166             =item Net::Msmgr::Switchboard
167              
168             Derived from Net::Msmgr::Connection
169              
170             =item Net::Msmgr::Conversation
171              
172             A higher level view of conversation - contains (but is not) a Switchboard
173              
174             =item Net::Msmgr::Object
175              
176             Pure base class from which all of the others are derived. Direct from
177             the perltoot manpage.
178              
179              
180             =head1 SERVER PROTOCOL
181              
182             The entire protocol consists of a series of discrete messages that are
183             passed between the client and the various servers that make up the
184             system. Messages come in a variety of broad classes (Normal,
185             Asyncronous, and Payload), and those are subdivided into more specific
186             types (Transfer Requests, Chat Messages, State Change Notifications.)
187              
188             There are three servers you will deal with during a basic session, the
189             Dispatch Server, which is a meta server to distribute inbound
190             sessions, the Notification Server, which will hold a single connection
191             for the life of the session, and Switchboard Servers, which you will hold
192             as many connections as you have chat groups active.
193              
194             Technically, there is no difference between the Dispatch Server and
195             the Notification Server, except that the Dispatch Server will
196             (historically) always refer you to a Notification Server. There is
197             nothing in the protocol to prohibit a Notification Server from ALSO
198             refering you to a third Notification Server, although this author has
199             never seen that happen.
200              
201             Because of this, we tend to think of the DS and the NS as dissimilar
202             entities, but there is no need for them to be so, and in the interest
203             of flexibility they are treated the same. There is no limit, besides
204             end-user patience to how many XFR messages you can receive.
205              
206             =head2 DISPATCH SERVER
207              
208             This is the first-base server. Your minimum action here is to request
209             a session, and act on the instructions from the server.
210              
211             =head2 NOTIFICATION SERVER
212              
213             This is the center of your session, and when you have connected here,
214             most (other) clients, and this library will consider you "connected"
215             to MSN Chat.
216              
217             =head2 SWITCHBOARD SERVER
218              
219             To send or receive messages from other clients, there must be a
220             connection to one or more Switchboard Servers. Each one of these
221             connections is a 'party line', and all users currently connected to
222             the same session (referenced by what the library calls a $ssid
223             Switchboard Session ID) will see all messages sent by any user. The
224             number of users that can be attached to a SSID appears to be
225             reaosonably unlimited (on the order of dozens).
226              
227             =head1 COMMAND SUMMARY
228              
229             Here is a quick summary of all of the messages used in this library
230             between the client and the servers.
231              
232             =over
233              
234             =item VER -- Version
235              
236             Optionally sent from client to DS / NS for protocol version negotiation.
237              
238             =item INF -- Information
239              
240             Optionally sent from client to DS / NS, asking what Encryption
241             Technique to use. In MSNP7 and lower, it is always MD5. MSNP8 uses a
242             different technique, but does not use this command to negotiate it.
243             Go figure.
244              
245             =item USR -- User Information
246              
247             Used in two variants from client to server as part of
248             the login procedure, in a slightly different variant from server to client as
249             part of that same procedure, and again later during the authentication
250             with Switchboard Servers.
251              
252             =item XFR -- Transfer
253              
254             Used in one variant from server to client as part of
255             the login procedure, referring you from DS to NS. Used again later
256             from client to server to request a connection to a switchboard server.
257              
258             =item CHG -- Change
259              
260             Sent from client to server to alter your 'presence' (online, out to lunch, etc.)
261              
262             =item ILN -- Inital online
263              
264             Sent from server to client in response to your first change to online
265             status, with a list of visible users already on the system.
266              
267             =item SYN -- Synchonize
268              
269             Optionally sent from client to server to request a download of all of your user lists.
270              
271             =item GTC -- no known mnemonic
272              
273             Part of the bundle of information sent from server to client, it
274             advises the client of a user-set preference for dealing with new
275             users. It is stored on the server, but not acted on in any way. Can
276             be sent as a command to the server to alter this setting.
277              
278             =item BLP -- Blocking Preference
279              
280             Part of the bundle of information sent from server to client as part
281             of a SYN. Used by the server to determine behavior if an unkonwn user
282             attempts to invite you to a switchboard session.
283              
284             =item PRP -- Personal Phone Number
285              
286             Sent from server to client during SYN, and sent from client to server
287             to change the settings. Designed to hold telephone numbers on the
288             server in URI-encoded strings, and a few variants to hold some mobile
289             device preferences.
290              
291             =item LST -- List
292              
293             Sent from server to client during SYN, and in resposne to a LST
294             command. One variant for each of the four lists (Allow, Block, Forward
295             and Reverse) the server maintains for each client.
296              
297             =item ADD -- Add
298              
299             Sent from client to server to add a user to a list. Echoed from
300             server to client with new list serial-number. The server maintains
301             this serial-number, such that the client may cache the list locally.
302              
303             =item REM -- Remove
304              
305             Sent from client to server to remove a user from a list.
306              
307             =item REA -- Rename
308              
309             Sent from client to server to change the Friendly Name associated with
310             a user in your lists. Also used to change your own friendly name.
311              
312             =item MSG -- Message
313              
314             Sent from DS/NS server to client at login, and sometimes for
315             administrative (shutdown) messages. Also, the core of what this
316             protocol is about - sending messages to other users and receiving
317             messages from other users via Switchboard Servers.
318              
319             =item ANS -- Answer
320              
321             Sent from client to switchboard server in resposne to a switchboard
322             invitation.
323              
324             =item IRO -- Initial Roster
325              
326             Sent from switchboard to client upon connection to a switchboard
327             server informing client of other users attached to that switchboard
328             session.
329              
330             =item CAL -- Call
331              
332             Sent from client to switchboard to invite another user to join the
333             switchboard session.
334              
335             =item OUT -- Out
336              
337             Async command sent from client to NS/DS/SB server to terminate their session.
338              
339             =item NLN -- Online
340              
341             Async command sent from NS to client to advise of another user coming online.
342              
343             =item FLN -- Offline
344              
345             Async command sent from NS to client to advise of another user going offline.
346              
347             =item PNG -- Ping
348              
349             Async command sent from client to NS to make sure it is still there.
350              
351             =item QNG -- Pong
352              
353             Async command sent from NS to client to acknowledge its presence.
354              
355             =item RNG -- Ring
356              
357             Async command sent from NS to client to advise of another user inviting you to a Switchboard Session.
358              
359             =item JOI -- Join
360              
361             Async command sent from SB to client to advise of another user joining a Switchboard Session.
362              
363             =item BYE -- Bye
364              
365             Async command sent from SB to client to advise of another user leaving a Switchboard Session.
366              
367             =back
368              
369             =head1 COMMAND FORMATS
370              
371             Commands sent in the protocols come in three (and a theoretically
372             possible fourth) variants. This library refers to them as Normal,
373             Async, and Payload.
374              
375             =head2 NORMAL COMMANDS
376              
377             The vast bulk of commands are Normal, and each
378             one is tagged with a numeric identifier by the client. This
379             identifier will be used by the server to correlate its responses to
380             your requests. This library does not currently verify any of these
381             transaction identifiers (TRIDs), but does send each command with a
382             unique monotonically-increasing number. Library users can feel free
383             to use the TRID in Normal messages as a unique identifier, within the
384             rules of the protocol. (That is: Sometimes a single Normal command
385             from client to server will result in many related responses, all of
386             which will contain the TRID of that single request).
387              
388             =head2 ASYNC COMMANDS
389              
390             Another block of commands are those sent from server to client in
391             resposne to asyncronous events, such as users in your Forward List
392             changing their status, invitations by other users to Switchboard
393             Sessions, and users joining and leaving Switchboard Sessions.
394              
395             =head2 PAYLOAD COMMANDS
396              
397             The final type of command is that which contains message data. This
398             library only (currently) supports one, the MSG command, which is used
399             to encapsulate messages from server to client, and peer to peer.
400              
401             =head1 ASYNCRONOUS INPUT
402              
403             The library user is responsible for dealing with non-blocking IO, and
404             there are several ways you might do this. If you are writing a
405             Perl/Tk you would probably use fileevent, or you might want to use
406             Joshua Pritikin's Event package (which I use), or you can roll your
407             own with select and poll. You could even use alarm and signals to
408             periodically sweep all of the inbound sessions.
409              
410             To help you with this, there are a pair of handlers in the
411             Net::Msmgr::Session object, $session->connect_handler, and
412             $session->disconnect_handler - which are called just after the TCP
413             connect() call and just before the TCP close() call respectively.
414              
415             Each of these will be called with a single pointer to the Net::Msmgr::Connection object.
416              
417             It is the users' responsibility to call $connection->_recv_message
418             whenever input is available on $connection->socket.
419              
420             With Tk this would be something like
421              
422             sub Connect_handler
423             {
424             my $connection = shift;
425             $mainwindow->fileevent($connection->socket,
426             'readable',
427             sub { $connection->_recv_message });
428             }
429             $session->connect_hanlder(\&Connect_handler);
430             $session->Login;
431             MainLoop;
432              
433             Under Joshua Pritikin's Event package, you might use
434              
435             our %watcher;
436              
437             sub ConnectHandler
438             {
439             my ($connection) = @_;
440             my $socket = $connection->socket;
441             $watcher{$connection} = Event->io(fd => $socket,
442             cb => [ $connection , '_recv_message' ],
443             poll => 're',
444             desc => 'recv_watcher',
445             repeat => 1);
446             }
447              
448             sub DisconnectHandler
449             {
450             my $connection = shift;
451             $watcher{$connection}->cancel;
452             }
453              
454             $session->connect_handler(\&ConnectHandler);
455             $session->disconnect_handler(\&DisconnectHandler);
456              
457              
458             A third handler Net::Msmgr::Session::switchboard_handler() will be called
459             with a Net::Msmgr::Connection object and an ssid for each switchboard session
460             you are invited to, or instantiate through
461             Net::Msmgr::Session::ui_new_switchboard().
462              
463              
464             =cut
465              
466              
467             #
468             # $Log: Msmgr.pm,v $
469             # Revision 0.16 2003/08/07 00:01:59 lawrence
470             # Initial Release
471             #
472             #