diff --git a/SECURITY_PROCESS.md b/.github-upstream/SECURITY_PROCESS.md similarity index 100% rename from SECURITY_PROCESS.md rename to .github-upstream/SECURITY_PROCESS.md diff --git a/SECURITY_TEMPLATE.md b/.github-upstream/SECURITY_TEMPLATE.md similarity index 100% rename from SECURITY_TEMPLATE.md rename to .github-upstream/SECURITY_TEMPLATE.md diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..0c593be --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# Funding platforms shown behind the repository's Sponsor button. +# https://docs.github.com/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/displaying-a-sponsor-button-in-your-repository + +github: jcoffey-dev diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..f33796c --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,43 @@ + + +## Summary + + + +## Related issues + + + +## Upstream files + + + +## Clean room + + + +## Testing + + diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..cfacd74 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,42 @@ +version: 2 +updates: + # Cargo. One entry: the workspace has a single lockfile at the root, and + # ~30 manifests that upstream bumps on every release -- pointing entries at + # individual crates would find manifests with no lockfile beside them. + # + # Minor and patch arrive as one pull request a week. Majors are left out of + # the group on purpose: they are migrations rather than bumps, and each one + # deserves its own pull request and its own CI run. + - package-ecosystem: cargo + directory: "/" + schedule: + interval: weekly + day: tuesday + time: "09:00" + timezone: Etc/UTC + open-pull-requests-limit: 5 + groups: + minor-and-patch: + update-types: + - minor + - patch + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + day: tuesday + time: "09:00" + timezone: Etc/UTC + groups: + actions: + patterns: + - "*" + # The Dockerfiles pin their base images, so this is what keeps a published + # image off a stale base between releases. + - package-ecosystem: docker + directory: "/" + schedule: + interval: weekly + day: tuesday + time: "09:00" + timezone: Etc/UTC diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a5e105e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,51 @@ +# What CI can check without a mail server's worth of infrastructure. +# +# The build, and that every test target compiles. It deliberately does not +# *run* the test suites: the unit tests only build with the integration crate +# in the graph, because that is what switches on the `test_mode` features they +# rely on (docs/spec/SPEC.md 2.2b), and the integration suites need a `STORE`, +# fixed ports, and in most cases a container apiece (docs/spec/ +# container-tests.md). Running them here would mean either a green tick that +# skipped everything, or a red one that means "the runner has no Redis". +# +# So this catches what it can honestly catch -- code that does not compile, +# including test code -- and the suites are run by hand, one at a time, as +# that page describes. If that changes, it changes because someone made the +# suites runnable unattended, not because CI started ignoring failures. +name: CI +on: + push: + branches: [main] + pull_request: + # Lets CI be run by hand against any ref, including one that predates a CI + # change, without pushing an empty commit to move it. + workflow_dispatch: + +# A second push to a branch cancels the run still going for the first: the +# older run's answer is about code nobody is looking at any more. +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + # Every `uses:` here is pinned to a full commit SHA, with the release it + # belongs to in the trailing comment. A tag is a mutable pointer, so + # trusting `@v7` is trusting every future version of that action, + # including one pushed by whoever compromises the account. Dependabot + # updates both halves together -- do not "simplify" a pin back to a tag. + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - uses: Swatinem/rust-cache@49a0bdc70d2e1b713ca9e2869b211fcce03d3c1c # v2.9.2 + - name: System dependencies + # foundationdb and the search backends are off by default, but the + # default feature set still links against the system's C libraries. + run: sudo apt-get update && sudo apt-get install -y --no-install-recommends clang + - name: Build the server + run: cargo build -p inbuxa --locked + - name: Compile every test target + # `--no-run` is the point: it builds the unit tests and the integration + # crate together, which is the combination that resolves the test + # features, and stops short of running anything that wants a store. + run: cargo test --workspace --locked --no-run diff --git a/.gitignore b/.gitignore index e4e934e..970569e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ /target +# Release binaries built by hand: ~100 MB each, and a public repository is +# the wrong place for them. +/artifact *.failed *_failed run.sh diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..48d8417 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +**johnellisATlinuxDOTcom**. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5081afa..e2155b2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,61 +1,65 @@ # Contributing -Thank you for your interest in contributing to Stalwart. We appreciate the support and enthusiasm of the open-source community. To keep the project maintainable and the review process sustainable, contributions are subject to the policies described below. Please read them in full before opening a pull request. +Patches, bug reports and questions are welcome. -## Vouched Contributors Only +## Before a pull request -Due to the high volume of low-quality, AI-generated submissions, pull requests are limited to a list of vouched contributors. Pull requests opened by anyone who is not on this list are closed automatically. +**Open an issue first for anything substantial.** A feature or a refactor is +worth agreeing on before it is written, because this is a fork that tracks +upstream: a change that moves code around costs a conflict on every import, +and it should be worth that. -To be added as a vouched contributor, post a message at [support.stalw.art](https://support.stalw.art) explaining the code changes you would like to submit, and include a link to the proposed change (a branch, diff, or draft). Once a maintainer has reviewed your request and vouched for you, you will be able to open pull requests directly. +Small fixes — a bug, a typo, a test — need no ceremony. Send them. -This policy lets us focus limited review capacity on contributions from people who have taken the time to understand the codebase and discuss their changes first. +## What this repository is -## What Contributions Are Accepted +INBUXA is a fork of Stalwart, taken under the AGPL-3.0-only half of its dual +licence, with nine features rebuilt independently. Two things follow: -At this stage of the project we accept a narrow set of contributions: +- **The clean room is real.** The rebuilt features in `crates/features` were + written from specifications in `docs/spec/features/`, by people who had not + read Stalwart's Enterprise source. If you have read it, say so in the pull + request and it will be reviewed with that in mind, or declined for the parts + it touches. Nothing about this is personal: the project's defence of + independent creation is a record, and the record has to be true. +- **Upstream files stay recognisable.** Changes to files that came from + upstream are kept small and marked with an `inbuxa:` comment saying which + requirement they serve, so the next import merges cleanly and a reader can + tell fork from base. New work belongs in the fork's own crates where it can. -- **Bug fixes.** Corrections to existing, incorrect behavior are welcome. Please include steps to reproduce the bug and describe the fix. -- **Translations.** Additions and corrections to existing translations are welcome. +## Licence and provenance -New features are generally **not** accepted, unless they involve only a few lines of code. Larger features fall outside the scope of what we can review and integrate while the architecture is still evolving. +Contributions are under AGPL-3.0-only. Keep upstream's copyright headers where +they are; if you change a file that came from upstream, leave its "Modified by +Coffey Labs" line in place. New files carry: -If you would like to see a new feature, please request it at [support.stalw.art](https://support.stalw.art) under the **Feature Ideas** category rather than opening a pull request. This lets the community discuss and prioritize ideas before any code is written. +``` +/* + * SPDX-FileCopyrightText: 2026 Coffey Labs + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +``` -## No AI-Generated Code +If you bring in code from another project, it stays under its own licence and +its notice goes in `THIRD-PARTY.md`. `tools/fork/strip.py` reports any file +that is missing from there on every import. -AI-generated code is not accepted in this project. +## Running the tests -Even the most advanced models write inefficient Rust code. Beyond raw performance, AI creates technical debt by generating large amounts of code that not even the authors who submitted it can fully understand or maintain. Reviewing and untangling such contributions costs the maintainers far more time than it saves. +`cargo test -p tests` runs what needs nothing but a store on disk. The rest +need containers, a particular backend, or a copy of real data, and are +`#[ignore]`d: -Using AI as a fancy autocomplete is perfectly fine. What matters is that every line generated by a model is read, understood, and reviewed by a human before it is submitted. You are responsible for every line in your pull request, regardless of how it was produced. If you cannot explain why a change is written the way it is, it is not ready to be submitted. +- `docs/spec/container-tests.md` — the suites that need containers, with the + `STORE` each one wants and what a plain regression leaves failing. +- `docs/spec/compat-tests.md` — the compatibility set, which needs a copy of a + real server's data. -## Pull Request Process +Run one suite at a time. They bind fixed ports, and the timing checks flake if +two run at once. -Once you are a vouched contributor: +## Commit messages -1. Keep each pull request small and focused on a single logical change. -2. Match the style and conventions of the surrounding code. -3. Make sure the project builds and the test suite passes before opening the pull request. -4. In the pull request description, explain what the change does and why, and link to the [support.stalw.art](https://support.stalw.art) discussion where the change was vouched. - -## Code of Conduct - -We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. - -You can read the full Code of Conduct [here](https://github.com/stalwartlabs/.github/blob/main/CODE_OF_CONDUCT.md). - -## Licensing - -This project is licensed under the Affero General Public License (AGPL) version 3.0. By contributing to this project, you agree that your contributions will be licensed under the AGPL-3.0 license. - -## Fiduciary Contributor License Agreement - -Before making any contributions, all contributors are required to sign the Fiduciary Contributor License Agreement (FLA). The FLA is a legal agreement that assigns the copyright of contributions to a designated fiduciary, who manages these rights on behalf of the project. This arrangement ensures that the software remains free and open, even as contributors come and go. - -Key points of the FLA: - -- Ensures the software remains free and open source -- Protects the project from potential copyright issues -- Includes a reversion clause: if the fiduciary violates Free Software principles, rights revert to the original contributors - -For more details about the FLA, please refer to the [FLA FAQ](https://fsfe.org/activities/fla/fla.en.html). +Say what changed and why, in prose, wrapped at 72 characters or so. The why is +the part that is hard to recover later. No tool trailers. diff --git a/SECURITY.md b/SECURITY.md index 9d741d6..6d7e6c1 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,154 +1,42 @@ -# Security Policy for Stalwart +# Security policy -## Supported Versions +## Supported versions -We provide security updates for the following versions of Stalwart: +INBUXA is developed on `main`, and security fixes are applied there and in +the latest release. Older tags are not backported. -| Version | Supported | End of Support | -| ------- | ------------------ | -------------- | -| 0.16.x | :white_check_mark: | TBD | -| 0.15.x | :white_check_mark: | 2026-12-01 | -| < 0.14 | :x: | Ended | +| Version | Supported | +| --- | --- | +| `main` and the latest release | :white_check_mark: | +| Older releases | :x: | -**Note**: We typically support the current major version and one previous major version. Users are strongly encouraged to upgrade to the latest version for the best security posture. +## Reporting a vulnerability -## Reporting a Vulnerability +**Please don't open a public issue for a security problem.** An issue is +visible to everyone, including whoever would use it, before there is a fix. -We take the security of Stalwart very seriously. If you believe you've found a security vulnerability, we encourage you to inform us responsibly through coordinated disclosure. +Report it privately by email to: -### How to Report +**johnellisATlinuxDOTcom** -**Do not report security vulnerabilities through public GitHub issues, discussions, or social media.** +Include as much as you can of: -Instead, please use one of these secure channels: +- what the vulnerability is, and what it lets someone do; +- how to reproduce it, or a proof of concept; +- the version or commit affected; +- anything about the deployment that matters — backend, front ends, whether + it needs an authenticated account. -1. **Email** (preferred): Send details to `security@stalw.art` -2. **GitHub Security Advisories**: Use the "Report a vulnerability" button in the Security tab -3. **Backup contact**: If no response within 48 hours, email `hello@stalw.art` - -### What to Include - -To help us understand and address the issue quickly, please include: - -**Required Information:** -- Brief description of the vulnerability type -- Affected version(s) and components -- Steps to reproduce the issue -- Impact assessment (what could an attacker achieve?) - -**Helpful Additional Details:** -- Full paths of affected source files -- Specific commit/branch where the issue exists -- Required configuration to reproduce -- Proof-of-concept code (if available) -- Suggested mitigation or fix (if you have ideas) - -### Our Response Process - -**Timeline Commitments:** -- **Initial acknowledgment**: Within 24 hours -- **Detailed response**: Within 72 hours -- **Status updates**: Every 7 days until resolved -- **Resolution target**: 90 days for most issues - -**What We'll Do:** -1. Acknowledge your report and assign a tracking ID -2. Assess the vulnerability and determine severity -3. Develop and test a fix -4. Coordinate disclosure timeline with you -5. Release security update and publish advisory -6. Credit you in our security advisory (if desired) - -## Disclosure Policy - -We follow responsible disclosure principles: - -- **Coordinated disclosure**: We'll work with you to determine appropriate disclosure timing -- **Typical timeline**: 90 days from report to public disclosure -- **Early disclosure**: May occur if issue is being actively exploited -- **Delayed disclosure**: May be necessary for complex issues requiring significant changes +You'll get an acknowledgement within a few days. If a report turns out to +affect upstream Stalwart rather than this fork's own code, it will be passed +to Stalwart Labs with credit to you, and you'll be told that has happened. ## Scope -This security policy applies to: +This repository is the mail server. The web front ends have their own: -**In Scope:** -- Stalwart (all supported versions) -- Official Docker images -- Documentation that could lead to insecure configurations -- Dependencies with security implications - -**Out of Scope:** -- Third-party integrations or plugins -- Issues requiring physical access to the server -- Social engineering attacks -- Attacks requiring compromised credentials (unless the vulnerability enables credential compromise) -- Theoretical vulnerabilities without practical exploitation - -## Security Measures - -**Our Commitments:** -- Regular security audits of dependencies using `cargo audit` -- Automated security scanning in CI/CD pipeline -- Following Rust security best practices -- Prompt security updates for critical dependencies -- Security-focused code review process - -**User Responsibilities:** -- Keep Stalwart updated to supported versions -- Follow security configuration guidelines -- Implement proper network security (firewalls, TLS, etc.) -- Regular security monitoring and logging -- Secure credential management - -## Legal Safe Harbor - -We support security research conducted in good faith. If you follow these guidelines: - -**We will NOT:** -- Initiate legal action against you -- Contact law enforcement about your research -- Suspend or terminate your access to Stalwart services - -**You must:** -- Only test against your own Stalwart installations -- Not access, modify, or delete user data -- Not perform testing that could degrade service availability -- Not publicly disclose the issue before coordinated disclosure -- Act in good faith and not for malicious purposes - -## Recognition - -We believe in recognizing security researchers who help keep Stalwart secure: - -- **Security Advisory Credits**: We'll credit you in our GitHub Security Advisories (unless you prefer to remain anonymous) -- **Hall of Fame**: Significant contributors may be listed in our security acknowledgments -- **Swag**: We may send Stalwart merchandise for notable contributions - -## Security Updates - -**Stay Informed:** -- Subscribe to our [GitHub releases](https://github.com/stalwartlabs/stalwart/releases) for security updates -- Join our community channels for security announcements -- Enable GitHub notifications for security advisories - -**Update Process:** -- Security updates are published as patch releases (e.g., 0.12.1 → 0.12.2) -- Critical vulnerabilities may receive out-of-band releases -- Docker images are updated simultaneously with releases -- Security advisories are published through GitHub Security Advisories - -## Contact Information - -- **Security reports**: security@stalw.art -- **General inquiries**: hello@stalw.art -- **PGP Key**: Available upon request for sensitive communications - -## Additional Resources - -- [Stalwart Security Incident Response Process](SECURITY_PROCESS.md) -- [Security Configuration Guide](https://stalw.art/docs/install/security) -- [Rust Security Advisory Database](https://rustsec.org/) - -*This security policy is effective as of June 20, 2025 and may be updated periodically. Check back regularly for updates.* +- [inbuxa-admin](https://github.com/inbuxa/inbuxa-admin) +- [ihasmail-inbuxa](https://github.com/inbuxa/ihasmail-inbuxa) +Upstream's own security documents are kept in `.github-upstream/` for +reference. They describe Stalwart Labs' process, not this project's.