.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / sys@v0.0.0-20210124154548-22da62e12c0c / unix / creds_test.go
1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // +build linux
6
7 package unix_test
8
9 import (
10         "bytes"
11         "go/build"
12         "net"
13         "os"
14         "testing"
15
16         "golang.org/x/sys/unix"
17 )
18
19 // TestSCMCredentials tests the sending and receiving of credentials
20 // (PID, UID, GID) in an ancillary message between two UNIX
21 // sockets. The SO_PASSCRED socket option is enabled on the sending
22 // socket for this to work.
23 func TestSCMCredentials(t *testing.T) {
24         socketTypeTests := []struct {
25                 socketType int
26                 dataLen    int
27         }{
28                 {
29                         unix.SOCK_STREAM,
30                         1,
31                 }, {
32                         unix.SOCK_DGRAM,
33                         0,
34                 },
35         }
36
37         for _, tt := range socketTypeTests {
38                 if tt.socketType == unix.SOCK_DGRAM && !atLeast1p10() {
39                         t.Log("skipping DGRAM test on pre-1.10")
40                         continue
41                 }
42
43                 fds, err := unix.Socketpair(unix.AF_LOCAL, tt.socketType, 0)
44                 if err != nil {
45                         t.Fatalf("Socketpair: %v", err)
46                 }
47                 defer unix.Close(fds[0])
48                 defer unix.Close(fds[1])
49
50                 err = unix.SetsockoptInt(fds[0], unix.SOL_SOCKET, unix.SO_PASSCRED, 1)
51                 if err != nil {
52                         t.Fatalf("SetsockoptInt: %v", err)
53                 }
54
55                 srvFile := os.NewFile(uintptr(fds[0]), "server")
56                 defer srvFile.Close()
57                 srv, err := net.FileConn(srvFile)
58                 if err != nil {
59                         t.Errorf("FileConn: %v", err)
60                         return
61                 }
62                 defer srv.Close()
63
64                 cliFile := os.NewFile(uintptr(fds[1]), "client")
65                 defer cliFile.Close()
66                 cli, err := net.FileConn(cliFile)
67                 if err != nil {
68                         t.Errorf("FileConn: %v", err)
69                         return
70                 }
71                 defer cli.Close()
72
73                 var ucred unix.Ucred
74                 ucred.Pid = int32(os.Getpid())
75                 ucred.Uid = uint32(os.Getuid())
76                 ucred.Gid = uint32(os.Getgid())
77                 oob := unix.UnixCredentials(&ucred)
78
79                 // On SOCK_STREAM, this is internally going to send a dummy byte
80                 n, oobn, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
81                 if err != nil {
82                         t.Fatalf("WriteMsgUnix: %v", err)
83                 }
84                 if n != 0 {
85                         t.Fatalf("WriteMsgUnix n = %d, want 0", n)
86                 }
87                 if oobn != len(oob) {
88                         t.Fatalf("WriteMsgUnix oobn = %d, want %d", oobn, len(oob))
89                 }
90
91                 oob2 := make([]byte, 10*len(oob))
92                 n, oobn2, flags, _, err := srv.(*net.UnixConn).ReadMsgUnix(nil, oob2)
93                 if err != nil {
94                         t.Fatalf("ReadMsgUnix: %v", err)
95                 }
96                 if flags != 0 {
97                         t.Fatalf("ReadMsgUnix flags = 0x%x, want 0", flags)
98                 }
99                 if n != tt.dataLen {
100                         t.Fatalf("ReadMsgUnix n = %d, want %d", n, tt.dataLen)
101                 }
102                 if oobn2 != oobn {
103                         // without SO_PASSCRED set on the socket, ReadMsgUnix will
104                         // return zero oob bytes
105                         t.Fatalf("ReadMsgUnix oobn = %d, want %d", oobn2, oobn)
106                 }
107                 oob2 = oob2[:oobn2]
108                 if !bytes.Equal(oob, oob2) {
109                         t.Fatal("ReadMsgUnix oob bytes don't match")
110                 }
111
112                 scm, err := unix.ParseSocketControlMessage(oob2)
113                 if err != nil {
114                         t.Fatalf("ParseSocketControlMessage: %v", err)
115                 }
116                 newUcred, err := unix.ParseUnixCredentials(&scm[0])
117                 if err != nil {
118                         t.Fatalf("ParseUnixCredentials: %v", err)
119                 }
120                 if *newUcred != ucred {
121                         t.Fatalf("ParseUnixCredentials = %+v, want %+v", newUcred, ucred)
122                 }
123         }
124 }
125
126 // atLeast1p10 reports whether we are running on Go 1.10 or later.
127 func atLeast1p10() bool {
128         for _, ver := range build.Default.ReleaseTags {
129                 if ver == "go1.10" {
130                         return true
131                 }
132         }
133         return false
134 }