@@ -66,7 +66,16 @@ fifo.prototype.toArray = function () {
6666*
6767* @param processCmdBlacklistRegex optional config array regex patterns who if match the
6868* command requested to be executed will be rejected
69- * with an error.
69+ * with an error. Blacklisted commands are checked
70+ * before whitelisted commands below
71+ *
72+ * [ '{regex:'regex1',flags:'ig'},
73+ * {regex:'regex2',flags:'m'}...]
74+ *
75+ * @param processCmdWhitelistRegex optional config array regex patterns who must match
76+ * the command requested to be executed otherwise
77+ * will be rejected with an error. Whitelisted commands
78+ * are checked AFTER blacklisted commands above...
7079*
7180* [ '{regex:'regex1',flags:'ig'},
7281* {regex:'regex2',flags:'m'}...]
@@ -106,11 +115,13 @@ fifo.prototype.toArray = function () {
106115* }
107116*
108117*
118+ *
109119*/
110120function ProcessProxy ( processToSpawn , arguments ,
111121 retainMaxCmdHistory , invalidateOnRegex ,
112122 cwd , envMap , uid , gid , logFunction ,
113123 processCmdBlacklistRegex ,
124+ processCmdWhitelistRegex ,
114125 autoInvalidationConfig ) {
115126
116127 this . _createdAt = new Date ( ) ;
@@ -138,6 +149,15 @@ function ProcessProxy(processToSpawn, arguments,
138149 this . _parseRegexes ( processCmdBlacklistRegex , [ this . _cmdBlacklistRegexes ] ) ;
139150 }
140151
152+ this . _cmdWhitelistRegexes = [ ] ; // holds RegExp objs
153+ this . _cmdWhitelistRegexesConfs = processCmdWhitelistRegex ; // retains orig configs
154+ if ( typeof ( processCmdWhitelistRegex ) == 'undefined' ) {
155+ // nothing to do
156+ } else {
157+ // parse them
158+ this . _parseRegexes ( processCmdWhitelistRegex , [ this . _cmdWhitelistRegexes ] ) ;
159+ }
160+
141161
142162 // auto invalidation config build
143163 this . _buildAutoInvalidationConfig ( autoInvalidationConfig ) ;
@@ -412,6 +432,13 @@ ProcessProxy.prototype._handleCommandFinished = function(command) {
412432* Returns true if the command is blacklisted due to a match, false on no matches
413433*/
414434ProcessProxy . prototype . _commandIsBlacklisted = function ( command ) {
435+
436+ // no blacklist? then its not blacklisted
437+ if ( this . _cmdBlacklistRegexes . length == 0 ) {
438+ return false ;
439+ }
440+
441+
415442 for ( var i = 0 ; i < this . _cmdBlacklistRegexes . length ; i ++ ) {
416443 var regexp = this . _cmdBlacklistRegexes [ i ] ;
417444 var result = regexp . exec ( command ) ;
@@ -426,6 +453,35 @@ ProcessProxy.prototype._commandIsBlacklisted = function(command) {
426453 return false ;
427454}
428455
456+ /**
457+ * _commandIsWhitelisted(command)
458+ *
459+ * Checks to see if current command matches any of the command
460+ * whitelist regexes
461+ *
462+ * Returns true if the command is whitelisted due to a match, false on no matches
463+ */
464+ ProcessProxy . prototype . _commandIsWhitelisted = function ( command ) {
465+
466+ // no whitelist? then its whitelisted
467+ if ( this . _cmdWhitelistRegexes . length == 0 ) {
468+ return true ;
469+ }
470+
471+ for ( var i = 0 ; i < this . _cmdWhitelistRegexes . length ; i ++ ) {
472+ var regexp = this . _cmdWhitelistRegexes [ i ] ;
473+ var result = regexp . exec ( command ) ;
474+
475+ if ( result ) {
476+ return ; // exit! command is whitelisted
477+ }
478+ }
479+
480+ this . _log ( 'error' , "ProcessProxy: command does not match any configured " +
481+ "whitelist regexes, command: " + command ) ;
482+ return false ;
483+ }
484+
429485
430486/**
431487* onData()
@@ -581,7 +637,7 @@ ProcessProxy.prototype.initialize = function(initCommands) {
581637 // run all initCommands if provided
582638 if ( initCommands ) {
583639
584- self . executeCommands ( initCommands )
640+ self . _executeCommands ( initCommands , false ) // skip black/whitelists
585641
586642 . then ( function ( cmdResults ) {
587643
@@ -769,23 +825,61 @@ ProcessProxy.prototype.executeCommand = function(command) {
769825*
770826**/
771827ProcessProxy . prototype . executeCommands = function ( commands ) {
828+ return this . _executeCommands ( commands , true ) ;
829+ }
830+
831+
832+ /**
833+ * Internal method only:
834+ *
835+ * executeCommands - takes an array of raw command strings and returns promise
836+ * to be fulfilled with a an array of
837+ * of [
838+ * {command:cmd1, stdout:xxxx, stderr:xxxxx},
839+ * {command:cmd2, stdout:xxxx, stderr:xxxxx}
840+ * ]
841+ *
842+ * @commands Array of raw command/shell statements to be executed
843+ * @enforceBlackWhitelists enforce white and blacklists
844+ *
845+ * @return Promise, on fulfill returns promise to be fulfilled with a
846+ * array of command results as described above, on reject
847+ * and Error object
848+ *
849+ **/
850+ ProcessProxy . prototype . _executeCommands = function ( commands , enforceBlackWhitelists ) {
772851
773852 self = this ;
774853
775854 return new Promise ( function ( fulfill , reject ) {
776855
777856 try {
778857
779- // scan for blacklisted, and fail fast
780- for ( var i = 0 ; i < commands . length ; i ++ ) {
781- var cmd = commands [ i ] ;
782- if ( self . _commandIsBlacklisted ( cmd ) ) {
858+ if ( enforceBlackWhitelists ) {
859+
860+ // scan for blacklisted, and fail fast
861+ for ( var i = 0 ; i < commands . length ; i ++ ) {
862+ var cmd = commands [ i ] ;
863+ if ( self . _commandIsBlacklisted ( cmd ) ) {
783864 reject ( new Error ( "Command cannot be executed as it matches a " +
784- "blacklist regex pattern, see logs: command: " + cmd ) ) ;
865+ "blacklist regex pattern, see logs: command: " + cmd ) ) ;
785866 return ; // exit!
867+ }
786868 }
869+
870+ // scan for whitelisted, and fail fast
871+ for ( var i = 0 ; i < commands . length ; i ++ ) {
872+ var cmd = commands [ i ] ;
873+ if ( ! self . _commandIsWhitelisted ( cmd ) ) {
874+ reject ( new Error ( "Command cannot be executed it does not match " +
875+ "our set of whitelisted commands, see logs: command: " + cmd ) ) ;
876+ return ; // exit!
877+ }
878+ }
879+
787880 }
788881
882+
789883 var cmdResults = [ ] ;
790884
791885 for ( var i = 0 ; i < commands . length ; i ++ ) {
@@ -849,7 +943,7 @@ ProcessProxy.prototype.shutdown = function(shutdownCommands) {
849943 // run all shutdownCommands if provided
850944 if ( shutdownCommands ) {
851945
852- self . executeCommands ( shutdownCommands )
946+ self . _executeCommands ( shutdownCommands , false ) // skip black/whitelists
853947
854948 . then ( function ( cmdResults ) {
855949
@@ -902,7 +996,8 @@ ProcessProxy.prototype.getStatus = function() {
902996 'options' :this . _processOptions ,
903997 'isValid' :this . _isValid ,
904998 'createdAt' :( this . _createdAt ? this . _createdAt . toISOString ( ) : null ) ,
905- 'cmdBlacklistRegexes' :this . _cmdBlacklistRegexesConfs ,
999+ 'cmdBlacklistRegexesConfs' :this . _cmdBlacklistRegexesConfs ,
1000+ 'cmdWhitelistRegexesConfs' :this . _cmdWhitelistRegexesConfs ,
9061001 'invalidateOnRegexConfig' :this . _invalidateOnRegexConfig ,
9071002 'autoInvalidationConfig' :this . _autoInvalidationConfig ,
9081003 'activeCommandStack' :[ ] ,
0 commit comments