mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-04-29 06:07:55 -04:00
externalsignjob - External Code Signing Job (#6977)
* Moving external call back into meshcentral * Debugging logging * Moved the external call to the callback function * Updated codesigning.md * Move callback invoke of callExternalSignJob outside of err check * change console.log to obj.debug for external sign job call logging * obj debug signing failed using obj.debug and console.error inside callExternalSignJob
This commit is contained in:
parent
11ae3775d3
commit
5b974e8226
@ -99,3 +99,50 @@ Now that MeshCentral customizes and signs the agent, you can set that value to a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## External Signing Job
|
||||||
|
|
||||||
|
The externalsignjob feature allows you to perform additional operations on the agent after MeshCentral completes its code signing process. This is particularly useful for:
|
||||||
|
|
||||||
|
1. Using hardware security tokens for signing
|
||||||
|
2. Performing signing on a separate server or cloud host
|
||||||
|
3. Archiving signed agents
|
||||||
|
4. Adding additional security measures
|
||||||
|
|
||||||
|
The externalsignjob is called after MeshCentral completes its entire code signing process, including:
|
||||||
|
- Resource modification
|
||||||
|
- Digital signature application
|
||||||
|
- Timestamp application (if configured)
|
||||||
|
|
||||||
|
To use this feature, add the following to your config.json:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"settings": {
|
||||||
|
"externalsignjob": "path/to/your/script.bat"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The script will receive the path to the agent as its first argument. Here are example scripts:
|
||||||
|
|
||||||
|
### Batch File Example
|
||||||
|
```batch
|
||||||
|
@echo off
|
||||||
|
Echo External Signing Job
|
||||||
|
signtool sign /tr http://timestamp.sectigo.com /td SHA256 /fd SHA256 /a /v /f path/to/your/signing.cer /csp "eToken Base Cryptographic Provider" /k "[{{MyPassword}}]=PrivateKeyContainerName" "%~1"
|
||||||
|
```
|
||||||
|
|
||||||
|
### PowerShell Example
|
||||||
|
```powershell
|
||||||
|
$file = $args[0]
|
||||||
|
signtool sign /tr http://timestamp.sectigo.com /td SHA256 /fd SHA256 /a /v /f path/to/your/signing.cer /csp "eToken Base Cryptographic Provider" /k "[{{MyPassword}}]=PrivateKeyContainerName" $file
|
||||||
|
```
|
||||||
|
|
||||||
|
The externalsignjob can be used for more than just signing. For example, you could:
|
||||||
|
|
||||||
|
1. Archive signed agents to a secure location
|
||||||
|
2. Upload signed agents to a distribution server
|
||||||
|
3. Perform additional security checks
|
||||||
|
4. Add custom metadata or watermarks
|
||||||
|
5. Integrate with your organization's build pipeline
|
||||||
|
|
||||||
|
Note: The script must return a success exit code (0) for the process to be considered successful. Any non-zero exit code will be treated as a failure and will be logged.
|
||||||
|
@ -3415,6 +3415,7 @@ function CreateMeshCentralServer(config, args) {
|
|||||||
// Failed to sign agent
|
// Failed to sign agent
|
||||||
addServerWarning('Failed to sign \"' + agentSignedFunc.objx.meshAgentsArchitectureNumbers[agentSignedFunc.archid].localname + '\": ' + err, 22, [agentSignedFunc.objx.meshAgentsArchitectureNumbers[agentSignedFunc.archid].localname, err]);
|
addServerWarning('Failed to sign \"' + agentSignedFunc.objx.meshAgentsArchitectureNumbers[agentSignedFunc.archid].localname + '\": ' + err, 22, [agentSignedFunc.objx.meshAgentsArchitectureNumbers[agentSignedFunc.archid].localname, err]);
|
||||||
}
|
}
|
||||||
|
obj.callExternalSignJob(agentSignedFunc.signingArguments); // Call external signing job regardless of success or failure
|
||||||
if (--pendingOperations === 0) { agentSignedFunc.func(); }
|
if (--pendingOperations === 0) { agentSignedFunc.func(); }
|
||||||
}
|
}
|
||||||
pendingOperations++;
|
pendingOperations++;
|
||||||
@ -3470,7 +3471,10 @@ function CreateMeshCentralServer(config, args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const signingArguments = { out: signeedagentpath, desc: signDesc, url: signUrl, time: timeStampUrl, proxy: timeStampProxy }; // Shallow clone
|
const signingArguments = { out: signeedagentpath, desc: signDesc, url: signUrl, time: timeStampUrl, proxy: timeStampProxy }; // Shallow clone
|
||||||
|
signingArguments.resChanges = resChanges;
|
||||||
|
|
||||||
obj.debug('main', "Code signing with arguments: " + JSON.stringify(signingArguments));
|
obj.debug('main', "Code signing with arguments: " + JSON.stringify(signingArguments));
|
||||||
|
xagentSignedFunc.signingArguments = signingArguments; // Attach the signing arguments to the callback function
|
||||||
if (resChanges == false) {
|
if (resChanges == false) {
|
||||||
// Sign the agent the simple way, without changing any resources.
|
// Sign the agent the simple way, without changing any resources.
|
||||||
originalAgent.sign(agentSignCertInfo, signingArguments, xagentSignedFunc);
|
originalAgent.sign(agentSignCertInfo, signingArguments, xagentSignedFunc);
|
||||||
@ -3479,16 +3483,40 @@ function CreateMeshCentralServer(config, args) {
|
|||||||
// NOTE: This is experimental and could corupt the agent.
|
// NOTE: This is experimental and could corupt the agent.
|
||||||
originalAgent.writeExecutable(signingArguments, agentSignCertInfo, xagentSignedFunc);
|
originalAgent.writeExecutable(signingArguments, agentSignCertInfo, xagentSignedFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Signed agent is already ok, use it.
|
// Signed agent is already ok, use it.
|
||||||
originalAgent.close();
|
originalAgent.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (--pendingOperations === 0) { func(); }
|
if (--pendingOperations === 0) { func(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obj.callExternalSignJob = function (signingArguments) {
|
||||||
|
if (obj.config.settings && !obj.config.settings.externalsignjob) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
obj.debug('main', "External signing job called for file: " + signingArguments.out);
|
||||||
|
|
||||||
|
const { spawnSync } = require('child_process');
|
||||||
|
|
||||||
|
const signResult = spawnSync('"' + obj.config.settings.externalsignjob + '"', ['"' + signingArguments.out + '"'], {
|
||||||
|
encoding: 'utf-8',
|
||||||
|
shell: true,
|
||||||
|
stdio: 'inherit'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (signResult.error || signResult.status !== 0) {
|
||||||
|
obj.debug('main', "External signing failed for file: " + signingArguments.out);
|
||||||
|
console.error("External signing failed for file: " + signingArguments.out);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update the list of available mesh agents
|
// Update the list of available mesh agents
|
||||||
obj.updateMeshAgentsTable = function (domain, func) {
|
obj.updateMeshAgentsTable = function (domain, func) {
|
||||||
// Check if a custom agent signing certificate is available
|
// Check if a custom agent signing certificate is available
|
||||||
|
Loading…
x
Reference in New Issue
Block a user