~ubuntu-branches/ubuntu/utopic/golang/utopic

« back to all changes in this revision

Viewing changes to src/pkg/syscall/creds_test.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 syscall_test
 
8
 
 
9
import (
 
10
        "bytes"
 
11
        "net"
 
12
        "os"
 
13
        "syscall"
 
14
        "testing"
 
15
)
 
16
 
 
17
// TestSCMCredentials tests the sending and receiving of credentials
 
18
// (PID, UID, GID) in an ancillary message between two UNIX
 
19
// sockets. The SO_PASSCRED socket option is enabled on the sending
 
20
// socket for this to work.
 
21
func TestSCMCredentials(t *testing.T) {
 
22
        fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0)
 
23
        if err != nil {
 
24
                t.Fatalf("Socketpair: %v", err)
 
25
        }
 
26
        defer syscall.Close(fds[0])
 
27
        defer syscall.Close(fds[1])
 
28
 
 
29
        err = syscall.SetsockoptInt(fds[0], syscall.SOL_SOCKET, syscall.SO_PASSCRED, 1)
 
30
        if err != nil {
 
31
                t.Fatalf("SetsockoptInt: %v", err)
 
32
        }
 
33
 
 
34
        srvFile := os.NewFile(uintptr(fds[0]), "server")
 
35
        defer srvFile.Close()
 
36
        srv, err := net.FileConn(srvFile)
 
37
        if err != nil {
 
38
                t.Errorf("FileConn: %v", err)
 
39
                return
 
40
        }
 
41
        defer srv.Close()
 
42
 
 
43
        cliFile := os.NewFile(uintptr(fds[1]), "client")
 
44
        defer cliFile.Close()
 
45
        cli, err := net.FileConn(cliFile)
 
46
        if err != nil {
 
47
                t.Errorf("FileConn: %v", err)
 
48
                return
 
49
        }
 
50
        defer cli.Close()
 
51
 
 
52
        var ucred syscall.Ucred
 
53
        if os.Getuid() != 0 {
 
54
                ucred.Pid = int32(os.Getpid())
 
55
                ucred.Uid = 0
 
56
                ucred.Gid = 0
 
57
                oob := syscall.UnixCredentials(&ucred)
 
58
                _, _, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
 
59
                if err.(*net.OpError).Err != syscall.EPERM {
 
60
                        t.Fatalf("WriteMsgUnix failed with %v, want EPERM", err)
 
61
                }
 
62
        }
 
63
 
 
64
        ucred.Pid = int32(os.Getpid())
 
65
        ucred.Uid = uint32(os.Getuid())
 
66
        ucred.Gid = uint32(os.Getgid())
 
67
        oob := syscall.UnixCredentials(&ucred)
 
68
 
 
69
        // this is going to send a dummy byte
 
70
        n, oobn, err := cli.(*net.UnixConn).WriteMsgUnix(nil, oob, nil)
 
71
        if err != nil {
 
72
                t.Fatalf("WriteMsgUnix: %v", err)
 
73
        }
 
74
        if n != 0 {
 
75
                t.Fatalf("WriteMsgUnix n = %d, want 0", n)
 
76
        }
 
77
        if oobn != len(oob) {
 
78
                t.Fatalf("WriteMsgUnix oobn = %d, want %d", oobn, len(oob))
 
79
        }
 
80
 
 
81
        oob2 := make([]byte, 10*len(oob))
 
82
        n, oobn2, flags, _, err := srv.(*net.UnixConn).ReadMsgUnix(nil, oob2)
 
83
        if err != nil {
 
84
                t.Fatalf("ReadMsgUnix: %v", err)
 
85
        }
 
86
        if flags != 0 {
 
87
                t.Fatalf("ReadMsgUnix flags = 0x%x, want 0", flags)
 
88
        }
 
89
        if n != 1 {
 
90
                t.Fatalf("ReadMsgUnix n = %d, want 1 (dummy byte)", n)
 
91
        }
 
92
        if oobn2 != oobn {
 
93
                // without SO_PASSCRED set on the socket, ReadMsgUnix will
 
94
                // return zero oob bytes
 
95
                t.Fatalf("ReadMsgUnix oobn = %d, want %d", oobn2, oobn)
 
96
        }
 
97
        oob2 = oob2[:oobn2]
 
98
        if !bytes.Equal(oob, oob2) {
 
99
                t.Fatal("ReadMsgUnix oob bytes don't match")
 
100
        }
 
101
 
 
102
        scm, err := syscall.ParseSocketControlMessage(oob2)
 
103
        if err != nil {
 
104
                t.Fatalf("ParseSocketControlMessage: %v", err)
 
105
        }
 
106
        newUcred, err := syscall.ParseUnixCredentials(&scm[0])
 
107
        if err != nil {
 
108
                t.Fatalf("ParseUnixCredentials: %v", err)
 
109
        }
 
110
        if *newUcred != ucred {
 
111
                t.Fatalf("ParseUnixCredentials = %+v, want %+v", newUcred, ucred)
 
112
        }
 
113
}