ParseRemoteAddr checks if given remote address is valid, and returns composed URL with needed username and password. It also checks if given user has permission when remote address is actually a local path.
(options ParseRemoteAddrOptions)
| 64 | // It also checks if given user has permission when remote address |
| 65 | // is actually a local path. |
| 66 | func ParseRemoteAddr(options ParseRemoteAddrOptions) (string, error) { |
| 67 | remoteAddr := strings.TrimSpace(options.CloneAddr) |
| 68 | |
| 69 | // Remote address can be HTTP/HTTPS/Git URL or local path. |
| 70 | if strings.HasPrefix(remoteAddr, "http://") || |
| 71 | strings.HasPrefix(remoteAddr, "https://") || |
| 72 | strings.HasPrefix(remoteAddr, "git://") { |
| 73 | u, err := url.Parse(remoteAddr) |
| 74 | if err != nil { |
| 75 | return "", database.ErrInvalidCloneAddr{IsURLError: true} |
| 76 | } |
| 77 | |
| 78 | if netutil.IsBlockedLocalHostname(u.Hostname(), conf.Security.LocalNetworkAllowlist) { |
| 79 | return "", database.ErrInvalidCloneAddr{IsBlockedLocalAddress: true} |
| 80 | } |
| 81 | |
| 82 | if len(options.AuthUsername)+len(options.AuthPassword) > 0 { |
| 83 | u.User = url.UserPassword(options.AuthUsername, options.AuthPassword) |
| 84 | } |
| 85 | // To prevent CRLF injection in git protocol, see https://github.com/gogs/gogs/issues/6413 |
| 86 | if u.Scheme == "git" && (strings.Contains(remoteAddr, "%0d") || strings.Contains(remoteAddr, "%0a")) { |
| 87 | return "", database.ErrInvalidCloneAddr{IsURLError: true} |
| 88 | } |
| 89 | remoteAddr = u.String() |
| 90 | } else if !options.User.CanImportLocal() { |
| 91 | return "", database.ErrInvalidCloneAddr{IsPermissionDenied: true} |
| 92 | } else if !com.IsDir(remoteAddr) { |
| 93 | return "", database.ErrInvalidCloneAddr{IsInvalidPath: true} |
| 94 | } |
| 95 | |
| 96 | return remoteAddr, nil |
| 97 | } |
| 98 | |
| 99 | type RepoSetting struct { |
| 100 | RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"` |
no test coverage detected