daemon version check, idle mining control, bootstrap mirror, import key paste, and cleanup
- Add startup binary version checking for dragonxd/xmrig - Display daemon version in UI - Add idle mining thread count adjustment - Add bootstrap mirror option (bootstrap2.dragonx.is) in setup wizard - Add paste button to import private key dialog with address validation - Add z-address generation UI feedback (loading indicator) - Add option to delete blockchain data while preserving wallet.dat - Add font scale slider hotkey tooltip (Ctrl+Plus/Ctrl+Minus) - Fix Windows RPC auth: trim \r from config values, add .cookie fallback - Fix connection status message during block index loading - Improve application shutdown to prevent lingering background process
This commit is contained in:
@@ -118,13 +118,16 @@ ConnectionConfig Connection::parseConfFile(const std::string& path)
|
||||
std::string key = line.substr(0, eq_pos);
|
||||
std::string value = line.substr(eq_pos + 1);
|
||||
|
||||
// Trim whitespace
|
||||
while (!key.empty() && (key.back() == ' ' || key.back() == '\t')) {
|
||||
// Trim whitespace (including \r from Windows line endings)
|
||||
while (!key.empty() && (key.back() == ' ' || key.back() == '\t' || key.back() == '\r')) {
|
||||
key.pop_back();
|
||||
}
|
||||
while (!value.empty() && (value[0] == ' ' || value[0] == '\t')) {
|
||||
value.erase(0, 1);
|
||||
}
|
||||
while (!value.empty() && (value.back() == ' ' || value.back() == '\t' || value.back() == '\r')) {
|
||||
value.pop_back();
|
||||
}
|
||||
|
||||
// Map to config
|
||||
if (key == "rpcuser") {
|
||||
@@ -172,6 +175,16 @@ ConnectionConfig Connection::autoDetectConfig()
|
||||
}
|
||||
}
|
||||
|
||||
// If rpcpassword is empty, the daemon may be using .cookie auth
|
||||
if (config.rpcpassword.empty()) {
|
||||
std::string cookieUser, cookiePass;
|
||||
if (readAuthCookie(data_dir, cookieUser, cookiePass)) {
|
||||
config.rpcuser = cookieUser;
|
||||
config.rpcpassword = cookiePass;
|
||||
DEBUG_LOGF("Using .cookie authentication (no rpcpassword in config)\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Set defaults for missing values
|
||||
if (config.host.empty()) {
|
||||
config.host = DRAGONX_DEFAULT_RPC_HOST;
|
||||
@@ -319,5 +332,40 @@ bool Connection::ensureEncryptionEnabled(const std::string& confPath)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Connection::readAuthCookie(const std::string& dataDir, std::string& user, std::string& password)
|
||||
{
|
||||
if (dataDir.empty()) return false;
|
||||
|
||||
#ifdef _WIN32
|
||||
std::string cookiePath = dataDir + "\\.cookie";
|
||||
#else
|
||||
std::string cookiePath = dataDir + "/.cookie";
|
||||
#endif
|
||||
|
||||
std::ifstream file(cookiePath);
|
||||
if (!file.is_open()) return false;
|
||||
|
||||
std::string cookie;
|
||||
std::getline(file, cookie);
|
||||
file.close();
|
||||
|
||||
// Cookie format: __cookie__:base64encodedpassword
|
||||
size_t colonPos = cookie.find(':');
|
||||
if (colonPos == std::string::npos || colonPos == 0) return false;
|
||||
|
||||
user = cookie.substr(0, colonPos);
|
||||
password = cookie.substr(colonPos + 1);
|
||||
|
||||
// Trim \r if present (Windows line endings)
|
||||
while (!password.empty() && (password.back() == '\r' || password.back() == '\n')) {
|
||||
password.pop_back();
|
||||
}
|
||||
|
||||
if (user.empty() || password.empty()) return false;
|
||||
|
||||
DEBUG_LOGF("Read auth cookie from: %s (user=%s)\n", cookiePath.c_str(), user.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace dragonx
|
||||
|
||||
Reference in New Issue
Block a user