Changed
- An LDAP or SAML outage no longer looks like a wrong password. Every failure of the external login - a directory that could not be reached, a
jaas.confnaming a module that does not exist, an error while signing the user in - used to come back as "Login credentials are invalid", which is how LDAP login stayed broken unnoticed until 6.0.2. Now only a directory or IdP that actually rejects the credentials says so. When the directory cannot be reached, the login page says "The directory could not be reached. Please try again later or contact an administrator", the error log says why, and those attempts do not count against the client's login throttle. SAML redirects back withssoError=unavailableand shows "Single sign-on is unavailable" when its settings cannot be loaded; a malformed SAML response still counts as an invalid login. - Local accounts still sign in while the directory is down. A break-glass local account (such as a Manager kept for that purpose) keeps working during a directory outage; the outage is only reported once no local account matches.
- A database error while signing in an LDAP or SAML user is now reported as an error rather than as invalid credentials.
Security
- Controllers accept only the request parameters their forms send. Every field of every model object used to be settable by name, along with each controller's own internal state, so a form posting
user.firstNmequally accepteduser.authToken, and?errors=or?AUTH_ERROR=could put text of the requester's choosing on a page. Each controller now lists the parameters it accepts, and anything else is ignored. No exploitable case was found; this closes off the class of bug that let?publicKey=replace the key shown on the Settings page, rather than fixing a specific new one. If you have customised the web UI with extra form fields, they need adding to the controller's@Model(params = ...)list. - Disabling a key now takes it off every system. The confirmation says a disabled key "is removed from every system", but only the record clicked was disabled. Any other record of the same key - registered under another profile, for all systems, or by another user - stayed enabled and kept the key in those hosts'
authorized_keys. Disabling and enabling now apply to every record with that key's fingerprint, and every system is refreshed. - A key can no longer be registered twice in the same place. The check for "already registered under the selected profile" never matched a new key, nor any key for all systems, so the same key could be added again - and, with the problem above, survive being disabled.
- Pasted public keys must be a plain key. Anything containing
ssh-was accepted:ssh-ed25519 x, a key labelled with the wrong type, or a key withauthorized_keysoptions such ascommand="..."in front, which were stored and pushed to hosts exactly as typed. A key must now be<type> <base64 key> [comment], with the key matching its type. Keys already saved are unaffected. The same check applies to host certificate authorities.
Added
- A startup warning when LDAP cannot work. If
jaasModuleis set butjaas.confcannot be read, has no entry by that name, or names a login module that does not exist, Bastillion prints "WARNING: LDAP login will fail: …" to the console and the error log.
Fixed
- Terminal colors and color themes are saved again. Since 6.0.0, choosing them under Settings appeared to save but stored nothing, so terminals kept the default colors.
- Opening a terminal prompts for a password or key passphrase again. Since 4.0.0, connecting to a host that needed a password (the application key not yet installed) or an application key passphrase showed a bare "Failed" error instead of the prompt the terminal screen asks for. Both prompts now appear, and registering a system shows "Passphrase" rather than "Failed" when the application key's passphrase is missing or wrong.
- Two key refreshes reaching one host at once could delete its
authorized_keys. Since 6.0.0, writes stage the new file and rename it into place, but every write used the same staged name, so one could rename another's file away and then remove the original with nothing to replace it - leaving the host with noauthorized_keysat all, Bastillion's own key included, until it was fixed by hand. Disabling a key, assigning a profile and the refresh timer each start their own refresh, so this needed nothing unusual. Each write now has its own staged file, writes to the same file run one at a time, and the original is only removed once its replacement is known to exist. - The Manage Systems page showed a red "Certificate not accepted" banner on every visit since 6.0.0, without any certificate test having been run. It now appears only after one.
- The "Replace application SSH key" section of Settings opened expanded on every visit; it now starts collapsed. A missing certificate authority now shows its explanation instead of an empty key.
- Adding a user accepted any user type or authentication type. A type other than "Administrative Only" or "Full Access" gave the user no access at all while the user list showed "Full Access"; both are now validated.
- Downloading a generated private key without its name returned an error page; it now returns nothing.
- The application public key and certificate authority key on the Settings page were read from the database once, shortly after startup, so a failure at that moment left them blank until a restart. They are now read on every request.
Internal
@Model(params = {...})lists the request parameters a controller field accepts; a field without it is output only. The names are checked at startup, and a test fails the build if a template sends a parameter no controller accepts.- SSH connections are now tested end to end against an in-process SSH/SFTP server (Apache MINA SSHD, test scope only): password and key login, installing the application key over SFTP, host key trust and refusal, terminal output, certificate tests, and how each failure is reported.
- Startup (
DBInitServlet) is split into named steps, unchanged in order and output, and no longer leaks its database connection if a step fails. - Line endings are LF throughout, pinned by
.gitattributes;.git-blame-ignore-revslets blame skip the conversion commit. - OpenSSH key encoding moves from
SSHUtiltoOpenSSHKeyUtil, andauthorized_keyshandling toAuthorizedKeysUtil, unchanged. Log lines from that code now appear under those class names.
Upgrade notes:
-
Upgrade promptly if you use SAML or LDAP login; local-only installs are not affected by the login issue. No config or schema changes. A local account that was matched this way had its password cleared, so a user whose local password suddenly stopped working is worth checking.
-
If upgrading from 5.2.x: the new tables and columns are created on first start and need no action — upgrading from 5.2.x has been tested end to end. Host key verification defaults to
accept-new, so existing systems keep connecting and their keys are recorded as they are first seen; sethostKeyVerification=strictto require approval instead, oroffto keep the pre-6.0.0 behavior. The certificate authority is off untilsshCertificateAuthis set.keyManagementEnabled=true/falseis still honored and maps tomanage/append.
Upgrading from v4? v4 kept its H2 database inside the Jetty webapp, encrypted with that install's keystore, so 6.x cannot read it in place. Use the migration tool — you do not need to install 5.x first, you can import straight into 6.0.1:
# 1. export from the old v4 install (its WEB-INF/classes is the config dir)
./migrate.sh export /opt/Bastillion-jetty/jetty/bastillion/WEB-INF/classes/ ~/export.json
# 2. start 6.0.1 once against the new config dir, then stop it - creates schema + keystore
java -DCONFIG_DIR=/data/bastillion/ -jar bastillion-6.0.1.jar
# 3. import
./migrate.sh import /data/bastillion/ ~/export.json --yes-replace-all-data
# 4. the export holds plaintext secrets - delete it
rm ~/export.jsonUsers keep their existing passwords. Every column a v4 export carries still exists in the 6.0.0 schema, and the two columns 6.0.0 adds to those tables take their default or null. Full details in tools/migrate/README.md. bastillion-migrate-1.0.0.jar is attached to this release, and migrate.sh fetches it automatically, verifying its checksum.