Highly Performant & Scalable Ultima Online Server Emulator https://www.modernuo.com
Find a file
Kamron Batman b2c59191bd
fix: Fixes Argon2 verify correctness and the password upgrade lockout (#2562)
> ⚠️ **Rollback hazard — one-way door once logins are taken.** Serialization is unchanged, so a save
> written by this build still *loads* on the previous one. Its contents do not survive the trip: on
> its first successful login each account is rehashed to `$argon2id$`, and the previous build ships
> Argon2.Bindings 1.19.0, whose `Verify` is gated by the verifier's own configured type and answers
> `false` for an `$argon2id$` hash. **After a shard running this build has accepted logins, do not
> roll back past this commit** — every account that logged in is locked out on the older binary, and
> the only recovery is rolling forward again or resetting passwords by hand. Roll back only from a
> save taken before the first post-deploy login.

Requires [Argon2.Bindings 1.20.0](https://github.com/modernuo/Argon2.Bindings/pull/14), now published.

## What

- Consume `Argon2.Bindings` 1.20.0, which resolves the Argon2 type from the stored PHC string rather than from the verifier's own configuration.
- Default to **Argon2id, m=16384, t=1, p=1** — 8.51 ms against the old Argon2i 8 MiB t=3 at 10.11 ms. Cheaper *and* stronger.
- Rehash on a successful login whenever the stored parameters are stale, not only when the algorithm changes.
- Fix `SetPassword`, which derived the password phrase from the outgoing algorithm while storing it under the incoming one.

## Why

**Verification was gated by the verifier's configured type.** `Verify` passed the instance's own `ArgonType` to native `argon2_verify`, whose `decode_string` rejects a disagreeing `$argon2i$`/`$argon2id$` prefix and returns `DECODING_FAIL` — folded into `false`, the same answer as a wrong password. Switching the default type would have locked out every existing account, and `VerifyAndUpdate` could not have migrated them either: it delegates to the same type-fixed `Verify` and never compared `ArgonType`. Fixed upstream in 1.20.0. The pinned legacy-`$argon2i$` test here fails on 1.19.0 for exactly that reason, which is what makes the package bump load-bearing rather than incidental.

**Changing the defaults would otherwise have reached nobody.** Argon2's PHC string embeds `m`, `t` and `p`, so verification uses the parameters stored with each account, not the configured ones — and verification is the hot path. `CheckPassword` only rehashed when the *algorithm* changed, never when its cost parameters did, so on an established shard the new defaults would have applied to new accounts only. `IPasswordProtection.NeedsRehash` closes that: it defaults to `false`, so PBKDF2 and the `HashAlgorithm` protections are untouched — only Argon2 carries its cost inside the stored value.

**`SetPassword` picked the phrase rule from the wrong algorithm.** SHA1 and SHA2 salt the phrase with the username; Argon2 and PBKDF2 do not. It chose the rule from the *outgoing* algorithm while storing under the *incoming* one, so any algorithm change wrote a credential its own next verify could not reproduce. It now assigns `PasswordAlgorithm` first and derives the phrase from that. Note this ordering is load-bearing and invisible — `UpgradingAlgorithm_DoesNotLockTheAccountOut` is what pins it.

## Cost

Verification is re-derivation, so these are login numbers. A full login calls `CheckPassword` twice — `AccountLogin` (0x80) then `GameLogin` (0x91): **~20 ms before, ~17 ms after**, plus a one-time ~8.5 ms rehash on each account's migrating login.

That cost is still paid on the game loop. Moving hashing off-loop is deliberately **not** in this PR — it needs a pending-auth state in the login handlers, bounding of in-flight hashes, and login rate limiting.
2026-08-08 00:24:59 -07:00
.config feat: Adds Build Tool for Publishing/Setup (#2392) 2026-03-28 21:21:50 -07:00
.github fix: Require only runtime packages on Linux, and check ICU and tzdata the way the runtime does (#2561) 2026-08-07 15:03:08 -07:00
branding feat(build-tool): add application icon and refresh MUO.ico (#2487) 2026-06-14 11:59:54 -07:00
dev-docs fix: Fixes Argon2 verify correctness and the password upgrade lockout (#2562) 2026-08-08 00:24:59 -07:00
Distribution/Data fix(throwing): grant Str/Dex stat gains for the Throwing skill (#2514) 2026-07-02 23:07:36 -07:00
Projects fix: Fixes Argon2 verify correctness and the password upgrade lockout (#2562) 2026-08-08 00:24:59 -07:00
tools feat(network): allowlist false-positive IPs, escalate on behavior (#2556) 2026-07-30 23:12:17 -07:00
.cursorrules chore: Adds AI instructions and SKILLs for ModernUO codebase (#2347) 2026-03-01 11:42:19 -08:00
.editorconfig chore(docs): Adds UnmanagedDataReader & BinaryFileReader documentation (#1968) 2024-10-01 17:07:51 -07:00
.gitattributes fix: Adds migration checks to CICD, updates dependencies, adds Fedora 37, alpine 3.17 support (#1309) 2022-12-22 12:12:47 -08:00
.gitignore feat(network): allowlist false-positive IPs, escalate on behavior (#2556) 2026-07-30 23:12:17 -07:00
AGENTS.md chore: Adds AI instructions and SKILLs for ModernUO codebase (#2347) 2026-03-01 11:42:19 -08:00
azure-pipelines.yml chore: Cleans workflows for NodeJS 24 (#2394) 2026-03-28 21:55:29 -07:00
CLAUDE.md fix: Require only runtime packages on Linux, and check ICU and tzdata the way the runtime does (#2561) 2026-08-07 15:03:08 -07:00
CODE_OF_CONDUCT.md Create CODE_OF_CONDUCT.md 2020-05-05 08:51:39 -07:00
CONTRIBUTING.md chore(license): Removes CLA requirement. All contributors moving forward will retain copyright. (#2038) 2024-12-31 02:52:58 -08:00
Directory.Build.props fix: Bumps dependencies. (#2531) 2026-07-14 15:17:55 -07:00
FAQ.md docs: Updates FAQ for time zone issues. (#1368) 2023-03-10 00:18:36 -08:00
GEMINI.md chore: Adds AI instructions and SKILLs for ModernUO codebase (#2347) 2026-03-01 11:42:19 -08:00
global.json feat: Adds Build Tool for Publishing/Setup (#2392) 2026-03-28 21:21:50 -07:00
LICENSE Fixes more line ending issues (#267) 2020-09-27 13:54:56 -07:00
ModernUO.slnx feat: Adds Build Tool for Publishing/Setup (#2392) 2026-03-28 21:21:50 -07:00
publish.cmd feat: Adds Build Tool for Publishing/Setup (#2392) 2026-03-28 21:21:50 -07:00
publish.ps1 fix: Adds stamp check for build tool versioning (#2400) 2026-04-06 16:18:02 -06:00
publish.sh fix: Adds stamp check for build tool versioning (#2400) 2026-04-06 16:18:02 -06:00
README.md fix: Require only runtime packages on Linux, and check ICU and tzdata the way the runtime does (#2561) 2026-08-07 15:03:08 -07:00
rider-settings.zip Cleanup/Housekeeping (#242) 2020-09-12 15:31:21 -07:00
Rules.ruleset chore(docs): Adds UnmanagedDataReader & BinaryFileReader documentation (#1968) 2024-10-01 17:07:51 -07:00
SPONSORS.md chore: Updates readme files (#2247) 2025-07-27 11:04:32 -07:00
stylecop.json Updates formatting rules (#199) 2020-08-25 18:00:51 -07:00
THIRD-PARTY-NOTICES docs: Adds RunUO-Encryption notice attribution to DarkStorm (#2369) 2026-03-12 23:35:47 -07:00
version.json feat: Adds Build Tool for Publishing/Setup (#2392) 2026-03-28 21:21:50 -07:00

ModernUO - Ultima Online Server Emulator for the modern era!

ModernUO Discord Subreddit subscribers Twitter Follow

Ultima Online Server Emulator for the modern era!

GitHub license GitHub stars GitHub issues
GitHub build Azure Pipelines build

Requirements

Supported Operating Systems

Windows 10/11/2012/2016/2019/2022/2025 MacOS 14+ Debian 12+ Ubuntu 22+ LTS
Alpine 3.22+ Fedora 42+ RedHat 9+ CentOS Stream 9+ AlmaLinux 10 openSUSE 15.6+ SUSE Enterprise 15 SP6 Linux Mint 21+ Arch

Required Frameworks

All Operating Systems

.NET

Windows

VC++ Redistributable v14

Development

git .NET

Supported IDEs

Jetbrains Rider 2025.3+ space VSCode space Visual Studio 2026

Getting Started

  • Install prerequisite requirements
  • Clone this repository (or download the latest):
    • git clone https://github.com/modernuo/ModernUO.git
  • Open ModernUO.sln to start developing

Building/Publishing

Run ./publish.cmd (Windows) or ./publish.sh (Linux/macOS) with no arguments to launch the guided build tool. It will:

  • Check prerequisites (.NET SDK, native libraries)
  • Walk you through configuration and platform selection
  • Build and publish the server to the Distribution directory
  • Show deployment instructions for cross-compiled builds

Command Line

./publish.cmd [release|debug] [os] [arch]

Linux Prerequisites

Fedora, CentOS, RHEL, AlmaLinux, Rocky, etc

dnf upgrade --refresh -y
# RHEL-family distributions (CentOS Stream, AlmaLinux, Rocky, RHEL) need CRB and EPEL enabled.
# Fedora skips this block.
dnf install -y dnf-plugins-core
dnf config-manager --set-enabled crb
dnf install -y epel-release
# Prerequisites
dnf install -y findutils libicu libdeflate libargon2 tzdata

Ubuntu, Debian, etc

apt-get update -y
# The ICU runtime package carries the ABI version in its name (libicu74, libicu76, …) and has no
# stable alias, so match it by pattern rather than pinning a release-specific name.
apt-get install -y '^libicu[0-9]+$' libdeflate0 libargon2-1 tzdata

Only the runtime libraries are needed — the -dev/-devel packages are not. Run ./build-tool --check-prereqs to check the current machine and print the exact packages your release needs.

zstd is not listed because ZstdNet bundles libzstd for every platform, and liburing is not listed because IORingGroup issues io_uring syscalls directly.

If the shard's configured time zone is a legacy alias such as US/Eastern, Debian 12 and Ubuntu 24.04 also need tzdata-legacy. See Platform Prerequisites for what each dependency is for and what breaks without it.

OSX Requirements

brew install icu4c libdeflate argon2

Running the Server

  • Follow the publish instructions
  • The Distribution directory is portable — copy it to your production server for deployment
  • Run ModernUO.exe or dotnet ModernUO.dll from the Distribution directory
  • On first run, the server will prompt you to configure game data file locations

Troubleshooting / FAQ

Want to sponsor?

Thank you for supporting us! You can find out how by visiting the sponsors page.

Collaborators

Kamron Batman Mark1145

Thanks

  • RunUO Team & Community
  • Voxpire, the ServUO Team & Community
  • Karasho, Jaedan and the ClassicUO Community



Development Tools & Plugins provided with ♥ by

JetBrains
Material Theme

Code Signing Policy

Free code signing provided by SignPath.io, certificate by SignPath Foundation.

This program will not transfer any information to other networked systems unless specifically requested by the user or the person installing or operating it

Teams & Roles

Approvers & Committers: Development Team