diff --git a/routers/api/v1/repo/mirror.go b/routers/api/v1/repo/mirror.go index ae727fdbae..11b026abb7 100644 --- a/routers/api/v1/repo/mirror.go +++ b/routers/api/v1/repo/mirror.go @@ -363,7 +363,7 @@ func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirro address, err := forms.ParseRemoteAddr(mirrorOption.RemoteAddress, mirrorOption.RemoteUsername, mirrorOption.RemotePassword) if err == nil { - err = migrations.IsMigrateURLAllowed(address, ctx.ContextUser) + err = migrations.IsPushMirrorURLAllowed(address, ctx.ContextUser) } if err != nil { HandleRemoteAddressError(ctx, err) diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go index 2c6ca77a6a..df7e388680 100644 --- a/routers/web/repo/setting/setting.go +++ b/routers/web/repo/setting/setting.go @@ -651,7 +651,7 @@ func SettingsPost(ctx *context.Context) { address, err := forms.ParseRemoteAddr(form.PushMirrorAddress, form.PushMirrorUsername, form.PushMirrorPassword) if err == nil { - err = migrations.IsMigrateURLAllowed(address, ctx.Doer) + err = migrations.IsPushMirrorURLAllowed(address, ctx.Doer) } if err != nil { ctx.Data["Err_PushMirrorAddress"] = true diff --git a/services/migrations/migrate.go b/services/migrations/migrate.go index 29b815d521..ccb9cb7e98 100644 --- a/services/migrations/migrate.go +++ b/services/migrations/migrate.go @@ -39,8 +39,17 @@ func RegisterDownloaderFactory(factory base.DownloaderFactory) { factories = append(factories, factory) } -// IsMigrateURLAllowed checks if an URL is allowed to be migrated from +// IsPushMirrorURLAllowed checks if an URL is allowed to be pushed to. +func IsPushMirrorURLAllowed(remoteURL string, doer *user_model.User) error { + return isURLAllowed(remoteURL, doer, true) +} + +// IsMigrateURLAllowed checks if an URL is allowed to be migrated from. func IsMigrateURLAllowed(remoteURL string, doer *user_model.User) error { + return isURLAllowed(remoteURL, doer, false) +} + +func isURLAllowed(remoteURL string, doer *user_model.User, isPushMirror bool) error { // Remote address can be HTTP/HTTPS/Git URL or local path. u, err := url.Parse(remoteURL) if err != nil { @@ -71,7 +80,7 @@ func IsMigrateURLAllowed(remoteURL string, doer *user_model.User) error { return &models.ErrInvalidCloneAddr{Host: u.Host, IsURLError: true} } - if u.Opaque != "" || u.Scheme != "" && u.Scheme != "http" && u.Scheme != "https" && u.Scheme != "git" && u.Scheme != "ssh" { + if u.Opaque != "" || u.Scheme != "" && u.Scheme != "http" && u.Scheme != "https" && u.Scheme != "git" && u.Scheme != "ssh" || (!isPushMirror && u.Scheme == "ssh") { return &models.ErrInvalidCloneAddr{Host: u.Host, IsProtocolInvalid: true, IsPermissionDenied: true, IsURLError: true} } diff --git a/services/migrations/migrate_test.go b/services/migrations/migrate_test.go index 109a092796..6e45cbd906 100644 --- a/services/migrations/migrate_test.go +++ b/services/migrations/migrate_test.go @@ -113,3 +113,18 @@ func TestAllowBlockList(t *testing.T) { // reset init("", "", false) } + +func TestURLAllowedSSH(t *testing.T) { + require.NoError(t, unittest.PrepareTestDatabase()) + + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"}) + sshURL := "ssh://git@git.gay/gitgay/forgejo" + + t.Run("Migrate URL", func(t *testing.T) { + require.Error(t, IsMigrateURLAllowed(sshURL, user)) + }) + + t.Run("Pushmirror URL", func(t *testing.T) { + require.NoError(t, IsPushMirrorURLAllowed(sshURL, user)) + }) +}