jojo/models/asymkey/ssh_key_authorized_keys.go

311 lines
9.3 KiB
Go
Raw Normal View History

Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
package asymkey
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
import (
"bufio"
"context"
feat: ensure only expected ssh public keys are in authorized_keys file (#10010) A security vulnerability that was fixed in #9840 had the potential to corrupt the `authorized_keys` file that Forgejo is managing to allow ssh access. In the event that it was corrupted, the existing behaviour of Forgejo is to maintain the contents that it finds in the `authorized_keys` file, potentially making an exploit of a Forgejo server persistent despite attempts to rewrite the key file. This feature adds a new layer of security resiliency in order to prevent persistent ssh key corruption. When Forgejo starts up, if relevant, Forgejo will read the `authorized_keys` file and validate the file's contents. If any keys are found in the file that are not expected, then Forgejo will terminate its startup in order to signal to the server administrator that a critical security risk is present that must be addressed: ``` 2025/11/07 10:13:50 modules/ssh/init.go:86:Init() [F] An unexpected ssh public key was discovered. Forgejo will shutdown to require this to be fixed. Fix by either: Option 1: Delete the file /home/forgejo/.ssh/authorized_keys, and Forgejo will recreate it with only expected ssh public keys. Option 2: Permit unexpected keys by setting [server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=true in Forgejo's config file. Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 2 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 3 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 4 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 5 of /home/forgejo/.ssh/authorized_keys ``` As noted in the log message, the server administrator can address this problem in one of two ways: - If they delete the file that contains the unexpected keys, Forgejo will regenerate it containing only the expected keys from the Forgejo database. - If they would like to run their server with ssh keys that are not managed by Forgejo (for example, if they're reusing a `git` ssh user that is accessed through `git@server` and does not invoke Forgejo's ssh handlers), then they can disable the new security check by setting `[server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS = true` in their `app.ini`. **This is a breaking change**: the default behaviour is to be restrictive in the contents of `authorized_keys` in order to ensure that server administrators with unexpected keys in `authorized_keys` are aware of those keys. If `SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=false`, then the behaviour when Forgejo rewrites the `authorized_keys` file is changed to not maintain any unexpected keys in the file. If the value is `true`, then the old behaviour is retained. The `doctor check` subcommand is updated to use the new validity routines: ``` [4] Check if OpenSSH authorized_keys file is up-to-date - [E] Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys - [E] Key in database is not present in /home/forgejo/.ssh/authorized_keys: ... - [E] authorized_keys file "/home/forgejo/.ssh/authorized_keys" contains validity errors. Regenerate it with: "forgejo admin regenerate keys" or "forgejo doctor check --run authorized-keys --fix" ERROR ``` ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [x] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - **Documentation updates required**; pending initial reviews of this change. - [ ] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [ ] I want the title to show in the release notes with a link to this pull request. - [x] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10010 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: mfenniak <mfenniak@noreply.codeberg.org> Co-committed-by: mfenniak <mfenniak@noreply.codeberg.org>
2025-11-09 01:06:04 +01:00
"errors"
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
"fmt"
"io"
"os"
"path/filepath"
"strings"
"sync"
"time"
"forgejo.org/models/db"
feat: ensure only expected ssh public keys are in authorized_keys file (#10010) A security vulnerability that was fixed in #9840 had the potential to corrupt the `authorized_keys` file that Forgejo is managing to allow ssh access. In the event that it was corrupted, the existing behaviour of Forgejo is to maintain the contents that it finds in the `authorized_keys` file, potentially making an exploit of a Forgejo server persistent despite attempts to rewrite the key file. This feature adds a new layer of security resiliency in order to prevent persistent ssh key corruption. When Forgejo starts up, if relevant, Forgejo will read the `authorized_keys` file and validate the file's contents. If any keys are found in the file that are not expected, then Forgejo will terminate its startup in order to signal to the server administrator that a critical security risk is present that must be addressed: ``` 2025/11/07 10:13:50 modules/ssh/init.go:86:Init() [F] An unexpected ssh public key was discovered. Forgejo will shutdown to require this to be fixed. Fix by either: Option 1: Delete the file /home/forgejo/.ssh/authorized_keys, and Forgejo will recreate it with only expected ssh public keys. Option 2: Permit unexpected keys by setting [server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=true in Forgejo's config file. Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 2 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 3 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 4 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 5 of /home/forgejo/.ssh/authorized_keys ``` As noted in the log message, the server administrator can address this problem in one of two ways: - If they delete the file that contains the unexpected keys, Forgejo will regenerate it containing only the expected keys from the Forgejo database. - If they would like to run their server with ssh keys that are not managed by Forgejo (for example, if they're reusing a `git` ssh user that is accessed through `git@server` and does not invoke Forgejo's ssh handlers), then they can disable the new security check by setting `[server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS = true` in their `app.ini`. **This is a breaking change**: the default behaviour is to be restrictive in the contents of `authorized_keys` in order to ensure that server administrators with unexpected keys in `authorized_keys` are aware of those keys. If `SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=false`, then the behaviour when Forgejo rewrites the `authorized_keys` file is changed to not maintain any unexpected keys in the file. If the value is `true`, then the old behaviour is retained. The `doctor check` subcommand is updated to use the new validity routines: ``` [4] Check if OpenSSH authorized_keys file is up-to-date - [E] Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys - [E] Key in database is not present in /home/forgejo/.ssh/authorized_keys: ... - [E] authorized_keys file "/home/forgejo/.ssh/authorized_keys" contains validity errors. Regenerate it with: "forgejo admin regenerate keys" or "forgejo doctor check --run authorized-keys --fix" ERROR ``` ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [x] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - **Documentation updates required**; pending initial reviews of this change. - [ ] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [ ] I want the title to show in the release notes with a link to this pull request. - [x] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10010 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: mfenniak <mfenniak@noreply.codeberg.org> Co-committed-by: mfenniak <mfenniak@noreply.codeberg.org>
2025-11-09 01:06:04 +01:00
"forgejo.org/modules/container"
"forgejo.org/modules/log"
"forgejo.org/modules/setting"
"forgejo.org/modules/util"
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
)
// _____ __ .__ .__ .___
// / _ \ __ ___/ |_| |__ ___________|__|_______ ____ __| _/
// / /_\ \| | \ __\ | \ / _ \_ __ \ \___ // __ \ / __ |
// / | \ | /| | | Y ( <_> ) | \/ |/ /\ ___// /_/ |
// \____|__ /____/ |__| |___| /\____/|__| |__/_____ \\___ >____ |
// \/ \/ \/ \/ \/
// ____ __.
// | |/ _|____ ___.__. ______
// | <_/ __ < | |/ ___/
// | | \ ___/\___ |\___ \
// |____|__ \___ > ____/____ >
// \/ \/\/ \/
//
// This file contains functions for creating authorized_keys files
//
// There is a dependence on the database within RegeneratePublicKeys however most of these functions probably belong in a module
const (
tplCommentPrefix = `# gitea public key`
tplPublicKey = tplCommentPrefix + "\n" + `command=%s,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,no-user-rc,restrict %s` + "\n"
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
)
var sshOpLocker sync.Mutex
// AuthorizedStringForKey creates the authorized keys string appropriate for the provided key
func AuthorizedStringForKey(key *PublicKey) string {
sb := &strings.Builder{}
_ = setting.SSH.AuthorizedKeysCommandTemplateTemplate.Execute(sb, map[string]any{
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
"AppPath": util.ShellEscape(setting.AppPath),
"AppWorkPath": util.ShellEscape(setting.AppWorkPath),
"CustomConf": util.ShellEscape(setting.CustomConf),
"CustomPath": util.ShellEscape(setting.CustomPath),
"Key": key,
})
return fmt.Sprintf(tplPublicKey, util.ShellEscape(sb.String()), key.Content)
}
// appendAuthorizedKeysToFile appends new SSH keys' content to authorized_keys file.
func appendAuthorizedKeysToFile(keys ...*PublicKey) error {
// Don't need to rewrite this file if builtin SSH server is enabled.
if setting.SSH.StartBuiltinServer || !setting.SSH.CreateAuthorizedKeysFile {
return nil
}
sshOpLocker.Lock()
defer sshOpLocker.Unlock()
if setting.SSH.RootPath != "" {
// First of ensure that the RootPath is present, and if not make it with 0700 permissions
// This of course doesn't guarantee that this is the right directory for authorized_keys
// but at least if it's supposed to be this directory and it doesn't exist and we're the
// right user it will at least be created properly.
err := os.MkdirAll(setting.SSH.RootPath, 0o700)
if err != nil {
log.Error("Unable to MkdirAll(%s): %v", setting.SSH.RootPath, err)
return err
}
}
fPath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
f, err := os.OpenFile(fPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600)
if err != nil {
return err
}
defer f.Close()
fi, err := f.Stat()
if err != nil {
return err
}
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
// .ssh directory should have mode 700, and authorized_keys file should have mode 600.
if fi.Mode().Perm() > 0o600 {
log.Error("authorized_keys file has unusual permission flags: %s - setting to -rw-------", fi.Mode().Perm().String())
if err = f.Chmod(0o600); err != nil {
return err
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
}
}
for _, key := range keys {
if key.Type == KeyTypePrincipal {
continue
}
if _, err = f.WriteString(key.AuthorizedString()); err != nil {
return err
}
}
return nil
}
feat: ensure only expected ssh public keys are in authorized_keys file (#10010) A security vulnerability that was fixed in #9840 had the potential to corrupt the `authorized_keys` file that Forgejo is managing to allow ssh access. In the event that it was corrupted, the existing behaviour of Forgejo is to maintain the contents that it finds in the `authorized_keys` file, potentially making an exploit of a Forgejo server persistent despite attempts to rewrite the key file. This feature adds a new layer of security resiliency in order to prevent persistent ssh key corruption. When Forgejo starts up, if relevant, Forgejo will read the `authorized_keys` file and validate the file's contents. If any keys are found in the file that are not expected, then Forgejo will terminate its startup in order to signal to the server administrator that a critical security risk is present that must be addressed: ``` 2025/11/07 10:13:50 modules/ssh/init.go:86:Init() [F] An unexpected ssh public key was discovered. Forgejo will shutdown to require this to be fixed. Fix by either: Option 1: Delete the file /home/forgejo/.ssh/authorized_keys, and Forgejo will recreate it with only expected ssh public keys. Option 2: Permit unexpected keys by setting [server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=true in Forgejo's config file. Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 2 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 3 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 4 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 5 of /home/forgejo/.ssh/authorized_keys ``` As noted in the log message, the server administrator can address this problem in one of two ways: - If they delete the file that contains the unexpected keys, Forgejo will regenerate it containing only the expected keys from the Forgejo database. - If they would like to run their server with ssh keys that are not managed by Forgejo (for example, if they're reusing a `git` ssh user that is accessed through `git@server` and does not invoke Forgejo's ssh handlers), then they can disable the new security check by setting `[server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS = true` in their `app.ini`. **This is a breaking change**: the default behaviour is to be restrictive in the contents of `authorized_keys` in order to ensure that server administrators with unexpected keys in `authorized_keys` are aware of those keys. If `SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=false`, then the behaviour when Forgejo rewrites the `authorized_keys` file is changed to not maintain any unexpected keys in the file. If the value is `true`, then the old behaviour is retained. The `doctor check` subcommand is updated to use the new validity routines: ``` [4] Check if OpenSSH authorized_keys file is up-to-date - [E] Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys - [E] Key in database is not present in /home/forgejo/.ssh/authorized_keys: ... - [E] authorized_keys file "/home/forgejo/.ssh/authorized_keys" contains validity errors. Regenerate it with: "forgejo admin regenerate keys" or "forgejo doctor check --run authorized-keys --fix" ERROR ``` ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [x] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - **Documentation updates required**; pending initial reviews of this change. - [ ] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [ ] I want the title to show in the release notes with a link to this pull request. - [x] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10010 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: mfenniak <mfenniak@noreply.codeberg.org> Co-committed-by: mfenniak <mfenniak@noreply.codeberg.org>
2025-11-09 01:06:04 +01:00
type InspectionFinding struct {
Type InspectionFindingType
Comment string
}
type InspectionFindingType int
const (
InspectionResultFileMissing InspectionFindingType = iota // authorized_keys is absent, must regenerate
InspectionResultUnexpectedKey // authorized_keys contains at least one unexpected key
InspectionResultMissingExpectedKey // authorized_keys does not contain a key that is in the DB
)
func InspectPublicKeys(ctx context.Context) ([]InspectionFinding, error) {
if setting.SSH.StartBuiltinServer || !setting.SSH.CreateAuthorizedKeysFile {
return []InspectionFinding{}, nil
}
sshOpLocker.Lock()
defer sshOpLocker.Unlock()
path := filepath.Join(setting.SSH.RootPath, "authorized_keys")
file, err := os.OpenFile(path, os.O_RDONLY, 0o600)
if errors.Is(err, os.ErrNotExist) {
return []InspectionFinding{{Type: InspectionResultFileMissing}}, nil
} else if err != nil {
return nil, err
}
defer file.Close()
// Create a set of all the expected output in the `authorized_keys` file.
expectedKeys := make(container.Set[string])
if err := db.GetEngine(ctx).Where("type != ?", KeyTypePrincipal).Iterate(new(PublicKey), func(idx int, bean any) (err error) {
keyWithComment := (bean.(*PublicKey)).AuthorizedString()
if !strings.HasPrefix(keyWithComment, tplCommentPrefix) {
return fmt.Errorf("unexpected AuthorizedString")
}
key := strings.TrimSpace(keyWithComment[len(tplCommentPrefix):])
expectedKeys.Add(key)
return nil
}); err != nil {
return nil, err
}
findings := []InspectionFinding{}
scanner := bufio.NewScanner(file)
lineNumber := 0
for scanner.Scan() {
lineNumber++
line := scanner.Text()
if strings.HasPrefix(line, tplCommentPrefix) {
// After the public key comment, we expect a public key
lineNumber++
if !scanner.Scan() {
return nil, fmt.Errorf("authorized_keys file %s had a prefix comment but no key on line %d", path, lineNumber)
}
key := strings.TrimSpace(scanner.Text())
if !expectedKeys.Remove(key) {
findings = append(findings, InspectionFinding{
Type: InspectionResultUnexpectedKey,
Comment: fmt.Sprintf("Key on line %d of %s does not exist in database", lineNumber, path),
})
}
} else {
findings = append(findings, InspectionFinding{
Type: InspectionResultUnexpectedKey,
Comment: fmt.Sprintf("Unexpected key on line %d of %s", lineNumber, path),
})
}
}
if err = scanner.Err(); err != nil {
return nil, err
}
for key := range expectedKeys {
findings = append(findings, InspectionFinding{
Type: InspectionResultMissingExpectedKey,
Comment: fmt.Sprintf("Key in database is not present in %s: %s", path, key),
})
}
return findings, nil
}
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
// RewriteAllPublicKeys removes any authorized key and rewrite all keys from database again.
// Note: db.GetEngine(ctx).Iterate does not get latest data after insert/delete, so we have to call this function
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
// outside any session scope independently.
func RewriteAllPublicKeys(ctx context.Context) error {
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
// Don't rewrite key if internal server
if setting.SSH.StartBuiltinServer || !setting.SSH.CreateAuthorizedKeysFile {
return nil
}
sshOpLocker.Lock()
defer sshOpLocker.Unlock()
if setting.SSH.RootPath != "" {
// First of ensure that the RootPath is present, and if not make it with 0700 permissions
// This of course doesn't guarantee that this is the right directory for authorized_keys
// but at least if it's supposed to be this directory and it doesn't exist and we're the
// right user it will at least be created properly.
err := os.MkdirAll(setting.SSH.RootPath, 0o700)
if err != nil {
log.Error("Unable to MkdirAll(%s): %v", setting.SSH.RootPath, err)
return err
}
}
fPath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
tmpPath := fPath + ".tmp"
t, err := os.OpenFile(tmpPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600)
if err != nil {
return err
}
defer func() {
t.Close()
if err := util.Remove(tmpPath); err != nil {
log.Warn("Unable to remove temporary authorized keys file: %s: Error: %v", tmpPath, err)
}
}()
if setting.SSH.AuthorizedKeysBackup {
isExist, err := util.IsExist(fPath)
if err != nil {
log.Error("Unable to check if %s exists. Error: %v", fPath, err)
return err
}
if isExist {
bakPath := fmt.Sprintf("%s_%d.gitea_bak", fPath, time.Now().Unix())
if err = util.CopyFile(fPath, bakPath); err != nil {
return err
}
}
}
feat: ensure only expected ssh public keys are in authorized_keys file (#10010) A security vulnerability that was fixed in #9840 had the potential to corrupt the `authorized_keys` file that Forgejo is managing to allow ssh access. In the event that it was corrupted, the existing behaviour of Forgejo is to maintain the contents that it finds in the `authorized_keys` file, potentially making an exploit of a Forgejo server persistent despite attempts to rewrite the key file. This feature adds a new layer of security resiliency in order to prevent persistent ssh key corruption. When Forgejo starts up, if relevant, Forgejo will read the `authorized_keys` file and validate the file's contents. If any keys are found in the file that are not expected, then Forgejo will terminate its startup in order to signal to the server administrator that a critical security risk is present that must be addressed: ``` 2025/11/07 10:13:50 modules/ssh/init.go:86:Init() [F] An unexpected ssh public key was discovered. Forgejo will shutdown to require this to be fixed. Fix by either: Option 1: Delete the file /home/forgejo/.ssh/authorized_keys, and Forgejo will recreate it with only expected ssh public keys. Option 2: Permit unexpected keys by setting [server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=true in Forgejo's config file. Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 2 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 3 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 4 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 5 of /home/forgejo/.ssh/authorized_keys ``` As noted in the log message, the server administrator can address this problem in one of two ways: - If they delete the file that contains the unexpected keys, Forgejo will regenerate it containing only the expected keys from the Forgejo database. - If they would like to run their server with ssh keys that are not managed by Forgejo (for example, if they're reusing a `git` ssh user that is accessed through `git@server` and does not invoke Forgejo's ssh handlers), then they can disable the new security check by setting `[server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS = true` in their `app.ini`. **This is a breaking change**: the default behaviour is to be restrictive in the contents of `authorized_keys` in order to ensure that server administrators with unexpected keys in `authorized_keys` are aware of those keys. If `SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=false`, then the behaviour when Forgejo rewrites the `authorized_keys` file is changed to not maintain any unexpected keys in the file. If the value is `true`, then the old behaviour is retained. The `doctor check` subcommand is updated to use the new validity routines: ``` [4] Check if OpenSSH authorized_keys file is up-to-date - [E] Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys - [E] Key in database is not present in /home/forgejo/.ssh/authorized_keys: ... - [E] authorized_keys file "/home/forgejo/.ssh/authorized_keys" contains validity errors. Regenerate it with: "forgejo admin regenerate keys" or "forgejo doctor check --run authorized-keys --fix" ERROR ``` ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [x] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - **Documentation updates required**; pending initial reviews of this change. - [ ] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [ ] I want the title to show in the release notes with a link to this pull request. - [x] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10010 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: mfenniak <mfenniak@noreply.codeberg.org> Co-committed-by: mfenniak <mfenniak@noreply.codeberg.org>
2025-11-09 01:06:04 +01:00
if err := regeneratePublicKeys(ctx, t); err != nil {
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
return err
}
[GITEA] Make atomic ssh keys replacement robust - After stumbling upon https://github.com/golang/go/issues/22397 and reading the implementations I realized that Forgejo code doesn't have `Sync()` and it doesn't properly error handle the `Close` function. - (likely) Resolves https://codeberg.org/forgejo/forgejo/issues/1446 (cherry picked from commit 0efcb334c2f123d0869a30d684189eb31e8b983f) (cherry picked from commit 04ef02c0dd98c7437acb39383d311c0901366508) (cherry picked from commit 85f2065c9bc6ded9c21909ec76a9e8fc2d22f462) (cherry picked from commit 8d36b5cce66864e190bad3c9b0973e37ca774a22) (cherry picked from commit 378dc30fb5a88ffe185c54de7e69224289038bff) (cherry picked from commit 2b28bf826e51b8ccb4a693001c03ffe6132f7842) (cherry picked from commit d0625a001e5f8fe202865bec7aadcf0c551d556d) (cherry picked from commit f161a4f60f1cde80a41bece4929836257b9e0423) (cherry picked from commit 7430ca43e57683ca324fb20269a60e05cb393589) (cherry picked from commit ab6d38daf7eeb1dc993bfc0ac1a326af65128168) (cherry picked from commit 0f703fd02e69bdcf2f77e120ff8641f1b8089020) (cherry picked from commit 6931a8f6bbfa0fe4f68b462f88c4a3db7ea06306) (cherry picked from commit 5e2065c1c0ac66d90fae23f989077fa8cb0416ef) (cherry picked from commit 38c812acfffe4c83099881a8b47489caba64b42a) (cherry picked from commit 494874e23f2edb90beabe0827dadefa035e35a71) (cherry picked from commit d396b7fd47c20d08844f8de1255a32fe0de25249) (cherry picked from commit 7babc6efe11d0950ac47d3d4724bb5d414bdd6aa) (cherry picked from commit 2d4dbbe7418d6c1a3a47c7e65350cf65fc9dca19)
2023-09-30 22:16:47 +02:00
if err := t.Sync(); err != nil {
return err
}
if err := t.Close(); err != nil {
return err
}
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
return util.Rename(tmpPath, fPath)
}
feat: ensure only expected ssh public keys are in authorized_keys file (#10010) A security vulnerability that was fixed in #9840 had the potential to corrupt the `authorized_keys` file that Forgejo is managing to allow ssh access. In the event that it was corrupted, the existing behaviour of Forgejo is to maintain the contents that it finds in the `authorized_keys` file, potentially making an exploit of a Forgejo server persistent despite attempts to rewrite the key file. This feature adds a new layer of security resiliency in order to prevent persistent ssh key corruption. When Forgejo starts up, if relevant, Forgejo will read the `authorized_keys` file and validate the file's contents. If any keys are found in the file that are not expected, then Forgejo will terminate its startup in order to signal to the server administrator that a critical security risk is present that must be addressed: ``` 2025/11/07 10:13:50 modules/ssh/init.go:86:Init() [F] An unexpected ssh public key was discovered. Forgejo will shutdown to require this to be fixed. Fix by either: Option 1: Delete the file /home/forgejo/.ssh/authorized_keys, and Forgejo will recreate it with only expected ssh public keys. Option 2: Permit unexpected keys by setting [server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=true in Forgejo's config file. Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 2 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 3 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 4 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 5 of /home/forgejo/.ssh/authorized_keys ``` As noted in the log message, the server administrator can address this problem in one of two ways: - If they delete the file that contains the unexpected keys, Forgejo will regenerate it containing only the expected keys from the Forgejo database. - If they would like to run their server with ssh keys that are not managed by Forgejo (for example, if they're reusing a `git` ssh user that is accessed through `git@server` and does not invoke Forgejo's ssh handlers), then they can disable the new security check by setting `[server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS = true` in their `app.ini`. **This is a breaking change**: the default behaviour is to be restrictive in the contents of `authorized_keys` in order to ensure that server administrators with unexpected keys in `authorized_keys` are aware of those keys. If `SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=false`, then the behaviour when Forgejo rewrites the `authorized_keys` file is changed to not maintain any unexpected keys in the file. If the value is `true`, then the old behaviour is retained. The `doctor check` subcommand is updated to use the new validity routines: ``` [4] Check if OpenSSH authorized_keys file is up-to-date - [E] Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys - [E] Key in database is not present in /home/forgejo/.ssh/authorized_keys: ... - [E] authorized_keys file "/home/forgejo/.ssh/authorized_keys" contains validity errors. Regenerate it with: "forgejo admin regenerate keys" or "forgejo doctor check --run authorized-keys --fix" ERROR ``` ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [x] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - **Documentation updates required**; pending initial reviews of this change. - [ ] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [ ] I want the title to show in the release notes with a link to this pull request. - [x] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10010 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: mfenniak <mfenniak@noreply.codeberg.org> Co-committed-by: mfenniak <mfenniak@noreply.codeberg.org>
2025-11-09 01:06:04 +01:00
// regeneratePublicKeys regenerates the authorized_keys file
func regeneratePublicKeys(ctx context.Context, t io.StringWriter) error {
if err := db.GetEngine(ctx).Where("type != ?", KeyTypePrincipal).Iterate(new(PublicKey), func(idx int, bean any) (err error) {
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
_, err = t.WriteString((bean.(*PublicKey)).AuthorizedString())
return err
}); err != nil {
return err
}
feat: ensure only expected ssh public keys are in authorized_keys file (#10010) A security vulnerability that was fixed in #9840 had the potential to corrupt the `authorized_keys` file that Forgejo is managing to allow ssh access. In the event that it was corrupted, the existing behaviour of Forgejo is to maintain the contents that it finds in the `authorized_keys` file, potentially making an exploit of a Forgejo server persistent despite attempts to rewrite the key file. This feature adds a new layer of security resiliency in order to prevent persistent ssh key corruption. When Forgejo starts up, if relevant, Forgejo will read the `authorized_keys` file and validate the file's contents. If any keys are found in the file that are not expected, then Forgejo will terminate its startup in order to signal to the server administrator that a critical security risk is present that must be addressed: ``` 2025/11/07 10:13:50 modules/ssh/init.go:86:Init() [F] An unexpected ssh public key was discovered. Forgejo will shutdown to require this to be fixed. Fix by either: Option 1: Delete the file /home/forgejo/.ssh/authorized_keys, and Forgejo will recreate it with only expected ssh public keys. Option 2: Permit unexpected keys by setting [server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=true in Forgejo's config file. Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 2 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 3 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 4 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 5 of /home/forgejo/.ssh/authorized_keys ``` As noted in the log message, the server administrator can address this problem in one of two ways: - If they delete the file that contains the unexpected keys, Forgejo will regenerate it containing only the expected keys from the Forgejo database. - If they would like to run their server with ssh keys that are not managed by Forgejo (for example, if they're reusing a `git` ssh user that is accessed through `git@server` and does not invoke Forgejo's ssh handlers), then they can disable the new security check by setting `[server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS = true` in their `app.ini`. **This is a breaking change**: the default behaviour is to be restrictive in the contents of `authorized_keys` in order to ensure that server administrators with unexpected keys in `authorized_keys` are aware of those keys. If `SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=false`, then the behaviour when Forgejo rewrites the `authorized_keys` file is changed to not maintain any unexpected keys in the file. If the value is `true`, then the old behaviour is retained. The `doctor check` subcommand is updated to use the new validity routines: ``` [4] Check if OpenSSH authorized_keys file is up-to-date - [E] Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys - [E] Key in database is not present in /home/forgejo/.ssh/authorized_keys: ... - [E] authorized_keys file "/home/forgejo/.ssh/authorized_keys" contains validity errors. Regenerate it with: "forgejo admin regenerate keys" or "forgejo doctor check --run authorized-keys --fix" ERROR ``` ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [x] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - **Documentation updates required**; pending initial reviews of this change. - [ ] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [ ] I want the title to show in the release notes with a link to this pull request. - [x] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10010 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: mfenniak <mfenniak@noreply.codeberg.org> Co-committed-by: mfenniak <mfenniak@noreply.codeberg.org>
2025-11-09 01:06:04 +01:00
// Preserve any authorized_keys contents that are not generated from Forgejo
if setting.SSH.AllowUnexpectedAuthorizedKeys {
fPath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
isExist, err := util.IsExist(fPath)
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
if err != nil {
feat: ensure only expected ssh public keys are in authorized_keys file (#10010) A security vulnerability that was fixed in #9840 had the potential to corrupt the `authorized_keys` file that Forgejo is managing to allow ssh access. In the event that it was corrupted, the existing behaviour of Forgejo is to maintain the contents that it finds in the `authorized_keys` file, potentially making an exploit of a Forgejo server persistent despite attempts to rewrite the key file. This feature adds a new layer of security resiliency in order to prevent persistent ssh key corruption. When Forgejo starts up, if relevant, Forgejo will read the `authorized_keys` file and validate the file's contents. If any keys are found in the file that are not expected, then Forgejo will terminate its startup in order to signal to the server administrator that a critical security risk is present that must be addressed: ``` 2025/11/07 10:13:50 modules/ssh/init.go:86:Init() [F] An unexpected ssh public key was discovered. Forgejo will shutdown to require this to be fixed. Fix by either: Option 1: Delete the file /home/forgejo/.ssh/authorized_keys, and Forgejo will recreate it with only expected ssh public keys. Option 2: Permit unexpected keys by setting [server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=true in Forgejo's config file. Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 2 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 3 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 4 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 5 of /home/forgejo/.ssh/authorized_keys ``` As noted in the log message, the server administrator can address this problem in one of two ways: - If they delete the file that contains the unexpected keys, Forgejo will regenerate it containing only the expected keys from the Forgejo database. - If they would like to run their server with ssh keys that are not managed by Forgejo (for example, if they're reusing a `git` ssh user that is accessed through `git@server` and does not invoke Forgejo's ssh handlers), then they can disable the new security check by setting `[server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS = true` in their `app.ini`. **This is a breaking change**: the default behaviour is to be restrictive in the contents of `authorized_keys` in order to ensure that server administrators with unexpected keys in `authorized_keys` are aware of those keys. If `SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=false`, then the behaviour when Forgejo rewrites the `authorized_keys` file is changed to not maintain any unexpected keys in the file. If the value is `true`, then the old behaviour is retained. The `doctor check` subcommand is updated to use the new validity routines: ``` [4] Check if OpenSSH authorized_keys file is up-to-date - [E] Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys - [E] Key in database is not present in /home/forgejo/.ssh/authorized_keys: ... - [E] authorized_keys file "/home/forgejo/.ssh/authorized_keys" contains validity errors. Regenerate it with: "forgejo admin regenerate keys" or "forgejo doctor check --run authorized-keys --fix" ERROR ``` ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [x] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - **Documentation updates required**; pending initial reviews of this change. - [ ] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [ ] I want the title to show in the release notes with a link to this pull request. - [x] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10010 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: mfenniak <mfenniak@noreply.codeberg.org> Co-committed-by: mfenniak <mfenniak@noreply.codeberg.org>
2025-11-09 01:06:04 +01:00
log.Error("Unable to check if %s exists. Error: %v", fPath, err)
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
return err
}
feat: ensure only expected ssh public keys are in authorized_keys file (#10010) A security vulnerability that was fixed in #9840 had the potential to corrupt the `authorized_keys` file that Forgejo is managing to allow ssh access. In the event that it was corrupted, the existing behaviour of Forgejo is to maintain the contents that it finds in the `authorized_keys` file, potentially making an exploit of a Forgejo server persistent despite attempts to rewrite the key file. This feature adds a new layer of security resiliency in order to prevent persistent ssh key corruption. When Forgejo starts up, if relevant, Forgejo will read the `authorized_keys` file and validate the file's contents. If any keys are found in the file that are not expected, then Forgejo will terminate its startup in order to signal to the server administrator that a critical security risk is present that must be addressed: ``` 2025/11/07 10:13:50 modules/ssh/init.go:86:Init() [F] An unexpected ssh public key was discovered. Forgejo will shutdown to require this to be fixed. Fix by either: Option 1: Delete the file /home/forgejo/.ssh/authorized_keys, and Forgejo will recreate it with only expected ssh public keys. Option 2: Permit unexpected keys by setting [server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=true in Forgejo's config file. Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 2 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 3 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 4 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 5 of /home/forgejo/.ssh/authorized_keys ``` As noted in the log message, the server administrator can address this problem in one of two ways: - If they delete the file that contains the unexpected keys, Forgejo will regenerate it containing only the expected keys from the Forgejo database. - If they would like to run their server with ssh keys that are not managed by Forgejo (for example, if they're reusing a `git` ssh user that is accessed through `git@server` and does not invoke Forgejo's ssh handlers), then they can disable the new security check by setting `[server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS = true` in their `app.ini`. **This is a breaking change**: the default behaviour is to be restrictive in the contents of `authorized_keys` in order to ensure that server administrators with unexpected keys in `authorized_keys` are aware of those keys. If `SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=false`, then the behaviour when Forgejo rewrites the `authorized_keys` file is changed to not maintain any unexpected keys in the file. If the value is `true`, then the old behaviour is retained. The `doctor check` subcommand is updated to use the new validity routines: ``` [4] Check if OpenSSH authorized_keys file is up-to-date - [E] Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys - [E] Key in database is not present in /home/forgejo/.ssh/authorized_keys: ... - [E] authorized_keys file "/home/forgejo/.ssh/authorized_keys" contains validity errors. Regenerate it with: "forgejo admin regenerate keys" or "forgejo doctor check --run authorized-keys --fix" ERROR ``` ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [x] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - **Documentation updates required**; pending initial reviews of this change. - [ ] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [ ] I want the title to show in the release notes with a link to this pull request. - [x] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10010 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: mfenniak <mfenniak@noreply.codeberg.org> Co-committed-by: mfenniak <mfenniak@noreply.codeberg.org>
2025-11-09 01:06:04 +01:00
if isExist {
f, err := os.Open(fPath)
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
if err != nil {
return err
}
feat: ensure only expected ssh public keys are in authorized_keys file (#10010) A security vulnerability that was fixed in #9840 had the potential to corrupt the `authorized_keys` file that Forgejo is managing to allow ssh access. In the event that it was corrupted, the existing behaviour of Forgejo is to maintain the contents that it finds in the `authorized_keys` file, potentially making an exploit of a Forgejo server persistent despite attempts to rewrite the key file. This feature adds a new layer of security resiliency in order to prevent persistent ssh key corruption. When Forgejo starts up, if relevant, Forgejo will read the `authorized_keys` file and validate the file's contents. If any keys are found in the file that are not expected, then Forgejo will terminate its startup in order to signal to the server administrator that a critical security risk is present that must be addressed: ``` 2025/11/07 10:13:50 modules/ssh/init.go:86:Init() [F] An unexpected ssh public key was discovered. Forgejo will shutdown to require this to be fixed. Fix by either: Option 1: Delete the file /home/forgejo/.ssh/authorized_keys, and Forgejo will recreate it with only expected ssh public keys. Option 2: Permit unexpected keys by setting [server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=true in Forgejo's config file. Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 2 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 3 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 4 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 5 of /home/forgejo/.ssh/authorized_keys ``` As noted in the log message, the server administrator can address this problem in one of two ways: - If they delete the file that contains the unexpected keys, Forgejo will regenerate it containing only the expected keys from the Forgejo database. - If they would like to run their server with ssh keys that are not managed by Forgejo (for example, if they're reusing a `git` ssh user that is accessed through `git@server` and does not invoke Forgejo's ssh handlers), then they can disable the new security check by setting `[server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS = true` in their `app.ini`. **This is a breaking change**: the default behaviour is to be restrictive in the contents of `authorized_keys` in order to ensure that server administrators with unexpected keys in `authorized_keys` are aware of those keys. If `SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=false`, then the behaviour when Forgejo rewrites the `authorized_keys` file is changed to not maintain any unexpected keys in the file. If the value is `true`, then the old behaviour is retained. The `doctor check` subcommand is updated to use the new validity routines: ``` [4] Check if OpenSSH authorized_keys file is up-to-date - [E] Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys - [E] Key in database is not present in /home/forgejo/.ssh/authorized_keys: ... - [E] authorized_keys file "/home/forgejo/.ssh/authorized_keys" contains validity errors. Regenerate it with: "forgejo admin regenerate keys" or "forgejo doctor check --run authorized-keys --fix" ERROR ``` ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [x] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - **Documentation updates required**; pending initial reviews of this change. - [ ] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [ ] I want the title to show in the release notes with a link to this pull request. - [x] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10010 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: mfenniak <mfenniak@noreply.codeberg.org> Co-committed-by: mfenniak <mfenniak@noreply.codeberg.org>
2025-11-09 01:06:04 +01:00
defer f.Close()
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, tplCommentPrefix) {
scanner.Scan()
continue
}
_, err = t.WriteString(line + "\n")
if err != nil {
return err
}
}
if err = scanner.Err(); err != nil {
return fmt.Errorf("regeneratePublicKeys scan: %w", err)
}
}
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
}
feat: ensure only expected ssh public keys are in authorized_keys file (#10010) A security vulnerability that was fixed in #9840 had the potential to corrupt the `authorized_keys` file that Forgejo is managing to allow ssh access. In the event that it was corrupted, the existing behaviour of Forgejo is to maintain the contents that it finds in the `authorized_keys` file, potentially making an exploit of a Forgejo server persistent despite attempts to rewrite the key file. This feature adds a new layer of security resiliency in order to prevent persistent ssh key corruption. When Forgejo starts up, if relevant, Forgejo will read the `authorized_keys` file and validate the file's contents. If any keys are found in the file that are not expected, then Forgejo will terminate its startup in order to signal to the server administrator that a critical security risk is present that must be addressed: ``` 2025/11/07 10:13:50 modules/ssh/init.go:86:Init() [F] An unexpected ssh public key was discovered. Forgejo will shutdown to require this to be fixed. Fix by either: Option 1: Delete the file /home/forgejo/.ssh/authorized_keys, and Forgejo will recreate it with only expected ssh public keys. Option 2: Permit unexpected keys by setting [server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=true in Forgejo's config file. Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 2 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 3 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 4 of /home/forgejo/.ssh/authorized_keys Unexpected key on line 5 of /home/forgejo/.ssh/authorized_keys ``` As noted in the log message, the server administrator can address this problem in one of two ways: - If they delete the file that contains the unexpected keys, Forgejo will regenerate it containing only the expected keys from the Forgejo database. - If they would like to run their server with ssh keys that are not managed by Forgejo (for example, if they're reusing a `git` ssh user that is accessed through `git@server` and does not invoke Forgejo's ssh handlers), then they can disable the new security check by setting `[server].SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS = true` in their `app.ini`. **This is a breaking change**: the default behaviour is to be restrictive in the contents of `authorized_keys` in order to ensure that server administrators with unexpected keys in `authorized_keys` are aware of those keys. If `SSH_ALLOW_UNEXPECTED_AUTHORIZED_KEYS=false`, then the behaviour when Forgejo rewrites the `authorized_keys` file is changed to not maintain any unexpected keys in the file. If the value is `true`, then the old behaviour is retained. The `doctor check` subcommand is updated to use the new validity routines: ``` [4] Check if OpenSSH authorized_keys file is up-to-date - [E] Unexpected key on line 1 of /home/forgejo/.ssh/authorized_keys - [E] Key in database is not present in /home/forgejo/.ssh/authorized_keys: ... - [E] authorized_keys file "/home/forgejo/.ssh/authorized_keys" contains validity errors. Regenerate it with: "forgejo admin regenerate keys" or "forgejo doctor check --run authorized-keys --fix" ERROR ``` ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [x] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [x] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - **Documentation updates required**; pending initial reviews of this change. - [ ] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [ ] I want the title to show in the release notes with a link to this pull request. - [x] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10010 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: mfenniak <mfenniak@noreply.codeberg.org> Co-committed-by: mfenniak <mfenniak@noreply.codeberg.org>
2025-11-09 01:06:04 +01:00
Refactor: Move login out of models (#16199) `models` does far too much. In particular it handles all `UserSignin`. It shouldn't be responsible for calling LDAP, SMTP or PAM for signing in. Therefore we should move this code out of `models`. This code has to depend on `models` - therefore it belongs in `services`. There is a package in `services` called `auth` and clearly this functionality belongs in there. Plan: - [x] Change `auth.Auth` to `auth.Method` - as they represent methods of authentication. - [x] Move `models.UserSignIn` into `auth` - [x] Move `models.ExternalUserLogin` - [x] Move most of the `LoginVia*` methods to `auth` or subpackages - [x] Move Resynchronize functionality to `auth` - Involved some restructuring of `models/ssh_key.go` to reduce the size of this massive file and simplify its files. - [x] Move the rest of the LDAP functionality in to the ldap subpackage - [x] Re-factor the login sources to express an interfaces `auth.Source`? - I've done this through some smaller interfaces Authenticator and Synchronizable - which would allow us to extend things in future - [x] Now LDAP is out of models - need to think about modules/auth/ldap and I think all of that functionality might just be moveable - [x] Similarly a lot Oauth2 functionality need not be in models too and should be moved to services/auth/source/oauth2 - [x] modules/auth/oauth2/oauth2.go uses xorm... This is naughty - probably need to move this into models. - [x] models/oauth2.go - mostly should be in modules/auth/oauth2 or services/auth/source/oauth2 - [x] More simplifications of login_source.go may need to be done - Allow wiring in of notify registration - *this can now easily be done - but I think we should do it in another PR* - see #16178 - More refactors...? - OpenID should probably become an auth Method but I think that can be left for another PR - Methods should also probably be cleaned up - again another PR I think. - SSPI still needs more refactors.* Rename auth.Auth auth.Method * Restructure ssh_key.go - move functions from models/user.go that relate to ssh_key to ssh_key - split ssh_key.go to try create clearer function domains for allow for future refactors here. Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-07-24 11:16:34 +01:00
return nil
}