github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/util/oob_unix_conn.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 "errors" 22 "net" 23 "os" 24 "sync" 25 "syscall" 26 ) 27 28 // Error types for the protorpc package. 29 var ( 30 ErrOOBSendFailed = errors.New("error sending out-of-band unix socket data") 31 ErrOOBParseFailed = errors.New("error parsing out-of-band unix socket data") 32 ) 33 34 // Maximum amount of out-of-band data supported. This is enough to send 35 // at least a set of credentials and 3 file descriptors. 36 const OOBMaxLength = 100 // usually under 64 in practice 37 38 // OOBUnixConn provides the same operations as net.UnixConn, plus the ability to 39 // asynchronously make use of the out-of-band mechanism to share file descriptors 40 // and credentials. 41 type OOBUnixConn struct { 42 m sync.Mutex // protects recvFiles, sendFDs, and peerCred 43 recvFiles []*os.File 44 sendFDs []int 45 peerCred *Ucred 46 *net.UnixConn 47 } 48 49 // Ucred holds credentials of a peer process. 50 type Ucred struct { 51 Uid uint32 52 Gid uint32 53 } 54 55 // NewOOBUnixConn returns a new util.OOBUnixConn, which provides the same 56 // operations as net.UnixConn but also allows sharing of file descriptors and 57 // credentials. 58 func NewOOBUnixConn(conn *net.UnixConn) *OOBUnixConn { 59 return &OOBUnixConn{UnixConn: conn} 60 } 61 62 // ShareFDs adds some file descriptors to the list of filescriptors to be 63 // shared during the next Write. 64 func (s *OOBUnixConn) ShareFDs(fd ...int) { 65 s.m.Lock() 66 s.sendFDs = append(s.sendFDs, fd...) 67 s.m.Unlock() 68 } 69 70 // SharedFiles retreives the open files shared during recent Read calls. 71 func (s *OOBUnixConn) SharedFiles() []*os.File { 72 s.m.Lock() 73 fds := s.recvFiles 74 s.recvFiles = nil 75 s.m.Unlock() 76 return fds 77 } 78 79 func (s *OOBUnixConn) Write(buf []byte) (int, error) { 80 var oob []byte 81 s.m.Lock() 82 fds := s.sendFDs 83 s.sendFDs = nil 84 s.m.Unlock() 85 if len(fds) > 0 { 86 oob = syscall.UnixRights(fds...) 87 } 88 n, oobn, err := s.WriteMsgUnix(buf, oob, nil) 89 if err == nil && oobn != len(oob) { 90 err = ErrOOBSendFailed 91 } 92 return n, err 93 }