mirror of https://github.com/ospab/ostp.git
fix(migrate): backfill outbound SOCKS5 credential fields
migrate_server_json backfilled the `api` section but not the newer
outbound.username / outbound.password (added with SOCKS5 upstream auth), so a
server config predating them reported "nothing to migrate" while the fields were
absent. Now backfilled to their "" (no-auth) default.
Deliberately does NOT inject the optional bind_ip (top level) or per-rule
send_from: absent means "use the default source", which is correct and concise,
and a placeholder would be either stripped (null) or, worse, parse as an invalid
source IP (""). Those stay hand-added when the operator wants multi-address
egress. Test covers both the backfill and the no-inject.
This commit is contained in:
parent
c1b7172fc0
commit
d170b6de73
|
|
@ -353,6 +353,22 @@ pub fn migrate_server_json(json: Value) -> (Value, MigrationReport) {
|
|||
}
|
||||
}
|
||||
|
||||
// Backfill the SOCKS5 credential fields on `outbound`, added after some
|
||||
// server configs already existed. These are plain strings that default to
|
||||
// "" (no-auth), so making them explicit is safe and concise. The optional
|
||||
// `bind_ip` (top level) and per-rule `send_from` are deliberately NOT
|
||||
// backfilled: absent means "use the default source", which is correct — and
|
||||
// a placeholder would either be stripped (null) or, worse, parse as an
|
||||
// invalid source IP ("").
|
||||
if let Some(outbound) = obj.get_mut("outbound").and_then(|o| o.as_object_mut()) {
|
||||
for key in ["username", "password"] {
|
||||
if !outbound.contains_key(key) {
|
||||
report.note(format!("Added outbound.{key} = \"\" (missing default)"));
|
||||
outbound.insert(key.to_string(), json!(""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(out, report)
|
||||
}
|
||||
|
||||
|
|
@ -584,6 +600,31 @@ mod tests {
|
|||
assert!(report.notes.iter().any(|n| n.contains("api.token")));
|
||||
}
|
||||
|
||||
/// A server config whose `outbound` predates the SOCKS5 credential fields
|
||||
/// must get them backfilled — this is exactly the "migrate said nothing to
|
||||
/// migrate but the new fields were missing" gap. The optional bind_ip /
|
||||
/// send_from must NOT be injected (absent = correct).
|
||||
#[test]
|
||||
fn server_migrate_backfills_outbound_credentials() {
|
||||
let old = json!({
|
||||
"listen": "0.0.0.0:50000",
|
||||
"access_keys": ["k1"],
|
||||
"api": { "enabled": true, "bind": "0.0.0.0:9090", "webpath": "", "username": "", "password_hash": "" },
|
||||
"outbound": {
|
||||
"enabled": false, "protocol": "socks5", "address": "127.0.0.1", "port": 40000,
|
||||
"default_action": "proxy",
|
||||
"rules": [{ "action": "proxy", "domain_suffix": [".onion"] }]
|
||||
}
|
||||
});
|
||||
let (new, report) = migrate_server_json(old);
|
||||
assert!(report.changed, "adding the missing credential fields is a change");
|
||||
assert_eq!(new["outbound"]["username"], "");
|
||||
assert_eq!(new["outbound"]["password"], "");
|
||||
// Optional fields are left absent, not injected.
|
||||
assert!(new.get("bind_ip").is_none());
|
||||
assert!(new["outbound"]["rules"][0].get("send_from").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detect_kind_falls_back_to_structural_sniffing_without_mode_tag() {
|
||||
assert_eq!(detect_kind(&json!({"access_key": "x", "server": "y"})), Some(ConfigKind::Client));
|
||||
|
|
|
|||
Loading…
Reference in New Issue