Browse files

Retracting previous commit message since it seems like logging in wit…

…h an ICQ UIN works, but not email addresses (which is what you're given to use to log in with new ICQ accounts).

ICQ accounts worked fine out of the box with just one modification. ICQ-specific functionality yet to come.
  • Loading branch information...
1 parent 812b820 commit aa8571207b24c0cde8a03987b902a37ac4779cb6 @mscdex committed Jan 30, 2011
Showing with 38 additions and 37 deletions.
  1. +6 −2 README.md
  2. +2 −0 TODO
  3. +30 −35 oscar.js
View
8 README.md
@@ -8,7 +8,7 @@ Requirements
============
* [node.js](http://nodejs.org/) -- tested with v0.2.6
-* An AIM account -- ICQ seems to require the clientLogin method for authentication which requires an API key and AOL isn't giving those out to anyone who is not excited about becoming a commercial partner of theirs.
+* An AIM or ICQ account -- Note: Only ICQ UINs will work and they must be a String when supplied as the username. For new ICQ accounts, they do not give you your ICQ UIN right away (you log in by email address). For these new accounts, you can find your UIN by: logging with the ICQ web client and editing your profile OR by going here (https://www.icq.com/karma/login_page.php), clicking the "Enable Log In With an Email" link, and logging in (your UIN will be displayed on the next page).
Example
@@ -118,7 +118,7 @@ OscarConnection Functions
* **connection** - An Object containing connection settings
* **username** - A String representing the username for authentication.
* **password** - A String representing the password for authentication.
- * **host** - A String representing the hostname or IP address of the OSCAR server. **Default:** AIM's server
+ * **host** - A String representing the hostname or IP address of the OSCAR server. **Default:** SERVER_AOL (predefined constants available, see constants list)
* **port** - An Integer representing the port of the OSCAR server. **Default:** 5190
* **connTimeout** - An Integer indicating the number of milliseconds to wait for a connection to be established. **Default:** 10000
* **allowMultiLogin** - A Boolean indicating whether simultaneous sessions should be allowed. **Default:** true
@@ -170,6 +170,10 @@ Constants
The following are available as static constants attached to the module (example: require('./oscar').IM\_FLAGS.AWAY):
+* **SERVER\_AOL** - A String containing the host name for logging onto AIM.
+
+* **SERVER\_ICQ** - A String containing the host name for logging onto ICQ.
+
* **IM\_MISSED\_REASONS**
* **INVALID** - IM data was invalid.
* **TOO\_BIG** - Sender's message was too large.
View
2 TODO
@@ -1,3 +1,5 @@
+- More ICQ testing and incorporation of ICQ-specific features
+
- Use setTimeout to send a keepalive packet on FLAP channel 0x05 -- time == 1 min? Digsby & Pidgin use a 30 sec timeout)
Note: Pidgin only seems to send keepalive on the main connection, unlike Digsby which sends keepalive on every connection
Also: the timer should be (re)started after each write to the socket and thus should not be sent if the connection isn't idle
View
65 oscar.js
@@ -1281,8 +1281,9 @@ OscarConnection.prototype._parseSNAC = function(conn, snac, cb) {
break;
case 0x05: // redirect info for requested service
debugtext += 'Service request info';
- var services = flip(SNAC_SERVICES);
+ var services = flip(SNAC_SERVICES), useSSL;
tlvs = extractTLVs(snac, idx);
+ useSSL = (tlvs[0x8E] && tlvs[0x8E][0] === 0x01);
if (typeof services[(tlvs[0x0D][0] << 8) + tlvs[0x0D][1]] !== 'undefined')
debugtext += ' (' + services[(tlvs[0x0D][0] << 8) + tlvs[0x0D][1]] + ')';
else
@@ -2536,51 +2537,45 @@ OscarConnection.prototype._login = function(error, conn, loginCb, reentry) {
}
if (typeof reentry === 'undefined') {
reentry = -1;
- if (self._state.isAOL) {
- // request salt from server for md5 hashing for password
- self._send(conn, self._createFLAP(conn, FLAP_CHANNELS.SNAC,
- self._createSNAC(SNAC_SERVICES.AUTH, 0x06, NO_FLAGS,
- self._createTLV(TLV_TYPES.SCREEN_NAME, self._options.connection.username)
- )
- ), function(e, salt) { process.nextTick(function(){ self._login(e, conn, loginCb, reentry + 1, salt); }); });
- } else {
- // TODO: truncate password if necessary
- var roastKey = [0xF3, 0x26, 0x81, 0xC4, 0x39, 0x86, 0xDB, 0x92, 0x71, 0xA3, 0xB9, 0xE6, 0x53, 0x7A, 0x95, 0x7C],
- roastKeyLen = roastKey.length, roasted = [];
- for (var i=0,len=self._options.connection.password.length; i<len; i++)
- roasted.push(self._options.connection.password.charCodeAt(i) ^ roastKey[i%roastKeyLen]);
- self._send(conn, self._createFLAP(conn, FLAP_CHANNELS.CONN_NEW,
- self._createTLV(TLV_TYPES.SCREEN_NAME, self._options.connection.username)
- .concat(self._createTLV(TLV_TYPES.CLIENT_ID_STR, 'ICQ Inc. - Product of ICQ (TM).2003a.5.45.1.3777.85'))
- .concat(self._createTLV(TLV_TYPES.PASSWORD_NEW, roasted))
- .concat(self._createTLV(TLV_TYPES.CLIENT_ID, [0x01, 0x0A]))
- .concat(self._createTLV(TLV_TYPES.CLIENT_VER_MAJOR, [0x00, 0x05]))
- .concat(self._createTLV(TLV_TYPES.CLIENT_VER_MINOR, [0x00, 0x2D]))
- .concat(self._createTLV(TLV_TYPES.CLIENT_VER_LESSER, [0x00, 0x00]))
- .concat(self._createTLV(TLV_TYPES.CLIENT_VER_BUILD, [0x0E, 0xC1]))
- .concat(self._createTLV(TLV_TYPES.DISTRIB_NUM, [0x00, 0x00, 0x00, 0x55]))
- .concat(self._createTLV(TLV_TYPES.CLIENT_LANG, 'en'))
- .concat(self._createTLV(TLV_TYPES.CLIENT_COUNTRY, 'us'))
- ), function(e, server, cookie) { process.nextTick(function(){ self._login(e, conn, loginCb, 1, server, cookie); }); });
- }
+ // request salt from server for md5 hashing for password
+ self._send(conn, self._createFLAP(conn, FLAP_CHANNELS.SNAC,
+ self._createSNAC(SNAC_SERVICES.AUTH, 0x06, NO_FLAGS,
+ self._createTLV(TLV_TYPES.SCREEN_NAME, self._options.connection.username)
+ )
+ ), function(e, salt) { process.nextTick(function(){ self._login(e, conn, loginCb, reentry + 1, salt); }); });
} else {
switch (reentry) {
case 0: // server sent us the salt ('key') for our md5 password hashing
// TODO: truncate password if necessary
- var salt = arguments[4], hash = [], oldhash;
+ var salt = arguments[4], hash = [], oldhash, clientInfo = {};
+ if (self._state.isAOL) {
+ clientInfo.str = 'AOL Instant Messenger, version 5.9.3702/WIN32';
+ clientInfo.id = [0x01, 0x09];
+ clientInfo.vMajor = [0x00, 0x05];
+ clientInfo.vMinor = [0x00, 0x09];
+ clientInfo.vLesser = [0x00, 0x00];
+ clientInfo.vBuild = [0x0E, 0x76];
+ } else {
+ clientInfo.str = 'ICQ Inc. - Product of ICQ (TM).2003a.5.45.1.3777.85';
+ clientInfo.id = [0x01, 0x0A];
+ clientInfo.vMajor = [0x00, 0x14];
+ clientInfo.vMinor = [0x00, 0x34];
+ clientInfo.vLesser = [0x00, 0x00];
+ clientInfo.vBuild = [0x0C, 0x18];
+ }
oldhash = crypto.createHash('md5').update(salt).update(self._options.connection.password).update('AOL Instant Messenger (SM)').digest();
for (var i=0,len=oldhash.length; i<len; i++)
hash[i] = oldhash.charCodeAt(i);
self._send(conn, self._createFLAP(conn, FLAP_CHANNELS.SNAC,
self._createSNAC(SNAC_SERVICES.AUTH, 0x02, NO_FLAGS,
self._createTLV(TLV_TYPES.SCREEN_NAME, self._options.connection.username)
- .concat(self._createTLV(TLV_TYPES.CLIENT_ID_STR, 'AOL Instant Messenger, version 5.9.3702/WIN32'))
+ .concat(self._createTLV(TLV_TYPES.CLIENT_ID_STR, clientInfo.str))
.concat(self._createTLV(TLV_TYPES.PASSWORD_HASH, hash))
- .concat(self._createTLV(TLV_TYPES.CLIENT_ID, [0x01, 0x09]))
- .concat(self._createTLV(TLV_TYPES.CLIENT_VER_MAJOR, [0x00, 0x05]))
- .concat(self._createTLV(TLV_TYPES.CLIENT_VER_MINOR, [0x00, 0x09]))
- .concat(self._createTLV(TLV_TYPES.CLIENT_VER_LESSER, [0x00, 0x00]))
- .concat(self._createTLV(TLV_TYPES.CLIENT_VER_BUILD, [0x0E, 0x76]))
+ .concat(self._createTLV(TLV_TYPES.CLIENT_ID, clientInfo.id))
+ .concat(self._createTLV(TLV_TYPES.CLIENT_VER_MAJOR, clientInfo.vMajor))
+ .concat(self._createTLV(TLV_TYPES.CLIENT_VER_MINOR, clientInfo.vMinor))
+ .concat(self._createTLV(TLV_TYPES.CLIENT_VER_LESSER, clientInfo.vLesser))
+ .concat(self._createTLV(TLV_TYPES.CLIENT_VER_BUILD, clientInfo.vBuild))
.concat(self._createTLV(TLV_TYPES.DISTRIB_NUM, [0x00, 0x00, 0x01, 0x11]))
.concat(self._createTLV(TLV_TYPES.CLIENT_LANG, 'en'))
.concat(self._createTLV(TLV_TYPES.CLIENT_COUNTRY, 'us'))

0 comments on commit aa85712

Please sign in to comment.