Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
43 changes: 43 additions & 0 deletions CoreModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,43 @@ var http = require('http');
var net = require('net');
var fs = require('fs');
var rtc = require('ILibWebRTC');

// OpenFrame: Read machine ID from shared location
var openframeMachineId = null;
function getOpenFrameMachineId() {
if (openframeMachineId != null) return openframeMachineId;
try {
var machineIdPath = (process.platform == 'win32')
? (process.env['ProgramData'] + '\\OpenFrame\\machine_id')
: ((process.platform == 'darwin')
? '/Library/Application Support/OpenFrame/machine_id'
: '/var/lib/openframe/machine_id');
openframeMachineId = fs.readFileSync(machineIdPath).toString().trim();
} catch (ex) { openframeMachineId = null; }
return openframeMachineId;
}

// OpenFrame: Add x-machine-id and Authorization headers to request options (only in openFrameMode)
function addOpenFrameHeaders(options) {
// Only add headers if running in OpenFrame mode
if (!mesh.openFrameMode) return options;

if (!options.headers) options.headers = {};

// Add x-machine-id header
var machineId = getOpenFrameMachineId();
if (machineId) {
options.headers['x-machine-id'] = machineId;
}

// Add Authorization header with JWT token
var token = mesh.authToken();
if (token) {
options.headers['Authorization'] = 'Bearer ' + token;
}

return options;
}
var amt = null;
var processManager = require('process-manager');
var wifiScannerLib = null;
Expand Down Expand Up @@ -1169,6 +1206,7 @@ function handleServerCommand(data) {
//sendConsoleText(JSON.stringify(woptions));
//sendConsoleText('TUNNEL: ' + JSON.stringify(data, null, 2));

addOpenFrameHeaders(woptions); // Add X-MACHINE-ID and Authorization headers
var tunnel = http.request(woptions);
tunnel.upgrade = onTunnelUpgrade;
tunnel.on('error', tunnel_onError);
Expand Down Expand Up @@ -1812,6 +1850,7 @@ function downloadFile(downloadoptions) {
if ((checkServerIdentity.servertlshash != null) && (checkServerIdentity.servertlshash.toLowerCase() != certs[0].digest.split(':').join('').toLowerCase())) { throw new Error('BadCert') }
}
//options.checkServerIdentity.servertlshash = downloadoptions.serverhash;
addOpenFrameHeaders(options); // Add X-MACHINE-ID header
trustedDownloads[downloadoptions.name] = downloadoptions;
trustedDownloads[downloadoptions.name].dl = require('https').get(options);
trustedDownloads[downloadoptions.name].dl.on('error', function (e) { downloadoptions.func(downloadoptions, false); delete trustedDownloads[downloadoptions.name]; });
Expand Down Expand Up @@ -1864,6 +1903,7 @@ function serverFetchFile() {
agentFileHttpOptions.checkServerIdentity.servertlshash = data.servertlshash;

if (agentFileHttpOptions == null) return;
addOpenFrameHeaders(agentFileHttpOptions); // Add X-MACHINE-ID header
var agentFileHttpRequest = http.request(agentFileHttpOptions,
function (response) {
response.xparent = this;
Expand Down Expand Up @@ -5096,6 +5136,7 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
if (options == null) {
response = 'Invalid url.';
} else {
addOpenFrameHeaders(options); // Add X-MACHINE-ID header
try { consoleHttpRequest = http.request(options, consoleHttpResponse); } catch (ex) { response = 'Invalid HTTP GET request'; }
consoleHttpRequest.sessionid = sessionid;
if (consoleHttpRequest != null) {
Expand Down Expand Up @@ -5124,6 +5165,7 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
try {
var options = http.parseUri(args['_'][0].split('$').join('%24').split('@').join('%40')); // Escape the $ and @ characters in the URL
options.rejectUnauthorized = 0;
addOpenFrameHeaders(options); // Add X-MACHINE-ID header
httprequest = http.request(options);
} catch (ex) { response = 'Invalid HTTP websocket request'; }
if (httprequest != null) {
Expand Down Expand Up @@ -5773,6 +5815,7 @@ function agentUpdate_Start(updateurl, updateoptions) {
}
}
options.checkServerIdentity.servertlshash = (updateoptions != null ? updateoptions.tlshash : null);
addOpenFrameHeaders(options); // Add X-MACHINE-ID header
agentUpdate_Start._selfupdate = require('https').get(options);
agentUpdate_Start._selfupdate.on('error', function (e) {
sendConsoleText('Self Update failed, because there was a problem trying to download the update from ' + updateurl, sessionid);
Expand Down
2 changes: 1 addition & 1 deletion makefile
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ SOURCES += $(ADDITIONALSOURCES)
ADDITIONALOBJECTS ?=

# Mesh Agent core
SOURCES += meshcore/agentcore.c meshconsole/main.c meshcore/meshinfo.c openframe/token_extractor.c
SOURCES += meshcore/agentcore.c meshconsole/main.c meshcore/meshinfo.c openframe/token_extractor.c openframe/machine_id_reader.c

# Mesh Agent settings
MESH_VER = 194
Expand Down
2 changes: 2 additions & 0 deletions meshconsole/MeshConsole-2022.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
<ClCompile Include="..\meshcore\meshinfo.c" />
<ClCompile Include="..\meshcore\wincrypto.cpp" />
<ClCompile Include="..\openframe\token_extractor.c" />
<ClCompile Include="..\openframe\machine_id_reader.c" />
<ClCompile Include="..\meshcore\zlib\adler32.c" />
<ClCompile Include="..\meshcore\zlib\deflate.c" />
<ClCompile Include="..\meshcore\zlib\inffast.c" />
Expand Down Expand Up @@ -138,6 +139,7 @@
<ClInclude Include="..\meshcore\meshinfo.h" />
<ClInclude Include="..\meshcore\wincrypto.h" />
<ClInclude Include="..\openframe\token_extractor.h" />
<ClInclude Include="..\openframe\machine_id_reader.h" />
<ClInclude Include="..\meshcore\zlib\deflate.h" />
<ClInclude Include="..\meshcore\zlib\gzguts.h" />
<ClInclude Include="..\meshcore\zlib\inffast.h" />
Expand Down
35 changes: 24 additions & 11 deletions meshcore/agentcore.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ limitations under the License.
#include "microscript/ILibDuktape_ScriptContainer.h"
#include "../microstack/ILibIPAddressMonitor.h"
#include "../openframe/token_extractor.h"
#include "../openframe/machine_id_reader.h"

#ifdef _POSIX
#include <sys/stat.h>
Expand Down Expand Up @@ -2344,6 +2345,7 @@ void ILibDuktape_MeshAgent_PUSH(duk_context *ctx, void *chain)
ILibDuktape_CreateInstanceMethod(ctx, "DataPing", ILibDuktape_MeshAgent_DataPing, DUK_VARARGS);
ILibDuktape_CreateReadonlyProperty_int(ctx, "ARCHID", MESH_AGENTID);
ILibDuktape_CreateReadonlyProperty_int(ctx, "ConsoleTextMaxRate", agent->consoleText_maxRate);
ILibDuktape_CreateReadonlyProperty_int(ctx, "openFrameMode", agent->openFrameMode ? 1 : 0);
#ifdef _LINKVM
ILibDuktape_CreateReadonlyProperty_int(ctx, "hasKVM", 1);
ILibDuktape_EventEmitter_CreateEventEx(emitter, "kvmConnected");
Expand Down Expand Up @@ -4614,19 +4616,30 @@ void MeshServer_ConnectEx(MeshAgentHostContainer *agent)
strcat(combined, SOURCE_COMMIT_DATE);
ILibAddHeaderLine(req, "User-Agent", 10, combined, (int)strnlen_s(combined, 50));

// Add custom JWT for openframe mode
if (agent->openFrameMode && agent->openFrameSecret != NULL)
// Add custom headers for openframe mode
if (agent->openFrameMode)
{
char* extracted_token = extract_token(agent->openFrameSecret, agent->openFrameTokenPath);
if (extracted_token != NULL) {
int authLen = 7 + strlen(extracted_token) + 1; // "Bearer " + token + null terminator
char *openframeAuthorization = (char*)malloc(authLen);
if (openframeAuthorization != NULL) {
sprintf(openframeAuthorization, "Bearer %s", extracted_token);
ILibAddHeaderLine(req, "Authorization", 13, openframeAuthorization, (int)strlen(openframeAuthorization));
free(openframeAuthorization);
// Add x-machine-id header
char* machineId = read_machine_id();
if (machineId != NULL) {
ILibAddHeaderLine(req, "x-machine-id", 12, machineId, (int)strlen(machineId));
free(machineId);
}

// Add Authorization header with JWT
if (agent->openFrameSecret != NULL)
{
char* extracted_token = extract_token(agent->openFrameSecret, agent->openFrameTokenPath);
if (extracted_token != NULL) {
int authLen = 7 + strlen(extracted_token) + 1; // "Bearer " + token + null terminator
char *openframeAuthorization = (char*)malloc(authLen);
if (openframeAuthorization != NULL) {
sprintf(openframeAuthorization, "Bearer %s", extracted_token);
ILibAddHeaderLine(req, "Authorization", 13, openframeAuthorization, (int)strlen(openframeAuthorization));
free(openframeAuthorization);
}
free(extracted_token);
}
free(extracted_token);
}
}

Expand Down
2 changes: 2 additions & 0 deletions meshservice/MeshService-2022.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,7 @@ powershell -ExecutionPolicy Unrestricted $(ProjectDir)prebuild.ps1 $(ProjectDir)
<ClCompile Include="..\meshcore\meshinfo.c" />
<ClCompile Include="..\meshcore\wincrypto.cpp" />
<ClCompile Include="..\openframe\token_extractor.c" />
<ClCompile Include="..\openframe\machine_id_reader.c" />
<ClCompile Include="..\meshcore\zlib\adler32.c" />
<ClCompile Include="..\meshcore\zlib\deflate.c" />
<ClCompile Include="..\meshcore\zlib\inffast.c" />
Expand Down Expand Up @@ -879,6 +880,7 @@ powershell -ExecutionPolicy Unrestricted $(ProjectDir)prebuild.ps1 $(ProjectDir)
<ClInclude Include="..\meshcore\meshinfo.h" />
<ClInclude Include="..\meshcore\wincrypto.h" />
<ClInclude Include="..\openframe\token_extractor.h" />
<ClInclude Include="..\openframe\machine_id_reader.h" />
<ClInclude Include="..\meshcore\zlib\deflate.h" />
<ClInclude Include="..\meshcore\zlib\gzguts.h" />
<ClInclude Include="..\meshcore\zlib\inffast.h" />
Expand Down
4 changes: 2 additions & 2 deletions microscript/ILibDuktape_Commit.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// This file is auto-generated, any edits may be overwritten
#define SOURCE_COMMIT_DATE "2026-Mar-3 13:49:57+0000"
#define SOURCE_COMMIT_HASH "26d32854a436dc65e45ee3576bf602c898444cc1"
#define SOURCE_COMMIT_DATE "2026-Mar-4 12:31:15+0000"
#define SOURCE_COMMIT_HASH "1242c456119125053a41282337d3f7d159ac4784"
38 changes: 38 additions & 0 deletions modules/RecoveryCore.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,43 @@ var nextTunnelIndex = 1;
var tunnels = {};
var fs = require('fs');

// OpenFrame: Read machine ID from shared location
var openframeMachineId = null;
function getOpenFrameMachineId() {
if (openframeMachineId != null) return openframeMachineId;
try {
var machineIdPath = (process.platform == 'win32')
? (process.env['ProgramData'] + '\\OpenFrame\\machine_id')
: ((process.platform == 'darwin')
? '/Library/Application Support/OpenFrame/machine_id'
: '/var/lib/openframe/machine_id');
openframeMachineId = fs.readFileSync(machineIdPath).toString().trim();
} catch (ex) { openframeMachineId = null; }
return openframeMachineId;
}

// OpenFrame: Add x-machine-id and Authorization headers to request options (only in openFrameMode)
function addOpenFrameHeaders(options) {
var mesh = require('MeshAgent');
if (!mesh.openFrameMode) return options;

if (!options.headers) options.headers = {};

// Add x-machine-id header
var machineId = getOpenFrameMachineId();
if (machineId) {
options.headers['x-machine-id'] = machineId;
}

// Add Authorization header with JWT token
var token = mesh.authToken();
if (token) {
options.headers['Authorization'] = 'Bearer ' + token;
}

return options;
}

//attachDebugger({ webport: 9994, wait: 1 }).then(function (p) { console.log('Debug on port: ' + p); });

function sendConsoleText(msg)
Expand Down Expand Up @@ -155,6 +192,7 @@ require('MeshAgent').AddCommandHandler(function (data)
var woptions = http.parseUri(xurl);
woptions.rejectUnauthorized = 0;
//sendConsoleText(JSON.stringify(woptions));
addOpenFrameHeaders(woptions); // Add X-MACHINE-ID header
var tunnel = http.request(woptions);
tunnel.on('upgrade', function (response, s, head)
{
Expand Down
97 changes: 97 additions & 0 deletions openframe/machine_id_reader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "machine_id_reader.h"

#define MAX_MACHINE_ID_LEN 128

#ifdef _WIN32
#include <windows.h>

char* read_machine_id() {
// Read from C:\ProgramData\OpenFrame\machine_id
char path[MAX_PATH];
char* programData = getenv("ProgramData");
if (!programData) {
return NULL;
}

snprintf(path, sizeof(path), "%s\\OpenFrame\\machine_id", programData);

FILE* file = fopen(path, "r");
if (!file) {
return NULL;
}

char* machineId = malloc(MAX_MACHINE_ID_LEN);
if (!machineId) {
fclose(file);
return NULL;
}

if (fgets(machineId, MAX_MACHINE_ID_LEN, file) == NULL) {
free(machineId);
fclose(file);
return NULL;
}

fclose(file);

// Trim newline
size_t len = strlen(machineId);
while (len > 0 && (machineId[len-1] == '\n' || machineId[len-1] == '\r')) {
machineId[--len] = '\0';
}

if (len == 0) {
free(machineId);
return NULL;
}

return machineId;
}

#else
// macOS / Linux

char* read_machine_id() {
#ifdef __APPLE__
const char* path = "/Library/Application Support/OpenFrame/machine_id";
#else
const char* path = "/var/lib/openframe/machine_id";
#endif

FILE* file = fopen(path, "r");
if (!file) {
return NULL;
}

char* machineId = malloc(MAX_MACHINE_ID_LEN);
if (!machineId) {
fclose(file);
return NULL;
}

if (fgets(machineId, MAX_MACHINE_ID_LEN, file) == NULL) {
free(machineId);
fclose(file);
return NULL;
}

fclose(file);

// Trim newline
size_t len = strlen(machineId);
while (len > 0 && (machineId[len-1] == '\n' || machineId[len-1] == '\r')) {
machineId[--len] = '\0';
}

if (len == 0) {
free(machineId);
return NULL;
}

return machineId;
}

#endif
22 changes: 22 additions & 0 deletions openframe/machine_id_reader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef MACHINE_ID_READER_H
#define MACHINE_ID_READER_H

#ifdef __cplusplus
extern "C" {
#endif

/**
* Read machine ID from shared OpenFrame location
* - macOS: /Library/Application Support/OpenFrame/machine_id
* - Windows: C:\ProgramData\OpenFrame\machine_id
* - Linux: /var/lib/openframe/machine_id
*
* @return Machine ID string (caller must free) or NULL if not found
*/
char* read_machine_id(void);

#ifdef __cplusplus
}
#endif

#endif // MACHINE_ID_READER_H
Loading