Drop SSPI auth support and more Windows files (#7148)
## Dropping SSPI auth support SSPI authentication relied on Microsoft Windows support, removal started in https://codeberg.org/forgejo/forgejo/pulls/5353, because it was broken anyway. We have no knowledge of any users using SSPI authentication. However, if you somehow managed to run Forgejo on Windows, or want to upgrade from a Gitea version which does, please ensure that you do not use SSPI as an authentication mechanism for user accounts. Feel free to reach out if you need assistance. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7148 Reviewed-by: Gusted <gusted@noreply.codeberg.org> Reviewed-by: 0ko <0ko@noreply.codeberg.org> Co-authored-by: Otto Richter <otto@codeberg.org> Co-committed-by: Otto Richter <otto@codeberg.org>
This commit is contained in:
parent
3de904c963
commit
9dea54a9d6
43 changed files with 39 additions and 816 deletions
|
@ -139,7 +139,7 @@ func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath
|
|||
cmd := NewCommandContextNoGlobals(ctx, "blame", "--porcelain")
|
||||
if ignoreRevsFile != nil {
|
||||
// Possible improvement: use --ignore-revs-file /dev/stdin on unix
|
||||
// There is no equivalent on Windows. May be implemented if Gitea uses an external git backend.
|
||||
// This was not done in Gitea because it would not have been compatible with Windows.
|
||||
cmd.AddOptionValues("--ignore-revs-file", *ignoreRevsFile)
|
||||
}
|
||||
cmd.AddDynamicArguments(commit.ID.String()).
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"runtime/trace"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -359,17 +358,6 @@ func (c *Command) Run(opts *RunOpts) error {
|
|||
log.Debug("slow git.Command.Run: %s (%s)", c, elapsed)
|
||||
}
|
||||
|
||||
// We need to check if the context is canceled by the program on Windows.
|
||||
// This is because Windows does not have signal checking when terminating the process.
|
||||
// It always returns exit code 1, unlike Linux, which has many exit codes for signals.
|
||||
if runtime.GOOS == "windows" &&
|
||||
err != nil &&
|
||||
err.Error() == "" &&
|
||||
cmd.ProcessState.ExitCode() == 1 &&
|
||||
ctx.Err() == context.Canceled {
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
if err != nil && ctx.Err() != context.DeadlineExceeded {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -59,15 +59,7 @@ func loadGitVersion() error {
|
|||
return fmt.Errorf("invalid git version output: %s", stdout)
|
||||
}
|
||||
|
||||
var versionString string
|
||||
|
||||
// Handle special case on Windows.
|
||||
i := strings.Index(fields[2], "windows")
|
||||
if i >= 1 {
|
||||
versionString = fields[2][:i-1]
|
||||
} else {
|
||||
versionString = fields[2]
|
||||
}
|
||||
versionString := fields[2]
|
||||
|
||||
var err error
|
||||
gitVersion, err = version.NewVersion(versionString)
|
||||
|
@ -280,24 +272,11 @@ func syncGitConfig() (err error) {
|
|||
// Thus the owner uid/gid for files on these filesystems will be marked as root.
|
||||
// As Gitea now always use its internal git config file, and access to the git repositories is managed through Gitea,
|
||||
// it is now safe to set "safe.directory=*" for internal usage only.
|
||||
// Please note: the wildcard "*" is only supported by Git 2.30.4/2.31.3/2.32.2/2.33.3/2.34.3/2.35.3/2.36 and later
|
||||
// Although only supported by Git 2.30.4/2.31.3/2.32.2/2.33.3/2.34.3/2.35.3/2.36 and later - this setting is tolerated by earlier versions
|
||||
// Please note: the wildcard "*" is only supported by Git 2.30.4/2.31.3/2.32.2/2.33.3/2.34.3/2.35.3/2.36 and later,
|
||||
// but is tolerated by earlier versions
|
||||
if err := configAddNonExist("safe.directory", "*"); err != nil {
|
||||
return err
|
||||
}
|
||||
if runtime.GOOS == "windows" {
|
||||
if err := configSet("core.longpaths", "true"); err != nil {
|
||||
return err
|
||||
}
|
||||
if setting.Git.DisableCoreProtectNTFS {
|
||||
err = configSet("core.protectNTFS", "false")
|
||||
} else {
|
||||
err = configUnsetAll("core.protectNTFS", "false")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// By default partial clones are disabled, enable them from git v2.22
|
||||
if !setting.Git.DisablePartialClone && CheckGitVersionAtLeast("2.22") == nil {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build !windows
|
||||
|
||||
package graceful
|
||||
|
||||
import (
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
|
||||
|
||||
//go:build !windows
|
||||
|
||||
package graceful
|
||||
|
||||
import (
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
|
||||
|
||||
//go:build !windows
|
||||
|
||||
package graceful
|
||||
|
||||
import (
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build !windows
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package log
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/mattn/go-isatty"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func enableVTMode(console windows.Handle) bool {
|
||||
mode := uint32(0)
|
||||
err := windows.GetConsoleMode(console, &mode)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// EnableVirtualTerminalProcessing is the console mode to allow ANSI code
|
||||
// interpretation on the console. See:
|
||||
// https://docs.microsoft.com/en-us/windows/console/setconsolemode
|
||||
// It only works on Windows 10. Earlier terminals will fail with an err which we will
|
||||
// handle to say don't color
|
||||
mode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||
err = windows.SetConsoleMode(console, mode)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
if isatty.IsTerminal(os.Stdout.Fd()) {
|
||||
CanColorStdout = enableVTMode(windows.Stdout)
|
||||
} else {
|
||||
CanColorStdout = isatty.IsCygwinTerminal(os.Stderr.Fd())
|
||||
}
|
||||
|
||||
if isatty.IsTerminal(os.Stderr.Fd()) {
|
||||
CanColorStderr = enableVTMode(windows.Stderr)
|
||||
} else {
|
||||
CanColorStderr = isatty.IsCygwinTerminal(os.Stderr.Fd())
|
||||
}
|
||||
}
|
4
modules/markup/external/external.go
vendored
4
modules/markup/external/external.go
vendored
|
@ -9,7 +9,6 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
|
@ -70,9 +69,6 @@ func (p *Renderer) DisplayInIFrame() bool {
|
|||
}
|
||||
|
||||
func envMark(envName string) string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return "%" + envName + "%"
|
||||
}
|
||||
return "$" + envName
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build !windows
|
||||
|
||||
package process
|
||||
|
||||
import (
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
@ -146,10 +145,6 @@ func CreateDelegateHooks(repoPath string) (err error) {
|
|||
}
|
||||
|
||||
func checkExecutable(filename string) bool {
|
||||
// windows has no concept of a executable bit
|
||||
if runtime.GOOS == "windows" {
|
||||
return true
|
||||
}
|
||||
fileInfo, err := os.Stat(filename)
|
||||
if err != nil {
|
||||
return false
|
||||
|
|
|
@ -34,11 +34,7 @@ var (
|
|||
func getAppPath() (string, error) {
|
||||
var appPath string
|
||||
var err error
|
||||
if IsWindows && filepath.IsAbs(os.Args[0]) {
|
||||
appPath = filepath.Clean(os.Args[0])
|
||||
} else {
|
||||
appPath, err = exec.LookPath(os.Args[0])
|
||||
}
|
||||
appPath, err = exec.LookPath(os.Args[0])
|
||||
if err != nil {
|
||||
if !errors.Is(err, exec.ErrDot) {
|
||||
return "", err
|
||||
|
|
|
@ -8,7 +8,6 @@ package setting
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -34,7 +33,6 @@ var (
|
|||
RunMode string
|
||||
RunUser string
|
||||
IsProd bool
|
||||
IsWindows bool
|
||||
|
||||
// IsInTesting indicates whether the testing is running. A lot of unreliable code causes a lot of nonsense error logs during testing
|
||||
// TODO: this is only a temporary solution, we should make the test code more reliable
|
||||
|
@ -42,22 +40,18 @@ var (
|
|||
)
|
||||
|
||||
func init() {
|
||||
IsWindows = runtime.GOOS == "windows"
|
||||
if AppVer == "" {
|
||||
AppVer = "dev"
|
||||
}
|
||||
|
||||
// We can rely on log.CanColorStdout being set properly because modules/log/console_windows.go comes before modules/setting/setting.go lexicographically
|
||||
// By default set this logger at Info - we'll change it later, but we need to start with something.
|
||||
log.SetConsoleLogger(log.DEFAULT, "console", log.INFO)
|
||||
}
|
||||
|
||||
// IsRunUserMatchCurrentUser returns false if configured run user does not match
|
||||
// actual user that runs the app. The first return value is the actual user name.
|
||||
// This check is ignored under Windows since SSH remote login is not the main
|
||||
// method to login on Windows.
|
||||
func IsRunUserMatchCurrentUser(runUser string) (string, bool) {
|
||||
if IsWindows || SSH.StartBuiltinServer {
|
||||
if SSH.StartBuiltinServer {
|
||||
return "", true
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@ package user
|
|||
import (
|
||||
"os"
|
||||
"os/user"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CurrentUsername return current login OS user name
|
||||
|
@ -16,12 +14,7 @@ func CurrentUsername() string {
|
|||
if err != nil {
|
||||
return fallbackCurrentUsername()
|
||||
}
|
||||
username := userinfo.Username
|
||||
if runtime.GOOS == "windows" {
|
||||
parts := strings.Split(username, "\\")
|
||||
username = parts[len(parts)-1]
|
||||
}
|
||||
return username
|
||||
return userinfo.Username
|
||||
}
|
||||
|
||||
// Old method, used if new method doesn't work on your OS for some reason
|
||||
|
|
|
@ -5,7 +5,6 @@ package user
|
|||
|
||||
import (
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
@ -23,10 +22,6 @@ func TestCurrentUsername(t *testing.T) {
|
|||
if len(user) == 0 {
|
||||
t.Errorf("expected non-empty user, got: %s", user)
|
||||
}
|
||||
// Windows whoami is weird, so just skip remaining tests
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("skipped test because of weird whoami on Windows")
|
||||
}
|
||||
whoami, err := getWhoamiOutput()
|
||||
if err != nil {
|
||||
t.Errorf("failed to run whoami to test current user: %f", err)
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build !windows
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//go:build !windows
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
|
|
|
@ -10,8 +10,6 @@ import (
|
|||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -78,11 +76,7 @@ func FilePathJoinAbs(base string, sub ...string) string {
|
|||
|
||||
// POSIX filesystem can have `\` in file names. Windows: `\` and `/` are both used for path separators
|
||||
// to keep the behavior consistent, we do not allow `\` in file names, replace all `\` with `/`
|
||||
if isOSWindows() {
|
||||
elems[0] = filepath.Clean(base)
|
||||
} else {
|
||||
elems[0] = filepath.Clean(strings.ReplaceAll(base, "\\", pathSeparator))
|
||||
}
|
||||
elems[0] = filepath.Clean(strings.ReplaceAll(base, "\\", pathSeparator))
|
||||
if !filepath.IsAbs(elems[0]) {
|
||||
// This shouldn't happen. If there is really necessary to pass in relative path, return the full path with filepath.Abs() instead
|
||||
panic(fmt.Sprintf("FilePathJoinAbs: %q (for path %v) is not absolute, do not guess a relative path based on current working directory", elems[0], elems))
|
||||
|
@ -91,11 +85,7 @@ func FilePathJoinAbs(base string, sub ...string) string {
|
|||
if s == "" {
|
||||
continue
|
||||
}
|
||||
if isOSWindows() {
|
||||
elems = append(elems, filepath.Clean(pathSeparator+s))
|
||||
} else {
|
||||
elems = append(elems, filepath.Clean(pathSeparator+strings.ReplaceAll(s, "\\", pathSeparator)))
|
||||
}
|
||||
elems = append(elems, filepath.Clean(pathSeparator+strings.ReplaceAll(s, "\\", pathSeparator)))
|
||||
}
|
||||
// the elems[0] must be an absolute path, just join them together
|
||||
return filepath.Join(elems...)
|
||||
|
@ -217,12 +207,6 @@ func StatDir(rootPath string, includeDir ...bool) ([]string, error) {
|
|||
return statDir(rootPath, "", isIncludeDir, false, false)
|
||||
}
|
||||
|
||||
func isOSWindows() bool {
|
||||
return runtime.GOOS == "windows"
|
||||
}
|
||||
|
||||
var driveLetterRegexp = regexp.MustCompile("/[A-Za-z]:/")
|
||||
|
||||
// FileURLToPath extracts the path information from a file://... url.
|
||||
// It returns an error only if the URL is not a file URL.
|
||||
func FileURLToPath(u *url.URL) (string, error) {
|
||||
|
@ -230,17 +214,7 @@ func FileURLToPath(u *url.URL) (string, error) {
|
|||
return "", errors.New("URL scheme is not 'file': " + u.String())
|
||||
}
|
||||
|
||||
path := u.Path
|
||||
|
||||
if !isOSWindows() {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
// If it looks like there's a Windows drive letter at the beginning, strip off the leading slash.
|
||||
if driveLetterRegexp.MatchString(path) {
|
||||
return path[1:], nil
|
||||
}
|
||||
return path, nil
|
||||
return u.Path, nil
|
||||
}
|
||||
|
||||
// HomeDir returns path of '~'(in Linux) on Windows,
|
||||
|
@ -249,14 +223,7 @@ func HomeDir() (home string, err error) {
|
|||
// TODO: some users run Gitea with mismatched uid and "HOME=xxx" (they set HOME=xxx by environment manually)
|
||||
// TODO: when running gitea as a sub command inside git, the HOME directory is not the user's home directory
|
||||
// so at the moment we can not use `user.Current().HomeDir`
|
||||
if isOSWindows() {
|
||||
home = os.Getenv("USERPROFILE")
|
||||
if home == "" {
|
||||
home = os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
|
||||
}
|
||||
} else {
|
||||
home = os.Getenv("HOME")
|
||||
}
|
||||
home = os.Getenv("HOME")
|
||||
|
||||
if home == "" {
|
||||
return "", errors.New("cannot get home directory")
|
||||
|
|
|
@ -5,7 +5,6 @@ package util
|
|||
|
||||
import (
|
||||
"net/url"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -17,7 +16,6 @@ func TestFileURLToPath(t *testing.T) {
|
|||
url string
|
||||
expected string
|
||||
haserror bool
|
||||
windows bool
|
||||
}{
|
||||
// case 0
|
||||
{
|
||||
|
@ -34,18 +32,9 @@ func TestFileURLToPath(t *testing.T) {
|
|||
url: "file:///path",
|
||||
expected: "/path",
|
||||
},
|
||||
// case 3
|
||||
{
|
||||
url: "file:///C:/path",
|
||||
expected: "C:/path",
|
||||
windows: true,
|
||||
},
|
||||
}
|
||||
|
||||
for n, c := range cases {
|
||||
if c.windows && runtime.GOOS != "windows" {
|
||||
continue
|
||||
}
|
||||
u, _ := url.Parse(c.url)
|
||||
p, err := FileURLToPath(u)
|
||||
if c.haserror {
|
||||
|
@ -177,35 +166,18 @@ func TestCleanPath(t *testing.T) {
|
|||
assert.Equal(t, c.expected, PathJoinRelX(c.elems...), "case: %v", c.elems)
|
||||
}
|
||||
|
||||
// for POSIX only, but the result is similar on Windows, because the first element must be an absolute path
|
||||
if isOSWindows() {
|
||||
cases = []struct {
|
||||
elems []string
|
||||
expected string
|
||||
}{
|
||||
{[]string{`C:\..`}, `C:\`},
|
||||
{[]string{`C:\a`}, `C:\a`},
|
||||
{[]string{`C:\a/`}, `C:\a`},
|
||||
{[]string{`C:\..\a\`, `../b`, `c\..`, `d`}, `C:\a\b\d`},
|
||||
{[]string{`C:\a/..\b`}, `C:\b`},
|
||||
{[]string{`C:\a`, ``, `b`}, `C:\a\b`},
|
||||
{[]string{`C:\a`, `..`, `b`}, `C:\a\b`},
|
||||
{[]string{`C:\lfs`, `repo/..`, `user/../path`}, `C:\lfs\path`},
|
||||
}
|
||||
} else {
|
||||
cases = []struct {
|
||||
elems []string
|
||||
expected string
|
||||
}{
|
||||
{[]string{`/..`}, `/`},
|
||||
{[]string{`/a`}, `/a`},
|
||||
{[]string{`/a/`}, `/a`},
|
||||
{[]string{`/../a/`, `../b`, `c/..`, `d`}, `/a/b/d`},
|
||||
{[]string{`/a\..\b`}, `/b`},
|
||||
{[]string{`/a`, ``, `b`}, `/a/b`},
|
||||
{[]string{`/a`, `..`, `b`}, `/a/b`},
|
||||
{[]string{`/lfs`, `repo/..`, `user/../path`}, `/lfs/path`},
|
||||
}
|
||||
cases = []struct {
|
||||
elems []string
|
||||
expected string
|
||||
}{
|
||||
{[]string{`/..`}, `/`},
|
||||
{[]string{`/a`}, `/a`},
|
||||
{[]string{`/a/`}, `/a`},
|
||||
{[]string{`/../a/`, `../b`, `c/..`, `d`}, `/a/b/d`},
|
||||
{[]string{`/a\..\b`}, `/b`},
|
||||
{[]string{`/a`, ``, `b`}, `/a/b`},
|
||||
{[]string{`/a`, `..`, `b`}, `/a/b`},
|
||||
{[]string{`/lfs`, `repo/..`, `user/../path`}, `/lfs/path`},
|
||||
}
|
||||
for _, c := range cases {
|
||||
assert.Equal(t, c.expected, FilePathJoinAbs(c.elems[0], c.elems[1:]...), "case: %v", c.elems)
|
||||
|
|
|
@ -5,13 +5,10 @@ package util
|
|||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
const windowsSharingViolationError syscall.Errno = 32
|
||||
|
||||
// Remove removes the named file or (empty) directory with at most 5 attempts.
|
||||
func Remove(name string) error {
|
||||
var err error
|
||||
|
@ -27,12 +24,6 @@ func Remove(name string) error {
|
|||
continue
|
||||
}
|
||||
|
||||
if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" {
|
||||
// try again
|
||||
<-time.After(100 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
|
||||
if unwrapped == syscall.ENOENT {
|
||||
// it's already gone
|
||||
return nil
|
||||
|
@ -56,12 +47,6 @@ func RemoveAll(name string) error {
|
|||
continue
|
||||
}
|
||||
|
||||
if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" {
|
||||
// try again
|
||||
<-time.After(100 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
|
||||
if unwrapped == syscall.ENOENT {
|
||||
// it's already gone
|
||||
return nil
|
||||
|
@ -85,12 +70,6 @@ func Rename(oldpath, newpath string) error {
|
|||
continue
|
||||
}
|
||||
|
||||
if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" {
|
||||
// try again
|
||||
<-time.After(100 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
|
||||
if i == 0 && os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue