feat(local): check integrity for online config

This commit is contained in:
ty
2024-05-13 10:12:12 +08:00
parent 0cf4291d67
commit 562e3deb1d
3 changed files with 71 additions and 3 deletions
+58
View File
@@ -242,6 +242,10 @@ struct SSConfig {
#[cfg(feature = "local-online-config")]
#[serde(skip_serializing_if = "Option::is_none")]
online_config: Option<SSOnlineConfig>,
#[cfg(feature = "local-online-config")]
#[serde(skip_serializing_if = "Option::is_none")]
version: Option<u32>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
@@ -425,6 +429,11 @@ pub enum ConfigType {
/// Config for Manager server
Manager,
/// Config for online config (SIP008)
/// https://shadowsocks.org/doc/sip008.html
#[cfg(feature = "local-online-config")]
OnlineConfig,
}
impl ConfigType {
@@ -442,6 +451,12 @@ impl ConfigType {
pub fn is_manager(self) -> bool {
self == ConfigType::Manager
}
/// Chec if it is online config type (SIP008)
#[cfg(feature = "local-online-config")]
pub fn is_online_config(self) -> bool {
self == ConfigType::OnlineConfig
}
}
cfg_if! {
@@ -1834,6 +1849,25 @@ impl Config {
//
// This behavior causes lots of confusion. use outbound_bind_addr instead
}
#[cfg(feature = "local-online-config")]
ConfigType::OnlineConfig => {
// SIP008. https://shadowsocks.org/doc/sip008.html
// "version" should be set to "1"
match config.version {
Some(1) => {}
Some(v) => {
let err = Error::new(
ErrorKind::Invalid,
"invalid online config version",
Some(format!("version: {v}")),
);
return Err(err);
}
None => {
warn!("OnlineConfig \"version\" is missing in the configuration, assuming it is a compatible version for this project");
}
}
}
}
// Standard config
@@ -2566,6 +2600,16 @@ impl Config {
return Err(err);
}
#[cfg(feature = "local-online-config")]
if self.config_type.is_online_config() && self.server.is_empty() {
let err = Error::new(
ErrorKind::MissingField,
"missing any valid servers in configuration",
None,
);
return Err(err);
}
if self.config_type.is_manager() && self.manager.is_none() {
let err = Error::new(
ErrorKind::MissingField,
@@ -2606,6 +2650,20 @@ impl Config {
return Err(err);
}
}
#[cfg(feature = "local-online-config")]
if self.config_type.is_online_config() {
// Only server could bind to INADDR_ANY
let ip = sa.ip();
if ip.is_unspecified() {
let err = Error::new(
ErrorKind::Malformed,
"`server` shouldn't be an unspecified address (INADDR_ANY)",
None,
);
return Err(err);
}
}
}
ServerAddr::DomainName(dn, port) => {
if dn.is_empty() || *port == 0 {
+1 -1
View File
@@ -302,7 +302,7 @@ impl Default for ServerUserManager {
}
/// The source of the ServerConfig
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum ServerSource {
Default, //< Default source, created in code
Configuration, //< Created from configuration
+12 -2
View File
@@ -575,6 +575,7 @@ pub fn define_command_line_options(mut app: Command) -> Command {
/// Create `Runtime` and `main` entry
pub fn create(matches: &ArgMatches) -> Result<(Runtime, impl Future<Output = ExitCode>), ExitCode> {
#[cfg_attr(not(feature = "local-online-config"), allow(unused_mut))]
let (mut config, runtime) = {
let config_path_opt = matches.get_one::<PathBuf>("CONFIG").cloned().or_else(|| {
if !matches.contains_id("SERVER_CONFIG") {
@@ -1140,8 +1141,7 @@ async fn get_online_config_servers(
}
};
// NOTE: ConfigType::Local will force verify local_address and local_port keys. SIP008 standard doesn't include those keys.
let online_config = match Config::load_from_str(&body, ConfigType::Server) {
let online_config = match Config::load_from_str(&body, ConfigType::OnlineConfig) {
Ok(c) => c,
Err(err) => {
error!(
@@ -1152,6 +1152,14 @@ async fn get_online_config_servers(
}
};
if let Err(err) = online_config.check_integrity() {
error!(
"server-loader task failed to load from url: {}, error: {}",
online_config_url, err
);
return Err(Box::new(err));
}
Ok(online_config.server)
}
@@ -1188,6 +1196,7 @@ impl ServerReloader {
struct ConfigDisplay<'a>(&'a ServerReloader);
impl Display for ConfigDisplay<'_> {
#[cfg_attr(not(feature = "local-online-config"), allow(unused_assignments, unused_variables))]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut is_first = true;
@@ -1266,6 +1275,7 @@ impl ServerReloader {
#[cfg(unix)]
{
#[cfg_attr(not(feature = "local-online-config"), allow(unused_mut))]
let mut has_things_to_do = arc_self.config_path.is_some();
#[cfg(feature = "local-online-config")]
{