feat: add share_key for Samba password, sync smbpasswd on startup
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
11
bin/clawd.js
11
bin/clawd.js
@@ -7,6 +7,7 @@ require('../lib/systemd-env');
|
||||
const path = require('path');
|
||||
const { exec } = require('child_process');
|
||||
const { ClawClient } = require('../lib/client');
|
||||
const config = require('../lib/config');
|
||||
const log = require('../lib/logger');
|
||||
const { pollSms } = require('../drivers/sim/sms-reader');
|
||||
|
||||
@@ -17,6 +18,16 @@ exec(`bash "${bindScript}"`, (err, stdout, stderr) => {
|
||||
else log.info('clawd', `bind-quectel-serial: ok`);
|
||||
});
|
||||
|
||||
// 同步 Samba 共享密码(idempotent,失败不影响主流程)
|
||||
const cfg = config.load();
|
||||
if (cfg.share_key) {
|
||||
const shareKey = cfg.share_key.replace(/'/g, "'\\''");
|
||||
exec(`printf '%s\\n%s\\n' '${shareKey}' '${shareKey}' | smbpasswd -a sts -s 2>/dev/null`, (err) => {
|
||||
if (err) log.warn('clawd', `smbpasswd sync failed (samba not installed?): ${err.message}`);
|
||||
else log.info('clawd', 'smbpasswd synced for user sts');
|
||||
});
|
||||
}
|
||||
|
||||
let smsTimer = null;
|
||||
let smsPolling = false;
|
||||
|
||||
|
||||
@@ -377,6 +377,7 @@ class ClawClient {
|
||||
token: this._cfg.token ?? null,
|
||||
version: CLAWD_VERSION,
|
||||
ssh_secret_key: this._cfg.ssh_secret_key ?? null,
|
||||
share_key: this._cfg.share_key ?? null,
|
||||
headscale_joined: headscale.isInstalled() && headscale.isJoined(this._cfg.headscale_server || 'https://hs.claw.cutos.ai'),
|
||||
local_ip: getLocalIps(),
|
||||
local_networks: getLocalNetworks(),
|
||||
|
||||
@@ -20,6 +20,7 @@ const DEFAULTS = {
|
||||
/** 云端已激活:用于启动/重连时立即点亮 alarm(pwr),不等首包 connected */
|
||||
activated: false,
|
||||
ssh_secret_key: null,
|
||||
share_key: null,
|
||||
headscale_server: 'https://hs.claw.cutos.ai',
|
||||
};
|
||||
|
||||
@@ -28,6 +29,33 @@ function _generateSshSecretKey() {
|
||||
return 'sk-' + bytes.toString('hex');
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成可读性好的 Samba 共享密码,格式:xxxxxx-xxxxxx-xxxxXX(三段各6字符,连字符分隔)。
|
||||
* 最后一段包含至少1个大写字母和1个数字,其余为小写字母。
|
||||
* 示例:juqhuf-hykgyh-mykGi3
|
||||
*/
|
||||
function _generateShareKey() {
|
||||
const crypto = require('crypto');
|
||||
const lower = 'abcdefghijklmnopqrstuvwxyz';
|
||||
const upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
const digits = '0123456789';
|
||||
|
||||
function rndChars(chars, n) {
|
||||
const bytes = crypto.randomBytes(n);
|
||||
return Array.from(bytes).map(b => chars[b % chars.length]).join('');
|
||||
}
|
||||
|
||||
const g1 = rndChars(lower, 6);
|
||||
const g2 = rndChars(lower, 6);
|
||||
// 第三段:4个小写 + 1个大写 + 1个数字,随机打乱顺序
|
||||
const g3raw = (rndChars(lower, 4) + rndChars(upper, 1) + rndChars(digits, 1)).split('');
|
||||
for (let i = g3raw.length - 1; i > 0; i--) {
|
||||
const j = crypto.randomBytes(1)[0] % (i + 1);
|
||||
[g3raw[i], g3raw[j]] = [g3raw[j], g3raw[i]];
|
||||
}
|
||||
return `${g1}-${g2}-${g3raw.join('')}`;
|
||||
}
|
||||
|
||||
function load() {
|
||||
let cfg;
|
||||
try {
|
||||
@@ -41,10 +69,16 @@ function load() {
|
||||
}
|
||||
if (!cfg) cfg = Object.assign({}, DEFAULTS);
|
||||
|
||||
let dirty = false;
|
||||
if (!cfg.ssh_secret_key) {
|
||||
cfg.ssh_secret_key = _generateSshSecretKey();
|
||||
save(cfg);
|
||||
dirty = true;
|
||||
}
|
||||
if (!cfg.share_key) {
|
||||
cfg.share_key = _generateShareKey();
|
||||
dirty = true;
|
||||
}
|
||||
if (dirty) save(cfg);
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user