Skip to content
This repository
Browse code

Cleanup SMTP Auth code, add in basic test case

  • Loading branch information...
commit 9e9d87417cb8d9be4e15fffa3c667172a8cd8600 1 parent 34b8360
Geoff Hayes hayesgm authored

Showing 2 changed files with 134 additions and 13 deletions. Show diff stats Hide diff stats

  1. +29 13 smtp_client.js
  2. +105 0 tests/smtp_client/auth.js
42 smtp_client.js
@@ -198,6 +198,7 @@ SMTPClient.prototype.release = function () {
198 198 return;
199 199 }
200 200 this.state = STATE_RELEASED;
  201 + this.authenticated = false;
201 202 this.removeAllListeners('greeting');
202 203 this.removeAllListeners('capabilities');
203 204 this.removeAllListeners('xclient');
@@ -349,23 +350,38 @@ exports.get_client_plugin = function (plugin, connection, config, callback) {
349 350 return;
350 351 }
351 352 }
  353 +
  354 + var auth_matches;
  355 + if (auth_matches = smtp_client.response[line].match(/^AUTH (.*)$/)) {
  356 + auth_matches = auth_matches[1].split(' ');
  357 + for (var i = 0; i < auth_matches.length; i++) {
  358 + connection.auth_capibilities.push(auth_matches[i].toLowerCase());
  359 + }
  360 + }
352 361 }
353 362 });
354 363
355 364 smtp_client.on('helo', function () {
356   - if (config.auth && !this.authentiated) {
357   - switch (config.auth.type) {
358   - case 'plain':
359   - connection.logdebug(['SMTP Authenticating as', config.auth.user]);
360   - smtp_client.send_command('AUTH',
361   - 'PLAIN ' + base64("\0" + config.auth.user + "\0" + config.auth.pass) );
362   - this.authenticated = true;
363   - break;
364   - case null:
365   - case undefined:
366   - break; // Nothing to do here
367   - default:
368   - throw new Error("Unknown AUTH type: " + config.auth.type);
  365 + if (config.auth && !smtp_client.authentiated) {
  366 + if (config.auth.type === null || typeof(config.auth.type) === 'undefined') { return; } // Ignore blank
  367 + var auth_type = config.auth.type.toLowerCase();
  368 + if (connection.auth_capibilities.indexOf(auth_type) == -1) {
  369 + throw new Error("Auth type \"" + auth_type + "\" not supported by server (supports: " + connection.auth_capibilities.join(',') + ")")
  370 + }
  371 + switch (auth_type) {
  372 + case 'plain':
  373 + if (!config.auth.user || !config.auth.pass) {
  374 + throw new Error("Must include auth.user and auth.pass for PLAIN auth.");
  375 + }
  376 + logger.logdebug('[smtp_client_pool] uuid=' + smtp_client.uuid + ' authenticating as "' + config.auth.user + '"');
  377 + smtp_client.send_command('AUTH',
  378 + 'PLAIN ' + base64(config.auth.user + "\0" + config.auth.user + "\0" + config.auth.pass) );
  379 + smtp_client.authenticated = true;
  380 + break;
  381 + case 'cram-md5':
  382 + throw new Error("Not implemented");
  383 + default:
  384 + throw new Error("Unknown AUTH type: " + auth_type);
369 385 }
370 386 }
371 387 });
105 tests/smtp_client/auth.js
... ... @@ -0,0 +1,105 @@
  1 +test.expect(24);
  2 +var server = {notes: {}};
  3 +
  4 +exports.get_pool(server);
  5 +var pool_name = '25:localhost:300';
  6 +test.equals(1, Object.keys(server.notes.pool).length);
  7 +test.equals(pool_name, Object.keys(server.notes.pool)[0]);
  8 +test.equals(0, server.notes.pool[pool_name].getPoolSize());
  9 +test.equals(0, server.notes.pool[pool_name].availableObjectsCount());
  10 +
  11 +exports.get_client(server, function(err, smtp_client) {
  12 + test.equals(null, err);
  13 + test.equals(1, server.notes.pool[pool_name].getPoolSize());
  14 + test.equals(0, server.notes.pool[pool_name].availableObjectsCount());
  15 +
  16 + var data = [];
  17 + var reading_body = false;
  18 + data.push('220 hi');
  19 +
  20 + smtp_client.on('greeting', function (command) {
  21 + test.equals(smtp_client.response[0], 'hi');
  22 + test.equals('EHLO', command);
  23 + smtp_client.send_command(command, 'example.com');
  24 + });
  25 +
  26 + data.push('EHLO example.com');
  27 + data.push('250 hello');
  28 +
  29 + smtp_client.on('helo', function () {
  30 + test.equals(smtp_client.response[0], 'hello');
  31 + smtp_client.send_command('AUTH', 'PLAIN AHRlc3QAdGVzdHBhc3M=');
  32 + smtp_client.send_command('MAIL', 'FROM: me@example.com');
  33 + });
  34 +
  35 + data.push('AUTH PLAIN AHRlc3QAdGVzdHBhc3M='); // test/testpass
  36 + data.push('235 Authentication successful.');
  37 +
  38 + data.push('MAIL FROM: me@example.com');
  39 + data.push('250 sender ok');
  40 +
  41 + smtp_client.on('mail', function () {
  42 + test.equals(smtp_client.response[0], 'sender ok');
  43 + smtp_client.send_command('RCPT', 'TO: you@example.com');
  44 + });
  45 +
  46 + data.push('RCPT TO: you@example.com');
  47 + data.push('250 recipient ok');
  48 +
  49 + smtp_client.on('rcpt', function () {
  50 + test.equals(smtp_client.response[0], 'recipient ok');
  51 + smtp_client.send_command('DATA');
  52 + });
  53 +
  54 + data.push('DATA');
  55 + data.push('354 go ahead');
  56 +
  57 + smtp_client.on('data', function () {
  58 + test.equals(smtp_client.response[0], 'go ahead');
  59 + smtp_client.start_data(['Header: test\r\n', '\r\n', 'hi\r\n']);
  60 + });
  61 +
  62 + data.push('Header: test');
  63 + data.push('');
  64 + data.push('hi');
  65 + data.push('.');
  66 + data.push('250 message queued');
  67 +
  68 + smtp_client.on('dot', function () {
  69 + test.equals(smtp_client.response[0], 'message queued');
  70 + smtp_client.send_command('QUIT');
  71 + });
  72 +
  73 + data.push('QUIT');
  74 + data.push('221 goodbye');
  75 +
  76 + smtp_client.on('quit', function () {
  77 + test.equals(smtp_client.response[0], 'goodbye');
  78 + test.done();
  79 + });
  80 +
  81 + smtp_client.socket.write = function (line) {
  82 + if (data.length == 0) {
  83 + test.ok(false);
  84 + return;
  85 + }
  86 + test.equals(data.shift() + '\r\n', line);
  87 + if (reading_body && line == '.\r\n') {
  88 + reading_body = false;
  89 + }
  90 + if (!reading_body) {
  91 + if (line == 'DATA\r\n') {
  92 + reading_body = true;
  93 + }
  94 + while (true) {
  95 + var line = data.shift();
  96 + this.emit('line', line + '\r\n');
  97 + if (line[3] == ' ') break;
  98 + }
  99 + }
  100 +
  101 + return true;
  102 + };
  103 +
  104 + smtp_client.socket.emit('line', data.shift());
  105 +});

0 comments on commit 9e9d874

Please sign in to comment.
Something went wrong with that request. Please try again.