Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0769227
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
5966430
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
91581e5
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
f5feee8
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
9f01da6
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
2ccbcd0
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
19a9723
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
369f12b
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
def3588
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
bb149c3
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
4670bda
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
d0700e5
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
9b33951
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
b95dc39
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
7f86e6b
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
ee9b56c
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
fadea2e
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
a64660e
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
f4068ae
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
d7f2934
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
06ea77b
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
e186f03
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
16c0eee
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
c6734ef
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
d37eb1e
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
6cb6e61
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
6a65681
fix(adhoc-sweep-fixes): 37 review findings across 27 files
flamingo[bot] Sep 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/changes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,21 @@ jobs:
"helm": ["./charts/**"]
}'

# any top-level directory not already covered above is tracked
# generically here so new components are not silently ignored
EXTRA_DIRS='[]'
while IFS= read -r dir; do
EXTRA_DIRS=$(jq -c --arg d "$dir" '. + [$d]' <<< "$EXTRA_DIRS")
done < <(
find . -maxdepth 1 -mindepth 1 -type d \
! -name '.git' ! -name '.github' ! -name 'docker' ! -name 'charts' \
-printf '%f\n' | sort
)

ADDONS=$(jq -nc --argjson addons "$ADDONS" --argjson extra "$EXTRA_DIRS" '
$addons + ( [ $extra[] | { key: ., value: ["./\(.)/**"] } ] | from_entries )
')

images_matrix=$(jq -c '[ .[] | {
name,
path: (.path // "./docker"),
Expand Down Expand Up @@ -109,3 +124,4 @@ jobs:
reduce $keys[] as $k ({}; .[$k] = ((($changed | index($k)) != null) | tostring))
')
echo "changes=$changes" >> "$GITHUB_OUTPUT"

9 changes: 9 additions & 0 deletions .github/workflows/sync-upstream.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ jobs:
exit 0
fi

if git ls-remote --exit-code --heads origin "$BRANCH" >/dev/null 2>&1; then
git fetch origin "$BRANCH"
if ! git merge-base --is-ancestor "origin/$BRANCH" origin/master; then
echo "::notice::$BRANCH has diverged from origin/master with manual commits — skipping to avoid overwriting them"
exit 0
fi
fi

git checkout -B "$BRANCH" origin/master
if ! git merge --no-ff --no-edit upstream/master; then
echo "::notice::merge has conflicts — skipping, will retry next run"
Expand All @@ -47,3 +55,4 @@ jobs:
gh pr create --repo "$GITHUB_REPOSITORY" --base master --head "$BRANCH" \
--title "Sync from Fork" \
--body "Automatic weekly sync from \`Ylianst/MeshCentral@master\`."

10 changes: 9 additions & 1 deletion agents/hashagents.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var fs = require('fs');
var crypto = require('crypto');

var agents = {
'MeshService.exe': 3,
Expand Down Expand Up @@ -30,6 +31,13 @@ var agents = {
'meshagent_osx-universal-64': 10005
}

function getSHA384FileHash(filename) {
var hash = crypto.createHash('sha384');
var data = fs.readFileSync(filename);
hash.update(data);
return hash.digest();
}

function getAgentInfo(filename, id) {
if (fs.existsSync(filename) != true) return null;
var stats = fs.statSync(filename);
Expand All @@ -42,4 +50,4 @@ for (var i in agents) {
if (info != null) { agentinfo[agents[i]] = info; }
}
console.log(JSON.stringify(agentinfo, null, 2));
process.exit();
process.exit();
9 changes: 5 additions & 4 deletions agents/meshinstall-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -144,26 +144,26 @@ DownloadAgent() {
meshid=$3
machineid=$4
echo "Downloading agent #$machineid..."
wget $url/meshagents?id=$machineid {{{wgetoptionshttps}}}-O ./meshagent || curl {{{curloptionshttps}}}--output ./meshagent $url/meshagents?id=$machineid
wget "$url/meshagents?id=$machineid" {{{wgetoptionshttps}}}-O ./meshagent || curl {{{curloptionshttps}}}--output ./meshagent "$url/meshagents?id=$machineid"

# If it did not work, try again using http
if [ $? != 0 ]
then
url=${url/"https://"/"http://"}
wget $url/meshagents?id=$machineid {{{wgetoptionshttp}}}-O ./meshagent || curl {{{curloptionshttp}}}--output ./meshagent $url/meshagents?id=$machineid
wget "$url/meshagents?id=$machineid" {{{wgetoptionshttp}}}-O ./meshagent || curl {{{curloptionshttp}}}--output ./meshagent "$url/meshagents?id=$machineid"
fi

if [ $? -eq 0 ]
then
echo "Agent downloaded."
# TODO: We could check the meshagent sha256 hash, but best to authenticate the server.
chmod 755 ./meshagent
wget $url/meshsettings?id=$meshid {{{wgetoptionshttps}}}-O ./meshagent.msh || curl {{{curloptionshttps}}}--output ./meshagent.msh $url/meshsettings?id=$meshid
wget "$url/meshsettings?id=$meshid" {{{wgetoptionshttps}}}-O ./meshagent.msh || curl {{{curloptionshttps}}}--output ./meshagent.msh "$url/meshsettings?id=$meshid"

# If it did not work, try again using http
if [ $? -ne 0 ]
then
wget $url/meshsettings?id=$meshid {{{wgetoptionshttp}}}-O ./meshagent.msh || curl {{{curloptionshttp}}}--output ./meshagent.msh $url/meshsettings?id=$meshid
wget "$url/meshsettings?id=$meshid" {{{wgetoptionshttp}}}-O ./meshagent.msh || curl {{{curloptionshttp}}}--output ./meshagent.msh "$url/meshsettings?id=$meshid"
fi

if [ $? -eq 0 ]
Expand Down Expand Up @@ -208,3 +208,4 @@ then
else
echo "Must be root to install or uninstall the agent."
fi

8 changes: 5 additions & 3 deletions agents/modules_meshcmd/amt-redir-duk.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
* @version v0.0.1f
*/

'use strict';

// Construct a MeshServer object
module.exports = function CreateAmtRedirect(module) {
var obj = {};
Expand Down Expand Up @@ -123,7 +125,7 @@ module.exports = function CreateAmtRedirect(module) {
var status = obj.amtaccumulator[1];
var authType = obj.amtaccumulator[4];
var authData = [];
for (i = 0; i < authDataLen; i++) { authData.push(obj.amtaccumulator[9 + i]); }
for (var i = 0; i < authDataLen; i++) { authData.push(obj.amtaccumulator[9 + i]); }
var authDataBuf = obj.amtaccumulator.slice(9, 9 + authDataLen);
cmdsize = 9 + authDataLen;
if (authType == 0) {
Expand Down Expand Up @@ -229,7 +231,7 @@ module.exports = function CreateAmtRedirect(module) {
obj.connectstate = 1;
obj.m.Start();
// KVM traffic, forward rest of accumulator directly.
if (obj.amtaccumulator.length > 8) { obj.m.ProcessData(obj.amtaccumulator.substring(8)); }
if (obj.amtaccumulator.length > 8) { obj.m.ProcessData(obj.amtaccumulator.slice(8)); }
cmdsize = obj.amtaccumulator.length;
break;
default:
Expand Down Expand Up @@ -306,4 +308,4 @@ function IntToStr(v) { return String.fromCharCode((v >> 24) & 0xFF, (v >> 16) &
function IntToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF, (v >> 24) & 0xFF); }

var md5hasher = require('MD5Stream').create();
function hex_md5(a) { return md5hasher.syncHash(a).toString('hex').toLowerCase(); }
function hex_md5(a) { return md5hasher.syncHash(a).toString('hex').toLowerCase(); }
9 changes: 8 additions & 1 deletion agents/modules_meshcmd/amt-xml.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,15 @@ function _ParseWsmanRec(node) {
return r;
}

function _GetNameFromUrl(url) {
if (!url) return url;
var i = url.lastIndexOf('/');
return (i >= 0) ? url.substring(i + 1) : url;
}

function _PutObjToBodyXml(resuri, putObj) {
if (!resuri || putObj == null) return '';
var objname = obj.GetNameFromUrl(resuri);
var objname = _GetNameFromUrl(resuri);
var result = '<r:' + objname + ' xmlns:r="' + resuri + '">';

for (var prop in putObj) {
Expand Down Expand Up @@ -187,3 +193,4 @@ function _turnToXmlRec(text) {
} catch (ex) { return null; }
return lastElement;
}

3 changes: 3 additions & 0 deletions agents/modules_meshcore/monitor-border.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ function windows_monitorborder()

this.Stop = function Stop()
{
clearInterval(info.redInterval);
info.redInterval = null;

var drawRect = gm.CreateVariable(16);
Expand Down Expand Up @@ -144,6 +145,7 @@ function linux_monitorborder()

this.Stop = function Stop()
{
clearTimeout(this._timeout);
this._timeout = null;
if(!this._isUnity)
{
Expand Down Expand Up @@ -333,3 +335,4 @@ switch(process.platform)




10 changes: 6 additions & 4 deletions agents/modules_meshcore/sysinfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,12 @@ function linux_cpuUtilization() {
for (y = x; y < columns.length; ++y) { currSum += parseInt(columns[y]); }
currIdle = parseInt(columns[3 + x]);

var diffIdle = currIdle - cpuLastIdle[cpuNo];
var diffSum = currSum - cpuLastSum[cpuNo];
var isFirstSample = (cpuLastIdle[cpuNo] === undefined || cpuLastSum[cpuNo] === undefined);

utilization = (100 - ((diffIdle / diffSum) * 100));
var diffIdle = isFirstSample ? 0 : (currIdle - cpuLastIdle[cpuNo]);
var diffSum = isFirstSample ? 0 : (currSum - cpuLastSum[cpuNo]);

utilization = isFirstSample ? 0 : (100 - ((diffIdle / diffSum) * 100));

cpuLastSum[cpuNo] = currSum;
cpuLastIdle[cpuNo] = currIdle;
Expand Down Expand Up @@ -222,7 +224,7 @@ function macos_memUtilization()
}
else
{
throw ('Parse Error');
throw (new Error('Parse Error'));
}
}

Expand Down
8 changes: 5 additions & 3 deletions agents/modules_meshcore/wifi-scanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,15 @@ function WiFiScanner()
{
this.child = require('child_process').execFile('/sbin/iwlist', ['iwlist', wlan, 'scan']);
this.child.parent = this;
this.child.str = '';
this.child.ms = new MemoryStream();
this.child.ms.parent = this.child;
this.child.stdout.on('data', function (buffer) { this.parent.ms.write(buffer); });
this.child.stdout.on('data', function (buffer) { this.parent.str += buffer.toString(); this.parent.ms.write(buffer); });
this.child.on('exit', function () { this.ms.end(); });
this.child.ms.on('end', function ()
{
var str = this.buffer.toString();
tokens = str.split(' - Address: ');
var str = this.parent.str;
var tokens = str.split(' - Address: ');
for (var block in tokens)
{
if (block == 0) continue;
Expand Down Expand Up @@ -125,3 +126,4 @@ module.exports = WiFiScanner;




5 changes: 4 additions & 1 deletion crowdsec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ module.exports.CreateCrowdSecBouncer = function (parent, config) {
// Setup constants
const { getLogger } = require('@crowdsec/express-bouncer/src/nodejs-bouncer/lib/logger');
const { configure, renderBanWall, testConnectionToCrowdSec, getRemediationForIp } = require('@crowdsec/express-bouncer/src/nodejs-bouncer');
const applyCaptcha = require('@crowdsec/express-bouncer/src/express-crowdsec-middleware/lib/captcha');
const { BYPASS_REMEDIATION, CAPTCHA_REMEDIATION, BAN_REMEDIATION } = require('@crowdsec/express-bouncer/src/nodejs-bouncer/lib/constants'); // "bypass", "captcha", "ban";
const svgCaptcha = require('svg-captcha');
const { renderCaptchaWall } = require('@crowdsec/express-bouncer/src/nodejs-bouncer');
Expand Down Expand Up @@ -118,6 +117,10 @@ module.exports.CreateCrowdSecBouncer = function (parent, config) {
}
}

if (currentCaptchaIpList[ip] == null) {
generateCaptcha(ip, captchaGenerationCacheDuration);
}

const captchaWallTemplate = await renderCaptchaWall({ captchaImageTag: currentCaptchaIpList[ip].data, captchaResolutionFormUrl: '', error });
res.status(401);
res.send(captchaWallTemplate);
Expand Down
5 changes: 2 additions & 3 deletions mcrec.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,12 @@ function readLastBlock(state, func) {
var magic = buf.toString('utf8', 16, 32);
if ((type == 3) && (size == 16) && (magic == 'MeshCentralMCNDX')) {
// Extra metadata present, lets read it.
extraMetadata = null;
var buf2 = Buffer.alloc(16);
fs.read(state.recFile, buf2, 0, 16, time, function (err, bytesRead, buf2) {
var xtype = buf2.readUInt16BE(0); // Type (1 = Header, 2 = Network Data, 3 = End, 4 = Extra Metadata)
var xflags = buf2.readUInt16BE(2); // Flags (1 = Binary, 2 = User)
var xsize = buf2.readUInt32BE(4); // Size
var xtime = buf.readUIntBE(10, 6); // Time
var xtime = buf2.readUIntBE(10, 6); // Time
var buf3 = Buffer.alloc(xsize);
fs.read(state.recFile, buf3, 0, xsize, time + 16, function (err, bytesRead, buf3) {
func(state, true, xtime, JSON.parse(buf3.toString()));
Expand Down Expand Up @@ -331,4 +330,4 @@ if (directRun) { setup(); }

// Export table
module.exports.startEx = startEx;
module.exports.indexFile = indexFile;
module.exports.indexFile = indexFile;
19 changes: 14 additions & 5 deletions meshmessaging.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,14 +295,17 @@ module.exports.CreateServer = function (parent) {
// Example: findUserByTab('aaaa#0000', function (userid) { sendMsg(userid, 'message'); });
async function discordFindUserByTag(userTag, func) {
var username = userTag.split('#')[0];
var found = false;
const guilds = await obj.discordClient.guilds.fetch();
guilds.forEach(async function (value, key) {
for (const [key, value] of guilds) {
var guild = await value.fetch();
const guildMembers = await guild.members.search({ query: username });
guildMembers.forEach(async function (value, key) {
if ((value.user.username + (value.user.discriminator != '0' ? '#' + value.user.discriminator : ''))== userTag) { func(key); return; }
});
});
for (const [memberKey, memberValue] of guildMembers) {
if ((memberValue.user.username + (memberValue.user.discriminator != '0' ? '#' + memberValue.user.discriminator : '')) == userTag) { found = true; func(memberKey); break; }
}
if (found) break;
}
if (!found) { func(null); }
}

// Send an XMPP message
Expand All @@ -323,6 +326,11 @@ module.exports.CreateServer = function (parent) {
sendTelegramMessage(to, msg, func);
} else if ((to.startsWith('discord:')) && (obj.discordClient != null)) { // Discord
discordFindUserByTag(to.substring(8), function (userid) {
if (userid == null) {
parent.debug('email', 'Discord user not found: ' + to.substring(8));
if (func != null) { func(false, 'Discord user not found.'); }
return;
}
parent.debug('email', 'Sending Discord message to: ' + to.substring(9) + ', ' + userid + ': ' + msg);
discordSendMsg(userid, msg); if (func != null) { func(true); }
});
Expand Down Expand Up @@ -773,3 +781,4 @@ module.exports.SetupTelegram = async function (parent) {
console.log('Telegram seems to be configured correctly in the config.json, no need to run --setuptelegram.');
process.exit();
};

6 changes: 3 additions & 3 deletions meshscanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ module.exports.CreateMeshScanner = function (parent) {
if ((typeof obj.parent.config.domains[''].title2 == 'string') && (obj.parent.config.domains[''].title2.length > 0)) {
info = obj.common.replacePlaceholders(obj.parent.config.domains[''].title2, {
'serverversion': obj.parent.currentVer,
'servername': obj.getWebServerName(domain, req),
'servername': parent.certificates.CommonName,
'agentsessions': Object.keys(parent.webserver.wsagents).length,
'connectedusers': Object.keys(parent.webserver.wssessions).length,
'userssessions': Object.keys(parent.webserver.wssessions2).length,
Expand Down Expand Up @@ -245,7 +245,7 @@ module.exports.CreateMeshScanner = function (parent) {
function sendPendingPacket() {
if (obj.pendingOutboundPackets.length == 0) { if (obj.pendingOutboundTimer != null) { clearInterval(obj.pendingOutboundTimer); obj.pendingOutboundTimer = null; } return; }
var packet = obj.pendingOutboundPackets.shift();
if (packet != null) { packet[0].send(packet[1], 0, packet[1].length, packet[2], packet[3]); }
if (packet != null) { try { packet[0].send(packet[1], 0, packet[1].length, packet[2], packet[3]); } catch (e) { } }
}

// As a side job, we also send server wake-on-lan packets
Expand Down Expand Up @@ -276,4 +276,4 @@ module.exports.CreateMeshScanner = function (parent) {
};

return obj;
};
};
8 changes: 4 additions & 4 deletions monitoring.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ module.exports.CreateMonitoring = function (parent, args) {
ConnectedUsers: { description: "Connected Users" }, // Object.keys(parent.webserver.wssessions).length
UsersSessions: { description: "Users Sessions" }, // Object.keys(parent.webserver.wssessions2).length
RelaySessions: { description: "Relay Sessions" }, // parent.webserver.relaySessionCount
RelayCount: { description: "Relay Count" } // Object.keys(parent.webserver.wsrelays).length30bb4fb74dfb758d36be52a7
RelayCount: { description: "Relay Count" } // Object.keys(parent.webserver.wsrelays).length
}
obj.collectors = [];
if (parent.config.settings.prometheus != null) { // Create Prometheus Monitoring Endpoint
Expand Down Expand Up @@ -76,10 +76,10 @@ module.exports.CreateMonitoring = function (parent, args) {
UsersSessions: Object.keys(parent.webserver.wssessions2).length,
RelaySessions: parent.webserver.relaySessionCount,
RelayCount: Object.keys(parent.webserver.wsrelays).length,
ConnectedIntelAMT: 0
ConnectedIntelAMT: 0,
ConnectedIntelAMTCira: 0
};
if (parent.mpsserver != null) {
gauges.ConnectedIntelAMTCira = 0;
for (var i in parent.mpsserver.ciraConnections) {
gauges.ConnectedIntelAMTCira += parent.mpsserver.ciraConnections[i].length;
}
Expand Down Expand Up @@ -119,4 +119,4 @@ module.exports.CreateMonitoring = function (parent, args) {
}
}
return obj;
}
}
3 changes: 2 additions & 1 deletion pkcs7-modified.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ try {
require('../node-forge/lib/pkcs7asn1');
require('../node-forge/lib/random');
require('../node-forge/lib/util');
require('../node-forge/lib/x509'); f
require('../node-forge/lib/x509');
} catch (ex) { }

if (forge == null) {
Expand Down Expand Up @@ -1277,3 +1277,4 @@ function _decryptContent(msg) {
msg.content = ciph.output;
}
}

Loading