Skip to content

Commit 8c8cbdc

Browse files
committed
fix: implement atomic file writes and fix config variable names
- Implement atomic file writes for tokens.json to prevent corruption - Use mkstemp() to create temporary file in same directory - Write data to temp file, set permissions, then atomic rename - Clean up temp file on error to prevent orphaned files - Prevents data loss if process crashes during write - Fix configuration variable name mismatch - Changed ORACLE_HOST/ORACLE_PORT to CHELON_HOST/CHELON_PORT in config file - Aligns with variable names expected by server code - Prevents service misconfiguration Addresses critical security issues: - Data corruption risk from non-atomic writes - Service startup failures from config mismatches
1 parent c3cd87c commit 8c8cbdc

2 files changed

Lines changed: 39 additions & 14 deletions

File tree

config/chelon.conf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
# This file is managed by the chelon RPM package
33

44
# Server binding
5-
ORACLE_HOST=127.0.0.1
6-
ORACLE_PORT=5050
5+
CHELON_HOST=127.0.0.1
6+
CHELON_PORT=5050
77

88
# GPG home directory (where keys are stored)
99
GNUPGHOME=/var/lib/chelon/.gnupg

server/auth.py

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import pwd
1313
import grp
1414
import threading
15+
import tempfile
1516
from pathlib import Path
1617
from typing import Dict, Optional
1718
from datetime import datetime, UTC
@@ -83,23 +84,47 @@ def _load_tokens(self) -> Dict:
8384
return {}
8485

8586
def _save_tokens(self):
86-
"""Save tokens to file"""
87+
"""Save tokens to file atomically to prevent corruption"""
88+
import tempfile
89+
8790
try:
8891
self.tokens_file.parent.mkdir(parents=True, exist_ok=True)
89-
with open(self.tokens_file, 'w') as f:
90-
json.dump(self.tokens, f, indent=2)
91-
# Secure permissions
92-
self.tokens_file.chmod(0o600)
9392

94-
# If running as root, try to chown to chelon user
95-
if os.getuid() == 0:
93+
# Write to temporary file first (atomic rename requires same filesystem)
94+
fd, tmp_path = tempfile.mkstemp(
95+
dir=self.tokens_file.parent,
96+
prefix='.tokens.json.',
97+
suffix='.tmp'
98+
)
99+
100+
try:
101+
with os.fdopen(fd, 'w') as f:
102+
json.dump(self.tokens, f, indent=2)
103+
104+
# Set secure permissions before moving
105+
os.chmod(tmp_path, 0o600)
106+
107+
# If running as root, try to chown to chelon user
108+
if os.getuid() == 0:
109+
try:
110+
uid = pwd.getpwnam('chelon').pw_uid
111+
gid = grp.getgrnam('chelon').gr_gid
112+
os.chown(tmp_path, uid, gid)
113+
except KeyError:
114+
# User or group doesn't exist, ignore
115+
pass
116+
117+
# Atomic rename (POSIX guarantees atomicity)
118+
os.rename(tmp_path, self.tokens_file)
119+
120+
except Exception:
121+
# Clean up temp file on error
96122
try:
97-
uid = pwd.getpwnam('chelon').pw_uid
98-
gid = grp.getgrnam('chelon').gr_gid
99-
os.chown(self.tokens_file, uid, gid)
100-
except KeyError:
101-
# User or group doesn't exist, ignore
123+
os.unlink(tmp_path)
124+
except OSError:
102125
pass
126+
raise
127+
103128
except Exception as e:
104129
logger.error(f"Failed to save tokens: {e}")
105130

0 commit comments

Comments
 (0)