Hide the current server version (closes #1435)

This commit is contained in:
mdecimus 2025-04-27 11:23:07 +02:00
parent ee7c953279
commit e10e94325f
12 changed files with 97 additions and 59 deletions

View file

@ -11,9 +11,12 @@ use sieve::{Compiler, Runtime, Sieve, compiler::grammar::Capability};
use store::Stores;
use utils::config::Config;
use crate::scripts::{
functions::{register_functions_trusted, register_functions_untrusted},
plugins::RegisterSievePlugins,
use crate::{
VERSION_PUBLIC,
scripts::{
functions::{register_functions_trusted, register_functions_untrusted},
plugins::RegisterSievePlugins,
},
};
use super::{if_block::IfBlock, smtp::SMTP_RCPT_TO_VARS, tokenizer::TokenMap};
@ -182,8 +185,8 @@ impl Scripting {
.unwrap_or("Auto: ")
.to_string(),
)
.with_env_variable("name", "Stalwart Mail Server")
.with_env_variable("version", env!("CARGO_PKG_VERSION"))
.with_env_variable("name", "Stalwart Server")
.with_env_variable("version", VERSION_PUBLIC)
.with_env_variable("location", "MS")
.with_env_variable("phase", "during");

View file

@ -71,8 +71,12 @@ pub mod telemetry;
pub use psl;
pub static USER_AGENT: &str = concat!("Stalwart/", env!("CARGO_PKG_VERSION"),);
pub static DAEMON_NAME: &str = concat!("Stalwart Mail Server v", env!("CARGO_PKG_VERSION"),);
pub static VERSION_PRIVATE: &str = env!("CARGO_PKG_VERSION");
pub static VERSION_PUBLIC: &str = "1.0.0";
pub static USER_AGENT: &str = "Stalwart/1.0.0";
pub static DAEMON_NAME: &str = concat!("Stalwart v", env!("CARGO_PKG_VERSION"),);
pub static PROD_ID: &str = "-//Stalwart Labs Ltd.//Stalwart Server//EN";
pub const LONG_1D_SLUMBER: Duration = Duration::from_secs(60 * 60 * 24);
pub const LONG_1Y_SLUMBER: Duration = Duration::from_secs(60 * 60 * 24 * 365);
@ -253,9 +257,22 @@ pub struct DavResource {
pub document_id: u32,
pub parent_id: Option<u32>,
pub name: String,
pub size: u32,
pub hierarchy_sequence: u32,
pub is_container: bool,
pub data: DavResourceMetadata,
}
#[derive(Debug, Default)]
pub enum DavResourceMetadata {
File {
size: u32,
hierarchy_sequence: u32,
is_container: bool,
},
Calendar {
start: i64,
duration: u32,
},
#[default]
None,
}
#[derive(Clone, Default)]
@ -506,7 +523,7 @@ impl DavResources {
}
pub fn format_resource(&self, resource: &DavResource) -> String {
if resource.is_container {
if resource.is_container() {
format!("{}{}/", self.base_path, resource.name)
} else {
format!("{}{}", self.base_path, resource.name)
@ -522,6 +539,46 @@ impl DavResources {
}
}
impl DavResource {
pub fn event_time_range(&self) -> Option<(i64, i64)> {
match &self.data {
DavResourceMetadata::Calendar { start, duration } => {
Some((*start, *start + *duration as i64))
}
_ => None,
}
}
pub fn is_container(&self) -> bool {
match &self.data {
DavResourceMetadata::File { is_container, .. } => *is_container,
_ => self.parent_id.is_none(),
}
}
pub fn size(&self) -> u32 {
match &self.data {
DavResourceMetadata::File { size, .. } => *size,
_ => 0,
}
}
pub fn hierarchy_sequence(&self) -> u32 {
match &self.data {
DavResourceMetadata::File {
hierarchy_sequence, ..
} => *hierarchy_sequence,
_ => {
if self.parent_id.is_none() {
0
} else {
1
}
}
}
}
}
impl IdBimapItem for DavResource {
fn id(&self) -> &u32 {
&self.document_id

View file

@ -52,7 +52,7 @@ pub struct IpcReceivers {
}
const HELP: &str = concat!(
"Stalwart Mail Server v",
"Stalwart Server v",
env!("CARGO_PKG_VERSION"),
r#"

View file

@ -16,7 +16,7 @@ use store::{
};
const HELP: &str = concat!(
"Stalwart Mail Server v",
"Stalwart Server v",
env!("CARGO_PKG_VERSION"),
r#" Data Store CLI

View file

@ -17,9 +17,10 @@ impl Server {
access_token: &AccessToken,
to_account_id: u32,
to_collection: Collection,
check_acls: impl Into<Bitmap<Acl>>,
check_acls: impl IntoIterator<Item = Acl>,
match_any: bool,
) -> trc::Result<RoaringBitmap> {
let check_acls = check_acls.into();
let check_acls = Bitmap::<Acl>::from_iter(check_acls);
let mut document_ids = RoaringBitmap::new();
let to_collection = u8::from(to_collection);
for &grant_account_id in [access_token.primary_id]
@ -39,9 +40,8 @@ impl Server {
.caused_by(trc::location!())?
{
let mut acls = Bitmap::<Acl>::from(acl_item.permissions);
acls.intersection(&check_acls);
if !acls.is_empty() {
if acls == check_acls || (match_any && !acls.is_empty()) {
document_ids.insert(acl_item.to_document_id);
}
}
@ -50,26 +50,6 @@ impl Server {
Ok(document_ids)
}
pub async fn owned_or_shared_containers(
&self,
access_token: &AccessToken,
account_id: u32,
collection: Collection,
check_acls: impl Into<Bitmap<Acl>>,
) -> trc::Result<RoaringBitmap> {
let check_acls = check_acls.into();
let mut document_ids = self
.get_document_ids(account_id, collection)
.await?
.unwrap_or_default();
if !document_ids.is_empty() && !access_token.is_member(account_id) {
document_ids &= self
.shared_containers(access_token, account_id, collection, check_acls)
.await?;
}
Ok(document_ids)
}
pub async fn has_access_to_document(
&self,
access_token: &AccessToken,

View file

@ -130,6 +130,12 @@ impl From<u64> for IndexItem<'_> {
}
}
impl From<i64> for IndexItem<'_> {
fn from(value: i64) -> Self {
IndexItem::LongInt(value.to_be_bytes())
}
}
impl<'x> From<&'x [u8]> for IndexItem<'x> {
fn from(value: &'x [u8]) -> Self {
IndexItem::Slice(value)

View file

@ -64,9 +64,7 @@ impl<T: SessionStream> Session<T> {
.with_tag(request.tag)
.serialize(
concat!(
"* ID (\"name\" \"Stalwart IMAP\" \"version\" \"",
env!("CARGO_PKG_VERSION"),
"\" \"vendor\" \"Stalwart Labs Ltd.\" ",
"* ID (\"name\" \"Stalwart\" \"version\" \"1.0.0\" \"vendor\" \"Stalwart Labs Ltd.\" ",
"\"support-url\" \"https://stalw.art\")\r\n"
)
.as_bytes()

View file

@ -14,15 +14,8 @@ impl<T: SessionStream> Session<T> {
pub async fn handle_logout(&mut self, request: Request<Command>) -> trc::Result<()> {
let op_start = Instant::now();
let mut response = StatusResponse::bye(
concat!(
"Stalwart IMAP4rev2 v",
env!("CARGO_PKG_VERSION"),
" bids you farewell."
)
.to_string(),
)
.into_bytes();
let mut response =
StatusResponse::bye("Stalwart IMAP4rev2 bids you farewell.".to_string()).into_bytes();
trc::event!(
Imap(trc::ImapEvent::Logout),

View file

@ -300,7 +300,7 @@ impl Account {
impl Default for SieveSessionCapabilities {
fn default() -> Self {
Self {
implementation: concat!("Stalwart JMAP v", env!("CARGO_PKG_VERSION"),),
implementation: "Stalwart v1.0.0",
}
}
}

View file

@ -48,7 +48,13 @@ impl SessionHandler for Server {
let is_personal = !access_token.is_member(*id);
let is_readonly = is_personal
&& self
.shared_containers(&access_token, *id, Collection::Mailbox, Acl::AddItems)
.shared_containers(
&access_token,
*id,
Collection::Mailbox,
[Acl::AddItems],
false,
)
.await
.caused_by(trc::location!())?
.is_empty();

View file

@ -16,11 +16,6 @@ impl<T: AsyncRead + AsyncWrite> Session<T> {
Elapsed = trc::Value::Duration(0)
);
Ok(StatusResponse::ok(concat!(
"Stalwart ManageSieve v",
env!("CARGO_PKG_VERSION"),
" bids you farewell."
))
.into_bytes())
Ok(StatusResponse::ok("Stalwart ManageSieve bids you farewell.").into_bytes())
}
}

View file

@ -114,7 +114,7 @@ impl<T: Display> Response<T> {
"EXPIRE NEVER",
"UIDL",
"UTF8",
"IMPLEMENTATION Stalwart Mail Server",
"IMPLEMENTATION Stalwart Server",
] {
buf.extend_from_slice(capa.as_bytes());
buf.extend_from_slice(b"\r\n");
@ -201,7 +201,7 @@ mod tests {
"EXPIRE NEVER\r\n",
"UIDL\r\n",
"UTF8\r\n",
"IMPLEMENTATION Stalwart Mail Server\r\n.\r\n"
"IMPLEMENTATION Stalwart Server\r\n.\r\n"
),
),
(