github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/util/peercred_linux.go (about) 1 // Copyright (c) 2015, Kevin Walsh. 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 util 16 17 // This provides a version of UnixConn that can inject and collect out-of-band 18 // data, specifically, credentials and file descriptors. 19 20 import ( 21 "syscall" 22 ) 23 24 // PeerCred retreives the most recently passed peer credential, or nil if no 25 // credentials have been received yet. 26 func (s *OOBUnixConn) PeerCred() *Ucred { 27 s.m.Lock() 28 defer s.m.Unlock() 29 return s.peerCred 30 } 31 32 func (s *OOBUnixConn) Read(p []byte) (n int, err error) { 33 var oob [OOBMaxLength]byte 34 n, oobn, _, _, err := s.ReadMsgUnix(p, oob[:]) 35 if err == nil && n > 0 && oobn > 0 { 36 scm, err := syscall.ParseSocketControlMessage(oob[0:oobn]) 37 if err != nil { 38 return n, err 39 } 40 s.m.Lock() 41 for _, m := range scm { 42 if m.Header.Level != syscall.SOL_SOCKET { 43 continue 44 } 45 switch m.Header.Type { 46 case syscall.SCM_RIGHTS: 47 if fds, err := syscall.ParseUnixRights(&m); err == nil { 48 for _, fd := range fds { 49 // Note: We wrap the raw FDs inside an os.File just 50 // once, early, to prevent double-free or leaking FDs. 51 f := NewFile(fd) 52 s.recvFiles = append(s.recvFiles, f) 53 } 54 } 55 case syscall.SCM_CREDENTIALS: 56 if ucred, err := syscall.ParseUnixCredentials(&m); err == nil { 57 s.peerCred = &Ucred{Uid: ucred.Uid, Gid: ucred.Gid} 58 } 59 } 60 } 61 s.m.Unlock() 62 } 63 return n, err 64 }