git

Форк
0
97 строк · 2.8 Кб
1
// Copyright 2012 Google Inc. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
package main
16

17
import (
18
	"fmt"
19
	"log"
20
	"net"
21
	"os"
22
	"path/filepath"
23
	"syscall"
24
)
25

26
// A Socket is a wrapper around a Unix socket that verifies directory
27
// permissions.
28
type Socket struct {
29
	Dir string
30
}
31

32
func defaultDir() string {
33
	sockPath := ".git-credential-cache"
34
	if home := os.Getenv("HOME"); home != "" {
35
		return filepath.Join(home, sockPath)
36
	}
37
	log.Printf("socket: cannot find HOME path. using relative directory %q for socket", sockPath)
38
	return sockPath
39
}
40

41
// DefaultSocket is a Socket in the $HOME/.git-credential-cache directory.
42
var DefaultSocket = Socket{Dir: defaultDir()}
43

44
// Listen announces the local network address of the unix socket. The
45
// permissions on the socket directory are verified before attempting
46
// the actual listen.
47
func (s Socket) Listen() (net.Listener, error) {
48
	network, addr := "unix", s.Path()
49
	if err := s.mkdir(); err != nil {
50
		return nil, &net.OpError{Op: "listen", Net: network, Addr: &net.UnixAddr{Name: addr, Net: network}, Err: err}
51
	}
52
	return net.Listen(network, addr)
53
}
54

55
// Dial connects to the unix socket. The permissions on the socket directory
56
// are verified before attempting the actual dial.
57
func (s Socket) Dial() (net.Conn, error) {
58
	network, addr := "unix", s.Path()
59
	if err := s.checkPermissions(); err != nil {
60
		return nil, &net.OpError{Op: "dial", Net: network, Addr: &net.UnixAddr{Name: addr, Net: network}, Err: err}
61
	}
62
	return net.Dial(network, addr)
63
}
64

65
// Path returns the fully specified file name of the unix socket.
66
func (s Socket) Path() string {
67
	return filepath.Join(s.Dir, "persistent-https-proxy-socket")
68
}
69

70
func (s Socket) mkdir() error {
71
	if err := s.checkPermissions(); err == nil {
72
		return nil
73
	} else if !os.IsNotExist(err) {
74
		return err
75
	}
76
	if err := os.MkdirAll(s.Dir, 0700); err != nil {
77
		return err
78
	}
79
	return s.checkPermissions()
80
}
81

82
func (s Socket) checkPermissions() error {
83
	fi, err := os.Stat(s.Dir)
84
	if err != nil {
85
		return err
86
	}
87
	if !fi.IsDir() {
88
		return fmt.Errorf("socket: got file, want directory for %q", s.Dir)
89
	}
90
	if fi.Mode().Perm() != 0700 {
91
		return fmt.Errorf("socket: got perm %o, want 700 for %q", fi.Mode().Perm(), s.Dir)
92
	}
93
	if st := fi.Sys().(*syscall.Stat_t); int(st.Uid) != os.Getuid() {
94
		return fmt.Errorf("socket: got uid %d, want %d for %q", st.Uid, os.Getuid(), s.Dir)
95
	}
96
	return nil
97
}
98

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.