Skip to content

Commit 691875e

Browse files
committed
fix(agent): quote WMIC/netsh args for hyphens and special chars on Windows
1 parent c0da311 commit 691875e

3 files changed

Lines changed: 42 additions & 4 deletions

File tree

agent/network_config.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import sys
88
from typing import Dict, List, Optional, Tuple
99

10+
from common.wincli_escape import netsh_interface_name_arg
11+
1012

1113
def _subprocess_flags() -> int:
1214
return subprocess.CREATE_NO_WINDOW if sys.platform == "win32" else 0
@@ -338,7 +340,7 @@ def get_default_ipv4_interface_name() -> Tuple[Optional[str], str]:
338340

339341
def apply_ipv4_dhcp(interface_name: str) -> Tuple[bool, str]:
340342
flags = _subprocess_flags()
341-
name_arg = "name=%s" % interface_name
343+
name_arg = netsh_interface_name_arg(interface_name)
342344
try:
343345
p1 = subprocess.run(
344346
["netsh", "interface", "ipv4", "set", "address", name_arg, "dhcp"],
@@ -372,7 +374,7 @@ def apply_ipv4_static(
372374
dns_secondary: Optional[str],
373375
) -> Tuple[bool, str]:
374376
flags = _subprocess_flags()
375-
name_arg = "name=%s" % interface_name
377+
name_arg = netsh_interface_name_arg(interface_name)
376378
gw = gateway.strip() if gateway else ""
377379
gw_arg = gw if gw else "none"
378380
mask_n = normalize_mask(mask)

agent/rename_host.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import subprocess
77
import sys
88

9+
from common.wincli_escape import wmic_call_arg_eq, wmic_where_eq
10+
911

1012
def rename_computer(new_name: str) -> tuple[bool, str]:
1113
"""
@@ -29,15 +31,16 @@ def rename_computer(new_name: str) -> tuple[bool, str]:
2931
cur = os.environ.get("COMPUTERNAME", "")
3032
if not cur:
3133
return False, "COMPUTERNAME not set"
32-
where = "name='%s'" % cur.replace("'", "''")
34+
where = wmic_where_eq("name", cur)
35+
name_arg = wmic_call_arg_eq("name", new_name)
3336
cmd = [
3437
"wmic",
3538
"computersystem",
3639
"where",
3740
where,
3841
"call",
3942
"rename",
40-
"name=%s" % new_name,
43+
name_arg,
4144
]
4245
p = subprocess.run(
4346
cmd,

common/wincli_escape.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""Windows CLI quoting: WMIC / netsh parse tokens and treat '-' as switches unless quoted."""
2+
3+
from __future__ import annotations
4+
5+
6+
def wmic_wql_single_quote_body(s: str) -> str:
7+
"""WQL string inside single quotes: double any apostrophe."""
8+
return s.replace("'", "''")
9+
10+
11+
def wmic_where_eq(property_name: str, value: str) -> str:
12+
"""WMIC argv token for where clause, e.g. name='MY-PC' (hyphen-safe)."""
13+
prop = property_name.strip()
14+
if not prop:
15+
raise ValueError("wmic_where_eq: empty property_name")
16+
return "%s='%s'" % (prop, wmic_wql_single_quote_body(value))
17+
18+
19+
def wmic_call_arg_eq(arg_name: str, value: str) -> str:
20+
"""WMIC method argv token after 'call rename', e.g. name='Win7-1' (hyphen-safe)."""
21+
name = arg_name.strip()
22+
if not name:
23+
raise ValueError("wmic_call_arg_eq: empty arg_name")
24+
return "%s='%s'" % (name, wmic_wql_single_quote_body(value))
25+
26+
27+
def netsh_interface_name_arg(interface_name: str) -> str:
28+
"""
29+
Single argv token for netsh ipv4 commands: name="...".
30+
Spaces, hyphens, and '&' in names are safe; embedded " doubled per Windows rules.
31+
"""
32+
inner = (interface_name or "").replace('"', '""')
33+
return 'name="%s"' % inner

0 commit comments

Comments
 (0)