Added work around for agents older than v0.4.7-o that have an HTTP bug where the initial fragment can be duplicated

Bryan Roe committed Aug 16, 2021 at 23:50 UTC 8e0f30ae3527b10de9197c09b3589a4d115d1646
1 file changed +63 -15
agents/recoverycore.js
+63 -15
@@ -6,6 +6,8 @@ var nextTunnelIndex = 1;
6 var tunnels = {};
7 var fs = require('fs');
8
9 +var needStreamFix = (new Date(process.versions.meshAgent) < new Date('2020-01-21 13:27:45.000-08:00'));
10 +
11 try
12 {
13 Object.defineProperty(Array.prototype, 'find', {
@@ -626,33 +628,42 @@ function agentUpdate_Start(updateurl, updateoptions) {
628 sendAgentMessage('Self Update failed, because there was a problem trying to download the update from ' + updateurl, 3);
629 agentUpdate_Start._selfupdate = null;
630 });
629 - agentUpdate_Start._selfupdate.on('response', function (img) {
631 + agentUpdate_Start._selfupdate.on('response', function (img)
632 + {
633 + var self = this;
634 this._file = require('fs').createWriteStream(agentfilename + (process.platform=='win32'?'.update.exe':'.update'), { flags: 'wb' });
635 this._filehash = require('SHA384Stream').create();
632 - this._filehash.on('hash', function (h) {
633 - if (updateoptions != null && updateoptions.hash != null) {
634 - if (updateoptions.hash.toLowerCase() == h.toString('hex').toLowerCase()) {
636 + this._filehash.on('hash', function (h)
637 + {
638 + if (updateoptions != null && updateoptions.hash != null)
639 + {
640 + if (updateoptions.hash.toLowerCase() == h.toString('hex').toLowerCase())
641 + {
642 if (sessionid != null) { sendConsoleText('Download complete. HASH verified.', sessionid); }
643 }
637 - else {
644 + else
645 + {
646 agentUpdate_Start._retryCount++;
647 sendConsoleText('Self Update FAILED because the downloaded agent FAILED hash check (' + agentUpdate_Start._retryCount + '), URL: ' + updateurl, sessionid);
648 sendAgentMessage('Self Update FAILED because the downloaded agent FAILED hash check (' + agentUpdate_Start._retryCount + '), URL: ' + updateurl, 3);
649 agentUpdate_Start._selfupdate = null;
650
643 - if (agentUpdate_Start._retryCount < 4) {
651 + if (agentUpdate_Start._retryCount < 4)
652 + {
653 // Retry the download again
654 sendConsoleText('Self Update will try again in 60 seconds...', sessionid);
655 agentUpdate_Start._timeout = setTimeout(agentUpdate_Start, 60000, updateurl, updateoptions);
656 }
648 - else {
657 + else
658 + {
659 sendConsoleText('Self Update giving up, too many failures...', sessionid);
660 sendAgentMessage('Self Update giving up, too many failures...', 3);
661 }
662 return;
663 }
664 }
655 - else {
665 + else
666 + {
667 sendConsoleText('Download complete. HASH=' + h.toString('hex'), sessionid);
668 }
669
@@ -660,11 +671,13 @@ function agentUpdate_Start(updateurl, updateoptions) {
671 try { require('MeshAgent').SendCommand({ action: 'agentupdatedownloaded' }); } catch (e) { }
672
673 if (sessionid != null) { sendConsoleText('Updating and restarting agent...', sessionid); }
663 - if (process.platform == 'win32') {
674 + if (process.platform == 'win32')
675 + {
676 // Use _wexecve() equivalent to perform the update
677 windows_execve(name, agentfilename, sessionid);
678 }
667 - else {
679 + else
680 + {
681 var m = require('fs').statSync(process.execPath).mode;
682 require('fs').chmodSync(process.cwd() + agentfilename + '.update', m);
683
@@ -678,7 +691,8 @@ function agentUpdate_Start(updateurl, updateoptions) {
691 // erase update
692 require('fs').unlinkSync(process.cwd() + agentfilename + '.update');
693
681 - switch (process.platform) {
694 + switch (process.platform)
695 + {
696 case 'freebsd':
697 bsd_execv(name, agentfilename, sessionid);
698 break;
@@ -686,12 +700,14 @@ function agentUpdate_Start(updateurl, updateoptions) {
700 linux_execv(name, agentfilename, sessionid);
701 break;
702 default:
689 - try {
703 + try
704 + {
705 // restart service
706 var s = require('service-manager').manager.getService(name);
707 s.restart();
708 }
694 - catch (zz) {
709 + catch (zz)
710 + {
711 sendConsoleText('Self Update encountered an error trying to restart service', sessionid);
712 sendAgentMessage('Self Update encountered an error trying to restart service', 3);
713 }
@@ -699,8 +715,40 @@ function agentUpdate_Start(updateurl, updateoptions) {
715 }
716 }
717 });
702 - img.pipe(this._file);
703 - img.pipe(this._filehash);
718 +
719 + if (!needStreamFix)
720 + {
721 + img.pipe(this._file);
722 + img.pipe(this._filehash);
723 + }
724 + else
725 + {
726 + img.once('data', function (buffer)
727 + {
728 + if(this.immediate)
729 + {
730 + clearImmediate(this.immediate);
731 + this.immediate = null;
732 +
733 + // No need to apply fix
734 + self._file.write(buffer);
735 + self._filehash.write(buffer);
736 +
737 + this.pipe(self._file);
738 + this.pipe(self._filehash);
739 + }
740 + else
741 + {
742 + // Need to apply fix
743 + this.pipe(self._file);
744 + this.pipe(self._filehash);
745 + }
746 + });
747 + this.immediate = setImmediate(function (self)
748 + {
749 + self.immediate = null;
750 + },this);
751 + }
752 });
753 }
754 }