Skip to content

Commit 50111c7

Browse files
wxiaoguanglunny
andauthored
Refactor legacy strange git operations (#22756)
During the refactoring of the git module, I found there were some strange operations. This PR tries to fix 2 of them 1. The empty argument `--` in repo_attribute.go, which was introduced by #16773. It seems unnecessary because nothing else would be added later. 2. The complex git service logic in repo/http.go. * Before: the `hasAccess` only allow `service == "upload-pack" || service == "receive-pack"` * After: unrelated code is removed. No need to call ToTrustedCmdArgs anymore. Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
1 parent d987ac6 commit 50111c7

File tree

2 files changed

+26
-49
lines changed

2 files changed

+26
-49
lines changed

Diff for: modules/git/repo_attribute.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,7 @@ func (c *CheckAttributeReader) Init(ctx context.Context) error {
135135

136136
c.env = append(c.env, "GIT_FLUSH=1")
137137

138-
// The empty "--" comes from #16773 , and it seems unnecessary because nothing else would be added later.
139-
c.cmd.AddDynamicArguments(c.Attributes...).AddArguments("--")
138+
c.cmd.AddDynamicArguments(c.Attributes...)
140139

141140
var err error
142141

Diff for: routers/web/repo/http.go

+25-47
Original file line numberDiff line numberDiff line change
@@ -424,60 +424,40 @@ func (h *serviceHandler) sendFile(contentType, file string) {
424424
// one or more key=value pairs separated by colons
425425
var safeGitProtocolHeader = regexp.MustCompile(`^[0-9a-zA-Z]+=[0-9a-zA-Z]+(:[0-9a-zA-Z]+=[0-9a-zA-Z]+)*$`)
426426

427-
func getGitConfig(ctx gocontext.Context, option, dir string) string {
428-
out, _, err := git.NewCommand(ctx, "config").AddDynamicArguments(option).RunStdString(&git.RunOpts{Dir: dir})
429-
if err != nil {
430-
log.Error("%v - %s", err, out)
431-
}
432-
return out[0 : len(out)-1]
433-
}
434-
435-
func getConfigSetting(ctx gocontext.Context, service, dir string) bool {
436-
service = strings.ReplaceAll(service, "-", "")
437-
setting := getGitConfig(ctx, "http."+service, dir)
438-
439-
if service == "uploadpack" {
440-
return setting != "false"
441-
}
442-
443-
return setting == "true"
444-
}
445-
446-
func hasAccess(ctx gocontext.Context, service string, h serviceHandler, checkContentType bool) bool {
447-
if checkContentType {
448-
if h.r.Header.Get("Content-Type") != fmt.Sprintf("application/x-git-%s-request", service) {
449-
return false
450-
}
427+
func prepareGitCmdWithAllowedService(service string, h *serviceHandler) (*git.Command, error) {
428+
if service == "receive-pack" && h.cfg.ReceivePack {
429+
return git.NewCommand(h.r.Context(), "receive-pack"), nil
451430
}
452-
453-
if !(service == "upload-pack" || service == "receive-pack") {
454-
return false
455-
}
456-
if service == "receive-pack" {
457-
return h.cfg.ReceivePack
458-
}
459-
if service == "upload-pack" {
460-
return h.cfg.UploadPack
431+
if service == "upload-pack" && h.cfg.UploadPack {
432+
return git.NewCommand(h.r.Context(), "upload-pack"), nil
461433
}
462434

463-
return getConfigSetting(ctx, service, h.dir)
435+
return nil, fmt.Errorf("service %q is not allowed", service)
464436
}
465437

466-
func serviceRPC(ctx gocontext.Context, h serviceHandler, service string) {
438+
func serviceRPC(h *serviceHandler, service string) {
467439
defer func() {
468440
if err := h.r.Body.Close(); err != nil {
469441
log.Error("serviceRPC: Close: %v", err)
470442
}
471443
}()
472444

473-
if !hasAccess(ctx, service, h, true) {
445+
expectedContentType := fmt.Sprintf("application/x-git-%s-request", service)
446+
if h.r.Header.Get("Content-Type") != expectedContentType {
447+
log.Error("Content-Type (%q) doesn't match expected: %q", h.r.Header.Get("Content-Type"), expectedContentType)
448+
h.w.WriteHeader(http.StatusUnauthorized)
449+
return
450+
}
451+
452+
cmd, err := prepareGitCmdWithAllowedService(service, h)
453+
if err != nil {
454+
log.Error("Failed to prepareGitCmdWithService: %v", err)
474455
h.w.WriteHeader(http.StatusUnauthorized)
475456
return
476457
}
477458

478459
h.w.Header().Set("Content-Type", fmt.Sprintf("application/x-git-%s-result", service))
479460

480-
var err error
481461
reqBody := h.r.Body
482462

483463
// Handle GZIP.
@@ -498,8 +478,7 @@ func serviceRPC(ctx gocontext.Context, h serviceHandler, service string) {
498478
}
499479

500480
var stderr bytes.Buffer
501-
// the service is generated by ourselves, so it's safe to trust it
502-
cmd := git.NewCommand(h.r.Context(), git.ToTrustedCmdArgs([]string{service})...).AddArguments("--stateless-rpc").AddDynamicArguments(h.dir)
481+
cmd.AddArguments("--stateless-rpc").AddDynamicArguments(h.dir)
503482
cmd.SetDescription(fmt.Sprintf("%s %s %s [repo_path: %s]", git.GitExecutable, service, "--stateless-rpc", h.dir))
504483
if err := cmd.Run(&git.RunOpts{
505484
Dir: h.dir,
@@ -520,15 +499,15 @@ func serviceRPC(ctx gocontext.Context, h serviceHandler, service string) {
520499
func ServiceUploadPack(ctx *context.Context) {
521500
h := httpBase(ctx)
522501
if h != nil {
523-
serviceRPC(ctx, *h, "upload-pack")
502+
serviceRPC(h, "upload-pack")
524503
}
525504
}
526505

527506
// ServiceReceivePack implements Git Smart HTTP protocol
528507
func ServiceReceivePack(ctx *context.Context) {
529508
h := httpBase(ctx)
530509
if h != nil {
531-
serviceRPC(ctx, *h, "receive-pack")
510+
serviceRPC(h, "receive-pack")
532511
}
533512
}
534513

@@ -537,7 +516,7 @@ func getServiceType(r *http.Request) string {
537516
if !strings.HasPrefix(serviceType, "git-") {
538517
return ""
539518
}
540-
return strings.Replace(serviceType, "git-", "", 1)
519+
return strings.TrimPrefix(serviceType, "git-")
541520
}
542521

543522
func updateServerInfo(ctx gocontext.Context, dir string) []byte {
@@ -563,16 +542,15 @@ func GetInfoRefs(ctx *context.Context) {
563542
return
564543
}
565544
h.setHeaderNoCache()
566-
if hasAccess(ctx, getServiceType(h.r), *h, false) {
567-
service := getServiceType(h.r)
568-
545+
service := getServiceType(h.r)
546+
cmd, err := prepareGitCmdWithAllowedService(service, h)
547+
if err == nil {
569548
if protocol := h.r.Header.Get("Git-Protocol"); protocol != "" && safeGitProtocolHeader.MatchString(protocol) {
570549
h.environ = append(h.environ, "GIT_PROTOCOL="+protocol)
571550
}
572551
h.environ = append(os.Environ(), h.environ...)
573552

574-
// the service is generated by ourselves, so we can trust it
575-
refs, _, err := git.NewCommand(ctx, git.ToTrustedCmdArgs([]string{service})...).AddArguments("--stateless-rpc", "--advertise-refs", ".").RunStdBytes(&git.RunOpts{Env: h.environ, Dir: h.dir})
553+
refs, _, err := cmd.AddArguments("--stateless-rpc", "--advertise-refs", ".").RunStdBytes(&git.RunOpts{Env: h.environ, Dir: h.dir})
576554
if err != nil {
577555
log.Error(fmt.Sprintf("%v - %s", err, string(refs)))
578556
}

0 commit comments

Comments
 (0)