1 var net = require("net"),
  2     crypto = require("crypto"),
  3     tlslib = require("tls");
  4 
  5 /**
  6  * @namespace Mockup module
  7  * @name mockup
  8  */
  9 module.exports = runClientMockup;
 10 
 11 /**
 12  * <p>Runs a batch of commands against a server</p>
 13  * 
 14  * <pre>
 15  * var cmds = ["EHLO FOOBAR", "STARTTLS", "QUIT"];
 16  * runClientMockup(25, "mail.hot.ee", cmds, function(resp){
 17  *     console.log("Final:", resp.toString("utf-8").trim());
 18  * });
 19  * </pre>
 20  * 
 21  * @memberOf mockup
 22  * @param {Number} port Port number
 23  * @param {String} host Hostname to connect to
 24  * @param {Array} commands Command list to be sent to server
 25  * @param {Function} callback Callback function to run on completion,
 26  *        has the last response from the server as a param
 27  * @param {Boolean} [debug] if set to true log all input/output
 28  */
 29 function runClientMockup(port, host, commands, callback, debug){
 30     host = host || "localhost";
 31     port = port || 25;
 32     commands = Array.isArray(commands) ? commands : [];
 33 
 34     var command, ignore_data = false, sslcontext, pair;
 35 
 36     var socket = net.connect(port, host, function(){
 37         socket.on("data", function(chunk){
 38             if(ignore_data)return;
 39             
 40             if(debug){
 41                 console.log("S: "+chunk.toString("utf-8").trim());
 42             }
 43             
 44             if(!commands.length){
 45                 socket.end();
 46                 if(typeof callback == "function"){
 47                     callback(chunk);
 48                 }
 49                 return;
 50             }
 51             
 52             if(["STARTTLS", "STLS"].indexOf((command || "").trim().toUpperCase())>=0){
 53                 ignore_data = true;
 54                 if(debug){
 55                     console.log("Initiated TLS connection");
 56                 }
 57                 sslcontext = crypto.createCredentials();
 58                 pair = tlslib.createSecurePair(sslcontext, false);
 59                 
 60                 pair.encrypted.pipe(socket);
 61                 socket.pipe(pair.encrypted);
 62                 pair.fd = socket.fd;
 63                 
 64                 pair.on("secure", function(){
 65                     if(debug){
 66                         console.log("TLS connection secured");
 67                     }
 68                     command = commands.shift();
 69                     if(debug){
 70                         console.log("C: "+command);
 71                     }
 72                     pair.cleartext.write(command+"\r\n");
 73 
 74                     pair.cleartext.on("data", function(chunk){
 75                         if(debug){
 76                             console.log("S: "+chunk.toString("utf-8").trim());
 77                         }
 78                         
 79                         if(!commands.length){
 80                             pair.cleartext.end();
 81                             if(typeof callback == "function"){
 82                                 callback(chunk);
 83                             }
 84                             return;
 85                         }
 86                         command = commands.shift();
 87                         pair.cleartext.write(command+"\r\n");
 88                         if(debug){
 89                             console.log("C: "+command);
 90                         }
 91                     });
 92                 });
 93             }else{
 94                 command = commands.shift();
 95                 socket.write(command+"\r\n");
 96                 if(debug){
 97                     console.log("C: "+command);
 98                 }
 99             }
100         });
101     });
102     
103 }