vendor: pull in requirements for docker/pkg/listeners
Since we're using the docker "library" for socket activation (and dealing with sockets in general), we need to vendor the requirements for the library. Also, include go-winio even though Windows isn't a supported target at the moment. Signed-off-by: Aleksa Sarai <asarai@suse.de>
This commit is contained in:
		
							parent
							
								
									e8b33495f2
								
							
						
					
					
						commit
						20ef099321
					
				
					 36 changed files with 3169 additions and 23 deletions
				
			
		|  | @ -9,7 +9,7 @@ clone git github.com/cloudfoundry/gosigar 3ed7c74352dae6dc00bdc8c74045375352e3ec | |||
| clone git github.com/codegangsta/cli 9fec0fad02befc9209347cc6d620e68e1b45f74d | ||||
| clone git github.com/coreos/go-systemd 7b2428fec40033549c68f54e26e89e7ca9a9ce31 | ||||
| clone git github.com/cyberdelia/go-metrics-graphite 7e54b5c2aa6eaff4286c44129c3def899dff528c | ||||
| clone git github.com/docker/docker 9ff767bcc06c924fd669d881a34847aa4fbaab5e | ||||
| clone git github.com/docker/docker f3dcc1c46249ffc4a73ab2005d1ad011dff3c7df | ||||
| clone git github.com/docker/go-units 5d2041e26a699eaca682e2ea41c8f891e1060444 | ||||
| clone git github.com/godbus/dbus e2cf28118e66a6a63db46cf6088a35d2054d3bb0 | ||||
| clone git github.com/golang/glog 23def4e6c14b4da8ac2ed8007337bc5eb5007998 | ||||
|  | @ -28,4 +28,8 @@ clone git github.com/seccomp/libseccomp-golang 1b506fc7c24eec5a3693cdcbed40d9c22 | |||
| clone git github.com/vdemeester/shakers 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3 | ||||
| clone git github.com/go-check/check a625211d932a2a643d0d17352095f03fb7774663 https://github.com/cpuguy83/check.git | ||||
| 
 | ||||
| # dependencies of docker/pkg/listeners | ||||
| clone git github.com/docker/go-connections v0.2.0 | ||||
| clone git github.com/Microsoft/go-winio v0.3.2 | ||||
| 
 | ||||
| clean | ||||
|  |  | |||
							
								
								
									
										1
									
								
								vendor/src/github.com/Microsoft/go-winio/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/src/github.com/Microsoft/go-winio/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| *.exe | ||||
							
								
								
									
										22
									
								
								vendor/src/github.com/Microsoft/go-winio/LICENSE
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vendor/src/github.com/Microsoft/go-winio/LICENSE
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| The MIT License (MIT) | ||||
| 
 | ||||
| Copyright (c) 2015 Microsoft | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
| 
 | ||||
							
								
								
									
										15
									
								
								vendor/src/github.com/Microsoft/go-winio/README.md
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/src/github.com/Microsoft/go-winio/README.md
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| # go-winio | ||||
| 
 | ||||
| This repository contains utilities for efficiently performing Win32 IO operations in  | ||||
| Go. Currently, this is focused on accessing named pipes and other file handles, and | ||||
| for using named pipes as a net transport. | ||||
| 
 | ||||
| This code relies on IO completion ports to avoid blocking IO on system threads, allowing Go  | ||||
| to reuse the thread to schedule another goroutine. This limits support to Windows Vista and  | ||||
| newer operating systems. This is similar to the implementation of network sockets in Go's net | ||||
| package. | ||||
| 
 | ||||
| Please see the LICENSE file for licensing information. | ||||
| 
 | ||||
| Thanks to natefinch for the inspiration for this library. See https://github.com/natefinch/npipe  | ||||
| for another named pipe implementation. | ||||
							
								
								
									
										27
									
								
								vendor/src/github.com/Microsoft/go-winio/archive/tar/LICENSE
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/src/github.com/Microsoft/go-winio/archive/tar/LICENSE
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | |||
| Copyright (c) 2012 The Go Authors. All rights reserved. | ||||
| 
 | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are | ||||
| met: | ||||
| 
 | ||||
|    * Redistributions of source code must retain the above copyright | ||||
| notice, this list of conditions and the following disclaimer. | ||||
|    * Redistributions in binary form must reproduce the above | ||||
| copyright notice, this list of conditions and the following disclaimer | ||||
| in the documentation and/or other materials provided with the | ||||
| distribution. | ||||
|    * Neither the name of Google Inc. nor the names of its | ||||
| contributors may be used to endorse or promote products derived from | ||||
| this software without specific prior written permission. | ||||
| 
 | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
							
								
								
									
										266
									
								
								vendor/src/github.com/Microsoft/go-winio/backup.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										266
									
								
								vendor/src/github.com/Microsoft/go-winio/backup.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,266 @@ | |||
| package winio | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/binary" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"runtime" | ||||
| 	"syscall" | ||||
| 	"unicode/utf16" | ||||
| ) | ||||
| 
 | ||||
| //sys backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupRead | ||||
| //sys backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupWrite | ||||
| 
 | ||||
| const ( | ||||
| 	BackupData = uint32(iota + 1) | ||||
| 	BackupEaData | ||||
| 	BackupSecurity | ||||
| 	BackupAlternateData | ||||
| 	BackupLink | ||||
| 	BackupPropertyData | ||||
| 	BackupObjectId | ||||
| 	BackupReparseData | ||||
| 	BackupSparseBlock | ||||
| 	BackupTxfsData | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	StreamSparseAttributes = uint32(8) | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	WRITE_DAC              = 0x40000 | ||||
| 	WRITE_OWNER            = 0x80000 | ||||
| 	ACCESS_SYSTEM_SECURITY = 0x1000000 | ||||
| ) | ||||
| 
 | ||||
| // BackupHeader represents a backup stream of a file. | ||||
| type BackupHeader struct { | ||||
| 	Id         uint32 // The backup stream ID | ||||
| 	Attributes uint32 // Stream attributes | ||||
| 	Size       int64  // The size of the stream in bytes | ||||
| 	Name       string // The name of the stream (for BackupAlternateData only). | ||||
| 	Offset     int64  // The offset of the stream in the file (for BackupSparseBlock only). | ||||
| } | ||||
| 
 | ||||
| type win32StreamId struct { | ||||
| 	StreamId   uint32 | ||||
| 	Attributes uint32 | ||||
| 	Size       uint64 | ||||
| 	NameSize   uint32 | ||||
| } | ||||
| 
 | ||||
| // BackupStreamReader reads from a stream produced by the BackupRead Win32 API and produces a series | ||||
| // of BackupHeader values. | ||||
| type BackupStreamReader struct { | ||||
| 	r         io.Reader | ||||
| 	bytesLeft int64 | ||||
| } | ||||
| 
 | ||||
| // NewBackupStreamReader produces a BackupStreamReader from any io.Reader. | ||||
| func NewBackupStreamReader(r io.Reader) *BackupStreamReader { | ||||
| 	return &BackupStreamReader{r, 0} | ||||
| } | ||||
| 
 | ||||
| // Next returns the next backup stream and prepares for calls to Write(). It skips the remainder of the current stream if | ||||
| // it was not completely read. | ||||
| func (r *BackupStreamReader) Next() (*BackupHeader, error) { | ||||
| 	if r.bytesLeft > 0 { | ||||
| 		if _, err := io.Copy(ioutil.Discard, r); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
| 	var wsi win32StreamId | ||||
| 	if err := binary.Read(r.r, binary.LittleEndian, &wsi); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	hdr := &BackupHeader{ | ||||
| 		Id:         wsi.StreamId, | ||||
| 		Attributes: wsi.Attributes, | ||||
| 		Size:       int64(wsi.Size), | ||||
| 	} | ||||
| 	if wsi.NameSize != 0 { | ||||
| 		name := make([]uint16, int(wsi.NameSize/2)) | ||||
| 		if err := binary.Read(r.r, binary.LittleEndian, name); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		hdr.Name = syscall.UTF16ToString(name) | ||||
| 	} | ||||
| 	if wsi.StreamId == BackupSparseBlock { | ||||
| 		if err := binary.Read(r.r, binary.LittleEndian, &hdr.Offset); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		hdr.Size -= 8 | ||||
| 	} | ||||
| 	r.bytesLeft = hdr.Size | ||||
| 	return hdr, nil | ||||
| } | ||||
| 
 | ||||
| // Read reads from the current backup stream. | ||||
| func (r *BackupStreamReader) Read(b []byte) (int, error) { | ||||
| 	if r.bytesLeft == 0 { | ||||
| 		return 0, io.EOF | ||||
| 	} | ||||
| 	if int64(len(b)) > r.bytesLeft { | ||||
| 		b = b[:r.bytesLeft] | ||||
| 	} | ||||
| 	n, err := r.r.Read(b) | ||||
| 	r.bytesLeft -= int64(n) | ||||
| 	if err == io.EOF { | ||||
| 		err = io.ErrUnexpectedEOF | ||||
| 	} else if r.bytesLeft == 0 && err == nil { | ||||
| 		err = io.EOF | ||||
| 	} | ||||
| 	return n, err | ||||
| } | ||||
| 
 | ||||
| // BackupStreamWriter writes a stream compatible with the BackupWrite Win32 API. | ||||
| type BackupStreamWriter struct { | ||||
| 	w         io.Writer | ||||
| 	bytesLeft int64 | ||||
| } | ||||
| 
 | ||||
| // NewBackupStreamWriter produces a BackupStreamWriter on top of an io.Writer. | ||||
| func NewBackupStreamWriter(w io.Writer) *BackupStreamWriter { | ||||
| 	return &BackupStreamWriter{w, 0} | ||||
| } | ||||
| 
 | ||||
| // WriteHeader writes the next backup stream header and prepares for calls to Write(). | ||||
| func (w *BackupStreamWriter) WriteHeader(hdr *BackupHeader) error { | ||||
| 	if w.bytesLeft != 0 { | ||||
| 		return fmt.Errorf("missing %d bytes", w.bytesLeft) | ||||
| 	} | ||||
| 	name := utf16.Encode([]rune(hdr.Name)) | ||||
| 	wsi := win32StreamId{ | ||||
| 		StreamId:   hdr.Id, | ||||
| 		Attributes: hdr.Attributes, | ||||
| 		Size:       uint64(hdr.Size), | ||||
| 		NameSize:   uint32(len(name) * 2), | ||||
| 	} | ||||
| 	if hdr.Id == BackupSparseBlock { | ||||
| 		// Include space for the int64 block offset | ||||
| 		wsi.Size += 8 | ||||
| 	} | ||||
| 	if err := binary.Write(w.w, binary.LittleEndian, &wsi); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if len(name) != 0 { | ||||
| 		if err := binary.Write(w.w, binary.LittleEndian, name); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	if hdr.Id == BackupSparseBlock { | ||||
| 		if err := binary.Write(w.w, binary.LittleEndian, hdr.Offset); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	w.bytesLeft = hdr.Size | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // Write writes to the current backup stream. | ||||
| func (w *BackupStreamWriter) Write(b []byte) (int, error) { | ||||
| 	if w.bytesLeft < int64(len(b)) { | ||||
| 		return 0, fmt.Errorf("too many bytes by %d", int64(len(b))-w.bytesLeft) | ||||
| 	} | ||||
| 	n, err := w.w.Write(b) | ||||
| 	w.bytesLeft -= int64(n) | ||||
| 	return n, err | ||||
| } | ||||
| 
 | ||||
| // BackupFileReader provides an io.ReadCloser interface on top of the BackupRead Win32 API. | ||||
| type BackupFileReader struct { | ||||
| 	f               *os.File | ||||
| 	includeSecurity bool | ||||
| 	ctx             uintptr | ||||
| } | ||||
| 
 | ||||
| // NewBackupFileReader returns a new BackupFileReader from a file handle. If includeSecurity is true, | ||||
| // Read will attempt to read the security descriptor of the file. | ||||
| func NewBackupFileReader(f *os.File, includeSecurity bool) *BackupFileReader { | ||||
| 	r := &BackupFileReader{f, includeSecurity, 0} | ||||
| 	runtime.SetFinalizer(r, func(r *BackupFileReader) { r.Close() }) | ||||
| 	return r | ||||
| } | ||||
| 
 | ||||
| // Read reads a backup stream from the file by calling the Win32 API BackupRead(). | ||||
| func (r *BackupFileReader) Read(b []byte) (int, error) { | ||||
| 	var bytesRead uint32 | ||||
| 	err := backupRead(syscall.Handle(r.f.Fd()), b, &bytesRead, false, r.includeSecurity, &r.ctx) | ||||
| 	if err != nil { | ||||
| 		return 0, &os.PathError{"BackupRead", r.f.Name(), err} | ||||
| 	} | ||||
| 	if bytesRead == 0 { | ||||
| 		return 0, io.EOF | ||||
| 	} | ||||
| 	return int(bytesRead), nil | ||||
| } | ||||
| 
 | ||||
| // Close frees Win32 resources associated with the BackupFileReader. It does not close | ||||
| // the underlying file. | ||||
| func (r *BackupFileReader) Close() error { | ||||
| 	if r.ctx != 0 { | ||||
| 		backupRead(syscall.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx) | ||||
| 		r.ctx = 0 | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // BackupFileWriter provides an io.WriteCloser interface on top of the BackupWrite Win32 API. | ||||
| type BackupFileWriter struct { | ||||
| 	f               *os.File | ||||
| 	includeSecurity bool | ||||
| 	ctx             uintptr | ||||
| } | ||||
| 
 | ||||
| // NewBackupFileWrtier returns a new BackupFileWriter from a file handle. If includeSecurity is true, | ||||
| // Write() will attempt to restore the security descriptor from the stream. | ||||
| func NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter { | ||||
| 	w := &BackupFileWriter{f, includeSecurity, 0} | ||||
| 	runtime.SetFinalizer(w, func(w *BackupFileWriter) { w.Close() }) | ||||
| 	return w | ||||
| } | ||||
| 
 | ||||
| // Write restores a portion of the file using the provided backup stream. | ||||
| func (w *BackupFileWriter) Write(b []byte) (int, error) { | ||||
| 	var bytesWritten uint32 | ||||
| 	err := backupWrite(syscall.Handle(w.f.Fd()), b, &bytesWritten, false, w.includeSecurity, &w.ctx) | ||||
| 	if err != nil { | ||||
| 		return 0, &os.PathError{"BackupWrite", w.f.Name(), err} | ||||
| 	} | ||||
| 	if int(bytesWritten) != len(b) { | ||||
| 		return int(bytesWritten), errors.New("not all bytes could be written") | ||||
| 	} | ||||
| 	return len(b), nil | ||||
| } | ||||
| 
 | ||||
| // Close frees Win32 resources associated with the BackupFileWriter. It does not | ||||
| // close the underlying file. | ||||
| func (w *BackupFileWriter) Close() error { | ||||
| 	if w.ctx != 0 { | ||||
| 		backupWrite(syscall.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx) | ||||
| 		w.ctx = 0 | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // OpenForBackup opens a file or directory, potentially skipping access checks if the backup | ||||
| // or restore privileges have been acquired. | ||||
| // | ||||
| // If the file opened was a directory, it cannot be used with Readdir(). | ||||
| func OpenForBackup(path string, access uint32, share uint32, createmode uint32) (*os.File, error) { | ||||
| 	winPath, err := syscall.UTF16FromString(path) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	h, err := syscall.CreateFile(&winPath[0], access, share, nil, createmode, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0) | ||||
| 	if err != nil { | ||||
| 		err = &os.PathError{Op: "open", Path: path, Err: err} | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return os.NewFile(uintptr(h), path), nil | ||||
| } | ||||
							
								
								
									
										219
									
								
								vendor/src/github.com/Microsoft/go-winio/file.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										219
									
								
								vendor/src/github.com/Microsoft/go-winio/file.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,219 @@ | |||
| package winio | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"io" | ||||
| 	"runtime" | ||||
| 	"sync" | ||||
| 	"syscall" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| //sys cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) = CancelIoEx | ||||
| //sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort | ||||
| //sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus | ||||
| //sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes | ||||
| //sys timeBeginPeriod(period uint32) (n int32) = winmm.timeBeginPeriod | ||||
| 
 | ||||
| const ( | ||||
| 	cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1 | ||||
| 	cFILE_SKIP_SET_EVENT_ON_HANDLE        = 2 | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	ErrFileClosed = errors.New("file has already been closed") | ||||
| 	ErrTimeout    = &timeoutError{} | ||||
| ) | ||||
| 
 | ||||
| type timeoutError struct{} | ||||
| 
 | ||||
| func (e *timeoutError) Error() string   { return "i/o timeout" } | ||||
| func (e *timeoutError) Timeout() bool   { return true } | ||||
| func (e *timeoutError) Temporary() bool { return true } | ||||
| 
 | ||||
| var ioInitOnce sync.Once | ||||
| var ioCompletionPort syscall.Handle | ||||
| 
 | ||||
| // ioResult contains the result of an asynchronous IO operation | ||||
| type ioResult struct { | ||||
| 	bytes uint32 | ||||
| 	err   error | ||||
| } | ||||
| 
 | ||||
| // ioOperation represents an outstanding asynchronous Win32 IO | ||||
| type ioOperation struct { | ||||
| 	o  syscall.Overlapped | ||||
| 	ch chan ioResult | ||||
| } | ||||
| 
 | ||||
| func initIo() { | ||||
| 	h, err := createIoCompletionPort(syscall.InvalidHandle, 0, 0, 0xffffffff) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	ioCompletionPort = h | ||||
| 	go ioCompletionProcessor(h) | ||||
| } | ||||
| 
 | ||||
| // win32File implements Reader, Writer, and Closer on a Win32 handle without blocking in a syscall. | ||||
| // It takes ownership of this handle and will close it if it is garbage collected. | ||||
| type win32File struct { | ||||
| 	handle        syscall.Handle | ||||
| 	wg            sync.WaitGroup | ||||
| 	closing       bool | ||||
| 	readDeadline  time.Time | ||||
| 	writeDeadline time.Time | ||||
| } | ||||
| 
 | ||||
| // makeWin32File makes a new win32File from an existing file handle | ||||
| func makeWin32File(h syscall.Handle) (*win32File, error) { | ||||
| 	f := &win32File{handle: h} | ||||
| 	ioInitOnce.Do(initIo) | ||||
| 	_, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	err = setFileCompletionNotificationModes(h, cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS|cFILE_SKIP_SET_EVENT_ON_HANDLE) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	runtime.SetFinalizer(f, (*win32File).closeHandle) | ||||
| 	return f, nil | ||||
| } | ||||
| 
 | ||||
| func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) { | ||||
| 	return makeWin32File(h) | ||||
| } | ||||
| 
 | ||||
| // closeHandle closes the resources associated with a Win32 handle | ||||
| func (f *win32File) closeHandle() { | ||||
| 	if !f.closing { | ||||
| 		// cancel all IO and wait for it to complete | ||||
| 		f.closing = true | ||||
| 		cancelIoEx(f.handle, nil) | ||||
| 		f.wg.Wait() | ||||
| 		// at this point, no new IO can start | ||||
| 		syscall.Close(f.handle) | ||||
| 		f.handle = 0 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Close closes a win32File. | ||||
| func (f *win32File) Close() error { | ||||
| 	f.closeHandle() | ||||
| 	runtime.SetFinalizer(f, nil) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // prepareIo prepares for a new IO operation | ||||
| func (f *win32File) prepareIo() (*ioOperation, error) { | ||||
| 	f.wg.Add(1) | ||||
| 	if f.closing { | ||||
| 		return nil, ErrFileClosed | ||||
| 	} | ||||
| 	c := &ioOperation{} | ||||
| 	c.ch = make(chan ioResult) | ||||
| 	return c, nil | ||||
| } | ||||
| 
 | ||||
| // ioCompletionProcessor processes completed async IOs forever | ||||
| func ioCompletionProcessor(h syscall.Handle) { | ||||
| 	// Set the timer resolution to 1. This fixes a performance regression in golang 1.6. | ||||
| 	timeBeginPeriod(1) | ||||
| 	for { | ||||
| 		var bytes uint32 | ||||
| 		var key uintptr | ||||
| 		var op *ioOperation | ||||
| 		err := getQueuedCompletionStatus(h, &bytes, &key, &op, syscall.INFINITE) | ||||
| 		if op == nil { | ||||
| 			panic(err) | ||||
| 		} | ||||
| 		op.ch <- ioResult{bytes, err} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // asyncIo processes the return value from ReadFile or WriteFile, blocking until | ||||
| // the operation has actually completed. | ||||
| func (f *win32File) asyncIo(c *ioOperation, deadline time.Time, bytes uint32, err error) (int, error) { | ||||
| 	if err != syscall.ERROR_IO_PENDING { | ||||
| 		f.wg.Done() | ||||
| 		return int(bytes), err | ||||
| 	} else { | ||||
| 		var r ioResult | ||||
| 		wait := true | ||||
| 		timedout := false | ||||
| 		if f.closing { | ||||
| 			cancelIoEx(f.handle, &c.o) | ||||
| 		} else if !deadline.IsZero() { | ||||
| 			now := time.Now() | ||||
| 			if !deadline.After(now) { | ||||
| 				timedout = true | ||||
| 			} else { | ||||
| 				timeout := time.After(deadline.Sub(now)) | ||||
| 				select { | ||||
| 				case r = <-c.ch: | ||||
| 					wait = false | ||||
| 				case <-timeout: | ||||
| 					timedout = true | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		if timedout { | ||||
| 			cancelIoEx(f.handle, &c.o) | ||||
| 		} | ||||
| 		if wait { | ||||
| 			r = <-c.ch | ||||
| 		} | ||||
| 		err = r.err | ||||
| 		if err == syscall.ERROR_OPERATION_ABORTED { | ||||
| 			if f.closing { | ||||
| 				err = ErrFileClosed | ||||
| 			} else if timedout { | ||||
| 				err = ErrTimeout | ||||
| 			} | ||||
| 		} | ||||
| 		f.wg.Done() | ||||
| 		return int(r.bytes), err | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Read reads from a file handle. | ||||
| func (f *win32File) Read(b []byte) (int, error) { | ||||
| 	c, err := f.prepareIo() | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	var bytes uint32 | ||||
| 	err = syscall.ReadFile(f.handle, b, &bytes, &c.o) | ||||
| 	n, err := f.asyncIo(c, f.readDeadline, bytes, err) | ||||
| 
 | ||||
| 	// Handle EOF conditions. | ||||
| 	if err == nil && n == 0 && len(b) != 0 { | ||||
| 		return 0, io.EOF | ||||
| 	} else if err == syscall.ERROR_BROKEN_PIPE { | ||||
| 		return 0, io.EOF | ||||
| 	} else { | ||||
| 		return n, err | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Write writes to a file handle. | ||||
| func (f *win32File) Write(b []byte) (int, error) { | ||||
| 	c, err := f.prepareIo() | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	var bytes uint32 | ||||
| 	err = syscall.WriteFile(f.handle, b, &bytes, &c.o) | ||||
| 	return f.asyncIo(c, f.writeDeadline, bytes, err) | ||||
| } | ||||
| 
 | ||||
| func (f *win32File) SetReadDeadline(t time.Time) error { | ||||
| 	f.readDeadline = t | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (f *win32File) SetWriteDeadline(t time.Time) error { | ||||
| 	f.writeDeadline = t | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										54
									
								
								vendor/src/github.com/Microsoft/go-winio/fileinfo.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								vendor/src/github.com/Microsoft/go-winio/fileinfo.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,54 @@ | |||
| package winio | ||||
| 
 | ||||
| import ( | ||||
| 	"os" | ||||
| 	"syscall" | ||||
| 	"unsafe" | ||||
| ) | ||||
| 
 | ||||
| //sys getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = GetFileInformationByHandleEx | ||||
| //sys setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) = SetFileInformationByHandle | ||||
| 
 | ||||
| const ( | ||||
| 	fileBasicInfo = 0 | ||||
| 	fileIDInfo    = 0x12 | ||||
| ) | ||||
| 
 | ||||
| // FileBasicInfo contains file access time and file attributes information. | ||||
| type FileBasicInfo struct { | ||||
| 	CreationTime, LastAccessTime, LastWriteTime, ChangeTime syscall.Filetime | ||||
| 	FileAttributes                                          uintptr // includes padding | ||||
| } | ||||
| 
 | ||||
| // GetFileBasicInfo retrieves times and attributes for a file. | ||||
| func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) { | ||||
| 	bi := &FileBasicInfo{} | ||||
| 	if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil { | ||||
| 		return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err} | ||||
| 	} | ||||
| 	return bi, nil | ||||
| } | ||||
| 
 | ||||
| // SetFileBasicInfo sets times and attributes for a file. | ||||
| func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error { | ||||
| 	if err := setFileInformationByHandle(syscall.Handle(f.Fd()), fileBasicInfo, (*byte)(unsafe.Pointer(bi)), uint32(unsafe.Sizeof(*bi))); err != nil { | ||||
| 		return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // FileIDInfo contains the volume serial number and file ID for a file. This pair should be | ||||
| // unique on a system. | ||||
| type FileIDInfo struct { | ||||
| 	VolumeSerialNumber uint64 | ||||
| 	FileID             [16]byte | ||||
| } | ||||
| 
 | ||||
| // GetFileID retrieves the unique (volume, file ID) pair for a file. | ||||
| func GetFileID(f *os.File) (*FileIDInfo, error) { | ||||
| 	fileID := &FileIDInfo{} | ||||
| 	if err := getFileInformationByHandleEx(syscall.Handle(f.Fd()), fileIDInfo, (*byte)(unsafe.Pointer(fileID)), uint32(unsafe.Sizeof(*fileID))); err != nil { | ||||
| 		return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err} | ||||
| 	} | ||||
| 	return fileID, nil | ||||
| } | ||||
							
								
								
									
										398
									
								
								vendor/src/github.com/Microsoft/go-winio/pipe.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										398
									
								
								vendor/src/github.com/Microsoft/go-winio/pipe.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,398 @@ | |||
| package winio | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"io" | ||||
| 	"net" | ||||
| 	"os" | ||||
| 	"syscall" | ||||
| 	"time" | ||||
| 	"unsafe" | ||||
| ) | ||||
| 
 | ||||
| //sys connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) = ConnectNamedPipe | ||||
| //sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error)  [failretval==syscall.InvalidHandle] = CreateNamedPipeW | ||||
| //sys createFile(name string, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateFileW | ||||
| //sys waitNamedPipe(name string, timeout uint32) (err error) = WaitNamedPipeW | ||||
| //sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo | ||||
| //sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW | ||||
| 
 | ||||
| type securityAttributes struct { | ||||
| 	Length             uint32 | ||||
| 	SecurityDescriptor *byte | ||||
| 	InheritHandle      uint32 | ||||
| } | ||||
| 
 | ||||
| const ( | ||||
| 	cERROR_PIPE_BUSY      = syscall.Errno(231) | ||||
| 	cERROR_PIPE_CONNECTED = syscall.Errno(535) | ||||
| 	cERROR_SEM_TIMEOUT    = syscall.Errno(121) | ||||
| 
 | ||||
| 	cPIPE_ACCESS_DUPLEX            = 0x3 | ||||
| 	cFILE_FLAG_FIRST_PIPE_INSTANCE = 0x80000 | ||||
| 	cSECURITY_SQOS_PRESENT         = 0x100000 | ||||
| 	cSECURITY_ANONYMOUS            = 0 | ||||
| 
 | ||||
| 	cPIPE_REJECT_REMOTE_CLIENTS = 0x8 | ||||
| 
 | ||||
| 	cPIPE_UNLIMITED_INSTANCES = 255 | ||||
| 
 | ||||
| 	cNMPWAIT_USE_DEFAULT_WAIT = 0 | ||||
| 	cNMPWAIT_NOWAIT           = 1 | ||||
| 
 | ||||
| 	cPIPE_TYPE_MESSAGE = 4 | ||||
| 
 | ||||
| 	cPIPE_READMODE_MESSAGE = 2 | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	// ErrPipeListenerClosed is returned for pipe operations on listeners that have been closed. | ||||
| 	// This error should match net.errClosing since docker takes a dependency on its text. | ||||
| 	ErrPipeListenerClosed = errors.New("use of closed network connection") | ||||
| 
 | ||||
| 	errPipeWriteClosed = errors.New("pipe has been closed for write") | ||||
| ) | ||||
| 
 | ||||
| type win32Pipe struct { | ||||
| 	*win32File | ||||
| 	path string | ||||
| } | ||||
| 
 | ||||
| type win32MessageBytePipe struct { | ||||
| 	win32Pipe | ||||
| 	writeClosed bool | ||||
| 	readEOF     bool | ||||
| } | ||||
| 
 | ||||
| type pipeAddress string | ||||
| 
 | ||||
| func (f *win32Pipe) LocalAddr() net.Addr { | ||||
| 	return pipeAddress(f.path) | ||||
| } | ||||
| 
 | ||||
| func (f *win32Pipe) RemoteAddr() net.Addr { | ||||
| 	return pipeAddress(f.path) | ||||
| } | ||||
| 
 | ||||
| func (f *win32Pipe) SetDeadline(t time.Time) error { | ||||
| 	f.SetReadDeadline(t) | ||||
| 	f.SetWriteDeadline(t) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // CloseWrite closes the write side of a message pipe in byte mode. | ||||
| func (f *win32MessageBytePipe) CloseWrite() error { | ||||
| 	if f.writeClosed { | ||||
| 		return errPipeWriteClosed | ||||
| 	} | ||||
| 	_, err := f.win32File.Write(nil) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	f.writeClosed = true | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // Write writes bytes to a message pipe in byte mode. Zero-byte writes are ignored, since | ||||
| // they are used to implement CloseWrite(). | ||||
| func (f *win32MessageBytePipe) Write(b []byte) (int, error) { | ||||
| 	if f.writeClosed { | ||||
| 		return 0, errPipeWriteClosed | ||||
| 	} | ||||
| 	if len(b) == 0 { | ||||
| 		return 0, nil | ||||
| 	} | ||||
| 	return f.win32File.Write(b) | ||||
| } | ||||
| 
 | ||||
| // Read reads bytes from a message pipe in byte mode. A read of a zero-byte message on a message | ||||
| // mode pipe will return io.EOF, as will all subsequent reads. | ||||
| func (f *win32MessageBytePipe) Read(b []byte) (int, error) { | ||||
| 	if f.readEOF { | ||||
| 		return 0, io.EOF | ||||
| 	} | ||||
| 	n, err := f.win32File.Read(b) | ||||
| 	if err == io.EOF { | ||||
| 		// If this was the result of a zero-byte read, then | ||||
| 		// it is possible that the read was due to a zero-size | ||||
| 		// message. Since we are simulating CloseWrite with a | ||||
| 		// zero-byte message, ensure that all future Read() calls | ||||
| 		// also return EOF. | ||||
| 		f.readEOF = true | ||||
| 	} | ||||
| 	return n, err | ||||
| } | ||||
| 
 | ||||
| func (s pipeAddress) Network() string { | ||||
| 	return "pipe" | ||||
| } | ||||
| 
 | ||||
| func (s pipeAddress) String() string { | ||||
| 	return string(s) | ||||
| } | ||||
| 
 | ||||
| // DialPipe connects to a named pipe by path, timing out if the connection | ||||
| // takes longer than the specified duration. If timeout is nil, then the timeout | ||||
| // is the default timeout established by the pipe server. | ||||
| func DialPipe(path string, timeout *time.Duration) (net.Conn, error) { | ||||
| 	var absTimeout time.Time | ||||
| 	if timeout != nil { | ||||
| 		absTimeout = time.Now().Add(*timeout) | ||||
| 	} | ||||
| 	var err error | ||||
| 	var h syscall.Handle | ||||
| 	for { | ||||
| 		h, err = createFile(path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_OVERLAPPED|cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0) | ||||
| 		if err != cERROR_PIPE_BUSY { | ||||
| 			break | ||||
| 		} | ||||
| 		now := time.Now() | ||||
| 		var ms uint32 | ||||
| 		if absTimeout.IsZero() { | ||||
| 			ms = cNMPWAIT_USE_DEFAULT_WAIT | ||||
| 		} else if now.After(absTimeout) { | ||||
| 			ms = cNMPWAIT_NOWAIT | ||||
| 		} else { | ||||
| 			ms = uint32(absTimeout.Sub(now).Nanoseconds() / 1000 / 1000) | ||||
| 		} | ||||
| 		err = waitNamedPipe(path, ms) | ||||
| 		if err != nil { | ||||
| 			if err == cERROR_SEM_TIMEOUT { | ||||
| 				return nil, ErrTimeout | ||||
| 			} | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return nil, &os.PathError{Op: "open", Path: path, Err: err} | ||||
| 	} | ||||
| 
 | ||||
| 	var flags uint32 | ||||
| 	err = getNamedPipeInfo(h, &flags, nil, nil, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	var state uint32 | ||||
| 	err = getNamedPipeHandleState(h, &state, nil, nil, nil, nil, 0) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	if state&cPIPE_READMODE_MESSAGE != 0 { | ||||
| 		return nil, &os.PathError{Op: "open", Path: path, Err: errors.New("message readmode pipes not supported")} | ||||
| 	} | ||||
| 
 | ||||
| 	f, err := makeWin32File(h) | ||||
| 	if err != nil { | ||||
| 		syscall.Close(h) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	// If the pipe is in message mode, return a message byte pipe, which | ||||
| 	// supports CloseWrite(). | ||||
| 	if flags&cPIPE_TYPE_MESSAGE != 0 { | ||||
| 		return &win32MessageBytePipe{ | ||||
| 			win32Pipe: win32Pipe{win32File: f, path: path}, | ||||
| 		}, nil | ||||
| 	} | ||||
| 	return &win32Pipe{win32File: f, path: path}, nil | ||||
| } | ||||
| 
 | ||||
| type acceptResponse struct { | ||||
| 	f   *win32File | ||||
| 	err error | ||||
| } | ||||
| 
 | ||||
| type win32PipeListener struct { | ||||
| 	firstHandle        syscall.Handle | ||||
| 	path               string | ||||
| 	securityDescriptor []byte | ||||
| 	config             PipeConfig | ||||
| 	acceptCh           chan (chan acceptResponse) | ||||
| 	closeCh            chan int | ||||
| 	doneCh             chan int | ||||
| } | ||||
| 
 | ||||
| func makeServerPipeHandle(path string, securityDescriptor []byte, c *PipeConfig, first bool) (syscall.Handle, error) { | ||||
| 	var flags uint32 = cPIPE_ACCESS_DUPLEX | syscall.FILE_FLAG_OVERLAPPED | ||||
| 	if first { | ||||
| 		flags |= cFILE_FLAG_FIRST_PIPE_INSTANCE | ||||
| 	} | ||||
| 
 | ||||
| 	var mode uint32 = cPIPE_REJECT_REMOTE_CLIENTS | ||||
| 	if c.MessageMode { | ||||
| 		mode |= cPIPE_TYPE_MESSAGE | ||||
| 	} | ||||
| 
 | ||||
| 	var sa securityAttributes | ||||
| 	sa.Length = uint32(unsafe.Sizeof(sa)) | ||||
| 	if securityDescriptor != nil { | ||||
| 		sa.SecurityDescriptor = &securityDescriptor[0] | ||||
| 	} | ||||
| 	h, err := createNamedPipe(path, flags, mode, cPIPE_UNLIMITED_INSTANCES, uint32(c.OutputBufferSize), uint32(c.InputBufferSize), 0, &sa) | ||||
| 	if err != nil { | ||||
| 		return 0, &os.PathError{Op: "open", Path: path, Err: err} | ||||
| 	} | ||||
| 	return h, nil | ||||
| } | ||||
| 
 | ||||
| func (l *win32PipeListener) makeServerPipe() (*win32File, error) { | ||||
| 	h, err := makeServerPipeHandle(l.path, l.securityDescriptor, &l.config, false) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	f, err := makeWin32File(h) | ||||
| 	if err != nil { | ||||
| 		syscall.Close(h) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return f, nil | ||||
| } | ||||
| 
 | ||||
| func (l *win32PipeListener) listenerRoutine() { | ||||
| 	closed := false | ||||
| 	for !closed { | ||||
| 		select { | ||||
| 		case <-l.closeCh: | ||||
| 			closed = true | ||||
| 		case responseCh := <-l.acceptCh: | ||||
| 			p, err := l.makeServerPipe() | ||||
| 			if err == nil { | ||||
| 				// Wait for the client to connect. | ||||
| 				ch := make(chan error) | ||||
| 				go func() { | ||||
| 					ch <- connectPipe(p) | ||||
| 				}() | ||||
| 				select { | ||||
| 				case err = <-ch: | ||||
| 					if err != nil { | ||||
| 						p.Close() | ||||
| 						p = nil | ||||
| 					} | ||||
| 				case <-l.closeCh: | ||||
| 					// Abort the connect request by closing the handle. | ||||
| 					p.Close() | ||||
| 					p = nil | ||||
| 					err = <-ch | ||||
| 					if err == nil || err == ErrFileClosed { | ||||
| 						err = ErrPipeListenerClosed | ||||
| 					} | ||||
| 					closed = true | ||||
| 				} | ||||
| 			} | ||||
| 			responseCh <- acceptResponse{p, err} | ||||
| 		} | ||||
| 	} | ||||
| 	syscall.Close(l.firstHandle) | ||||
| 	l.firstHandle = 0 | ||||
| 	// Notify Close() and Accept() callers that the handle has been closed. | ||||
| 	close(l.doneCh) | ||||
| } | ||||
| 
 | ||||
| // PipeConfig contain configuration for the pipe listener. | ||||
| type PipeConfig struct { | ||||
| 	// SecurityDescriptor contains a Windows security descriptor in SDDL format. | ||||
| 	SecurityDescriptor string | ||||
| 
 | ||||
| 	// MessageMode determines whether the pipe is in byte or message mode. In either | ||||
| 	// case the pipe is read in byte mode by default. The only practical difference in | ||||
| 	// this implementation is that CloseWrite() is only supported for message mode pipes; | ||||
| 	// CloseWrite() is implemented as a zero-byte write, but zero-byte writes are only | ||||
| 	// transferred to the reader (and returned as io.EOF in this implementation) | ||||
| 	// when the pipe is in message mode. | ||||
| 	MessageMode bool | ||||
| 
 | ||||
| 	// InputBufferSize specifies the size the input buffer, in bytes. | ||||
| 	InputBufferSize int32 | ||||
| 
 | ||||
| 	// OutputBufferSize specifies the size the input buffer, in bytes. | ||||
| 	OutputBufferSize int32 | ||||
| } | ||||
| 
 | ||||
| // ListenPipe creates a listener on a Windows named pipe path, e.g. \\.\pipe\mypipe. | ||||
| // The pipe must not already exist. | ||||
| func ListenPipe(path string, c *PipeConfig) (net.Listener, error) { | ||||
| 	var ( | ||||
| 		sd  []byte | ||||
| 		err error | ||||
| 	) | ||||
| 	if c == nil { | ||||
| 		c = &PipeConfig{} | ||||
| 	} | ||||
| 	if c.SecurityDescriptor != "" { | ||||
| 		sd, err = SddlToSecurityDescriptor(c.SecurityDescriptor) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
| 	h, err := makeServerPipeHandle(path, sd, c, true) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	// Immediately open and then close a client handle so that the named pipe is | ||||
| 	// created but not currently accepting connections. | ||||
| 	h2, err := createFile(path, 0, 0, nil, syscall.OPEN_EXISTING, cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0) | ||||
| 	if err != nil { | ||||
| 		syscall.Close(h) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	syscall.Close(h2) | ||||
| 	l := &win32PipeListener{ | ||||
| 		firstHandle:        h, | ||||
| 		path:               path, | ||||
| 		securityDescriptor: sd, | ||||
| 		config:             *c, | ||||
| 		acceptCh:           make(chan (chan acceptResponse)), | ||||
| 		closeCh:            make(chan int), | ||||
| 		doneCh:             make(chan int), | ||||
| 	} | ||||
| 	go l.listenerRoutine() | ||||
| 	return l, nil | ||||
| } | ||||
| 
 | ||||
| func connectPipe(p *win32File) error { | ||||
| 	c, err := p.prepareIo() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	err = connectNamedPipe(p.handle, &c.o) | ||||
| 	_, err = p.asyncIo(c, time.Time{}, 0, err) | ||||
| 	if err != nil && err != cERROR_PIPE_CONNECTED { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (l *win32PipeListener) Accept() (net.Conn, error) { | ||||
| 	ch := make(chan acceptResponse) | ||||
| 	select { | ||||
| 	case l.acceptCh <- ch: | ||||
| 		response := <-ch | ||||
| 		err := response.err | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		if l.config.MessageMode { | ||||
| 			return &win32MessageBytePipe{ | ||||
| 				win32Pipe: win32Pipe{win32File: response.f, path: l.path}, | ||||
| 			}, nil | ||||
| 		} | ||||
| 		return &win32Pipe{win32File: response.f, path: l.path}, nil | ||||
| 	case <-l.doneCh: | ||||
| 		return nil, ErrPipeListenerClosed | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (l *win32PipeListener) Close() error { | ||||
| 	select { | ||||
| 	case l.closeCh <- 1: | ||||
| 		<-l.doneCh | ||||
| 	case <-l.doneCh: | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (l *win32PipeListener) Addr() net.Addr { | ||||
| 	return pipeAddress(l.path) | ||||
| } | ||||
							
								
								
									
										150
									
								
								vendor/src/github.com/Microsoft/go-winio/privilege.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								vendor/src/github.com/Microsoft/go-winio/privilege.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,150 @@ | |||
| package winio | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/binary" | ||||
| 	"fmt" | ||||
| 	"runtime" | ||||
| 	"syscall" | ||||
| 	"unicode/utf16" | ||||
| ) | ||||
| 
 | ||||
| //sys adjustTokenPrivileges(token syscall.Handle, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges | ||||
| //sys impersonateSelf(level uint32) (err error) = advapi32.ImpersonateSelf | ||||
| //sys revertToSelf() (err error) = advapi32.RevertToSelf | ||||
| //sys openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *syscall.Handle) (err error) = advapi32.OpenThreadToken | ||||
| //sys getCurrentThread() (h syscall.Handle) = GetCurrentThread | ||||
| //sys lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) = advapi32.LookupPrivilegeValueW | ||||
| //sys lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW | ||||
| //sys lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) = advapi32.LookupPrivilegeDisplayNameW | ||||
| 
 | ||||
| const ( | ||||
| 	SE_PRIVILEGE_ENABLED = 2 | ||||
| 
 | ||||
| 	ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300 | ||||
| 
 | ||||
| 	SeBackupPrivilege  = "SeBackupPrivilege" | ||||
| 	SeRestorePrivilege = "SeRestorePrivilege" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	securityAnonymous = iota | ||||
| 	securityIdentification | ||||
| 	securityImpersonation | ||||
| 	securityDelegation | ||||
| ) | ||||
| 
 | ||||
| type PrivilegeError struct { | ||||
| 	privileges []uint64 | ||||
| } | ||||
| 
 | ||||
| func (e *PrivilegeError) Error() string { | ||||
| 	s := "" | ||||
| 	if len(e.privileges) > 1 { | ||||
| 		s = "Could not enable privileges " | ||||
| 	} else { | ||||
| 		s = "Could not enable privilege " | ||||
| 	} | ||||
| 	for i, p := range e.privileges { | ||||
| 		if i != 0 { | ||||
| 			s += ", " | ||||
| 		} | ||||
| 		s += `"` | ||||
| 		s += getPrivilegeName(p) | ||||
| 		s += `"` | ||||
| 	} | ||||
| 	return s | ||||
| } | ||||
| 
 | ||||
| func RunWithPrivilege(name string, fn func() error) error { | ||||
| 	return RunWithPrivileges([]string{name}, fn) | ||||
| } | ||||
| 
 | ||||
| func RunWithPrivileges(names []string, fn func() error) error { | ||||
| 	var privileges []uint64 | ||||
| 	for _, name := range names { | ||||
| 		p := uint64(0) | ||||
| 		err := lookupPrivilegeValue("", name, &p) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		privileges = append(privileges, p) | ||||
| 	} | ||||
| 	runtime.LockOSThread() | ||||
| 	defer runtime.UnlockOSThread() | ||||
| 	token, err := newThreadToken() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer releaseThreadToken(token) | ||||
| 	err = adjustPrivileges(token, privileges) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return fn() | ||||
| } | ||||
| 
 | ||||
| func adjustPrivileges(token syscall.Handle, privileges []uint64) error { | ||||
| 	var b bytes.Buffer | ||||
| 	binary.Write(&b, binary.LittleEndian, uint32(len(privileges))) | ||||
| 	for _, p := range privileges { | ||||
| 		binary.Write(&b, binary.LittleEndian, p) | ||||
| 		binary.Write(&b, binary.LittleEndian, uint32(SE_PRIVILEGE_ENABLED)) | ||||
| 	} | ||||
| 	prevState := make([]byte, b.Len()) | ||||
| 	reqSize := uint32(0) | ||||
| 	success, err := adjustTokenPrivileges(token, false, &b.Bytes()[0], uint32(len(prevState)), &prevState[0], &reqSize) | ||||
| 	if !success { | ||||
| 		return err | ||||
| 	} | ||||
| 	if err == ERROR_NOT_ALL_ASSIGNED { | ||||
| 		return &PrivilegeError{privileges} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func getPrivilegeName(luid uint64) string { | ||||
| 	var nameBuffer [256]uint16 | ||||
| 	bufSize := uint32(len(nameBuffer)) | ||||
| 	err := lookupPrivilegeName("", &luid, &nameBuffer[0], &bufSize) | ||||
| 	if err != nil { | ||||
| 		return fmt.Sprintf("<unknown privilege %d>", luid) | ||||
| 	} | ||||
| 
 | ||||
| 	var displayNameBuffer [256]uint16 | ||||
| 	displayBufSize := uint32(len(displayNameBuffer)) | ||||
| 	var langId uint32 | ||||
| 	err = lookupPrivilegeDisplayName("", &nameBuffer[0], &displayNameBuffer[0], &displayBufSize, &langId) | ||||
| 	if err != nil { | ||||
| 		return fmt.Sprintf("<unknown privilege %s>", utf16.Decode(nameBuffer[:bufSize])) | ||||
| 	} | ||||
| 
 | ||||
| 	return string(utf16.Decode(displayNameBuffer[:displayBufSize])) | ||||
| } | ||||
| 
 | ||||
| func newThreadToken() (syscall.Handle, error) { | ||||
| 	err := impersonateSelf(securityImpersonation) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 		return 0, err | ||||
| 	} | ||||
| 
 | ||||
| 	var token syscall.Handle | ||||
| 	err = openThreadToken(getCurrentThread(), syscall.TOKEN_ADJUST_PRIVILEGES|syscall.TOKEN_QUERY, false, &token) | ||||
| 	if err != nil { | ||||
| 		rerr := revertToSelf() | ||||
| 		if rerr != nil { | ||||
| 			panic(rerr) | ||||
| 		} | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return token, nil | ||||
| } | ||||
| 
 | ||||
| func releaseThreadToken(h syscall.Handle) { | ||||
| 	err := revertToSelf() | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	syscall.Close(h) | ||||
| } | ||||
							
								
								
									
										128
									
								
								vendor/src/github.com/Microsoft/go-winio/reparse.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								vendor/src/github.com/Microsoft/go-winio/reparse.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,128 @@ | |||
| package winio | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/binary" | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 	"unicode/utf16" | ||||
| 	"unsafe" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	reparseTagMountPoint = 0xA0000003 | ||||
| 	reparseTagSymlink    = 0xA000000C | ||||
| ) | ||||
| 
 | ||||
| type reparseDataBuffer struct { | ||||
| 	ReparseTag           uint32 | ||||
| 	ReparseDataLength    uint16 | ||||
| 	Reserved             uint16 | ||||
| 	SubstituteNameOffset uint16 | ||||
| 	SubstituteNameLength uint16 | ||||
| 	PrintNameOffset      uint16 | ||||
| 	PrintNameLength      uint16 | ||||
| } | ||||
| 
 | ||||
| // ReparsePoint describes a Win32 symlink or mount point. | ||||
| type ReparsePoint struct { | ||||
| 	Target       string | ||||
| 	IsMountPoint bool | ||||
| } | ||||
| 
 | ||||
| // UnsupportedReparsePointError is returned when trying to decode a non-symlink or | ||||
| // mount point reparse point. | ||||
| type UnsupportedReparsePointError struct { | ||||
| 	Tag uint32 | ||||
| } | ||||
| 
 | ||||
| func (e *UnsupportedReparsePointError) Error() string { | ||||
| 	return fmt.Sprintf("unsupported reparse point %x", e.Tag) | ||||
| } | ||||
| 
 | ||||
| // DecodeReparsePoint decodes a Win32 REPARSE_DATA_BUFFER structure containing either a symlink | ||||
| // or a mount point. | ||||
| func DecodeReparsePoint(b []byte) (*ReparsePoint, error) { | ||||
| 	tag := binary.LittleEndian.Uint32(b[0:4]) | ||||
| 	return DecodeReparsePointData(tag, b[8:]) | ||||
| } | ||||
| 
 | ||||
| func DecodeReparsePointData(tag uint32, b []byte) (*ReparsePoint, error) { | ||||
| 	isMountPoint := false | ||||
| 	switch tag { | ||||
| 	case reparseTagMountPoint: | ||||
| 		isMountPoint = true | ||||
| 	case reparseTagSymlink: | ||||
| 	default: | ||||
| 		return nil, &UnsupportedReparsePointError{tag} | ||||
| 	} | ||||
| 	nameOffset := 8 + binary.LittleEndian.Uint16(b[4:6]) | ||||
| 	if !isMountPoint { | ||||
| 		nameOffset += 4 | ||||
| 	} | ||||
| 	nameLength := binary.LittleEndian.Uint16(b[6:8]) | ||||
| 	name := make([]uint16, nameLength/2) | ||||
| 	err := binary.Read(bytes.NewReader(b[nameOffset:nameOffset+nameLength]), binary.LittleEndian, &name) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &ReparsePoint{string(utf16.Decode(name)), isMountPoint}, nil | ||||
| } | ||||
| 
 | ||||
| func isDriveLetter(c byte) bool { | ||||
| 	return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') | ||||
| } | ||||
| 
 | ||||
| // EncodeReparsePoint encodes a Win32 REPARSE_DATA_BUFFER structure describing a symlink or | ||||
| // mount point. | ||||
| func EncodeReparsePoint(rp *ReparsePoint) []byte { | ||||
| 	// Generate an NT path and determine if this is a relative path. | ||||
| 	var ntTarget string | ||||
| 	relative := false | ||||
| 	if strings.HasPrefix(rp.Target, `\\?\`) { | ||||
| 		ntTarget = `\??\` + rp.Target[4:] | ||||
| 	} else if strings.HasPrefix(rp.Target, `\\`) { | ||||
| 		ntTarget = `\??\UNC\` + rp.Target[2:] | ||||
| 	} else if len(rp.Target) >= 2 && isDriveLetter(rp.Target[0]) && rp.Target[1] == ':' { | ||||
| 		ntTarget = `\??\` + rp.Target | ||||
| 	} else { | ||||
| 		ntTarget = rp.Target | ||||
| 		relative = true | ||||
| 	} | ||||
| 
 | ||||
| 	// The paths must be NUL-terminated even though they are counted strings. | ||||
| 	target16 := utf16.Encode([]rune(rp.Target + "\x00")) | ||||
| 	ntTarget16 := utf16.Encode([]rune(ntTarget + "\x00")) | ||||
| 
 | ||||
| 	size := int(unsafe.Sizeof(reparseDataBuffer{})) - 8 | ||||
| 	size += len(ntTarget16)*2 + len(target16)*2 | ||||
| 
 | ||||
| 	tag := uint32(reparseTagMountPoint) | ||||
| 	if !rp.IsMountPoint { | ||||
| 		tag = reparseTagSymlink | ||||
| 		size += 4 // Add room for symlink flags | ||||
| 	} | ||||
| 
 | ||||
| 	data := reparseDataBuffer{ | ||||
| 		ReparseTag:           tag, | ||||
| 		ReparseDataLength:    uint16(size), | ||||
| 		SubstituteNameOffset: 0, | ||||
| 		SubstituteNameLength: uint16((len(ntTarget16) - 1) * 2), | ||||
| 		PrintNameOffset:      uint16(len(ntTarget16) * 2), | ||||
| 		PrintNameLength:      uint16((len(target16) - 1) * 2), | ||||
| 	} | ||||
| 
 | ||||
| 	var b bytes.Buffer | ||||
| 	binary.Write(&b, binary.LittleEndian, &data) | ||||
| 	if !rp.IsMountPoint { | ||||
| 		flags := uint32(0) | ||||
| 		if relative { | ||||
| 			flags |= 1 | ||||
| 		} | ||||
| 		binary.Write(&b, binary.LittleEndian, flags) | ||||
| 	} | ||||
| 
 | ||||
| 	binary.Write(&b, binary.LittleEndian, ntTarget16) | ||||
| 	binary.Write(&b, binary.LittleEndian, target16) | ||||
| 	return b.Bytes() | ||||
| } | ||||
							
								
								
									
										96
									
								
								vendor/src/github.com/Microsoft/go-winio/sd.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								vendor/src/github.com/Microsoft/go-winio/sd.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,96 @@ | |||
| package winio | ||||
| 
 | ||||
| import ( | ||||
| 	"syscall" | ||||
| 	"unsafe" | ||||
| ) | ||||
| 
 | ||||
| //sys lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountNameW | ||||
| //sys convertSidToStringSid(sid *byte, str **uint16) (err error) = advapi32.ConvertSidToStringSidW | ||||
| //sys convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW | ||||
| //sys convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) = advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW | ||||
| //sys localFree(mem uintptr) = LocalFree | ||||
| //sys getSecurityDescriptorLength(sd uintptr) (len uint32) = advapi32.GetSecurityDescriptorLength | ||||
| 
 | ||||
| const ( | ||||
| 	cERROR_NONE_MAPPED = syscall.Errno(1332) | ||||
| ) | ||||
| 
 | ||||
| type AccountLookupError struct { | ||||
| 	Name string | ||||
| 	Err  error | ||||
| } | ||||
| 
 | ||||
| func (e *AccountLookupError) Error() string { | ||||
| 	if e.Name == "" { | ||||
| 		return "lookup account: empty account name specified" | ||||
| 	} | ||||
| 	var s string | ||||
| 	switch e.Err { | ||||
| 	case cERROR_NONE_MAPPED: | ||||
| 		s = "not found" | ||||
| 	default: | ||||
| 		s = e.Err.Error() | ||||
| 	} | ||||
| 	return "lookup account " + e.Name + ": " + s | ||||
| } | ||||
| 
 | ||||
| type SddlConversionError struct { | ||||
| 	Sddl string | ||||
| 	Err  error | ||||
| } | ||||
| 
 | ||||
| func (e *SddlConversionError) Error() string { | ||||
| 	return "convert " + e.Sddl + ": " + e.Err.Error() | ||||
| } | ||||
| 
 | ||||
| // LookupSidByName looks up the SID of an account by name | ||||
| func LookupSidByName(name string) (sid string, err error) { | ||||
| 	if name == "" { | ||||
| 		return "", &AccountLookupError{name, cERROR_NONE_MAPPED} | ||||
| 	} | ||||
| 
 | ||||
| 	var sidSize, sidNameUse, refDomainSize uint32 | ||||
| 	err = lookupAccountName(nil, name, nil, &sidSize, nil, &refDomainSize, &sidNameUse) | ||||
| 	if err != nil && err != syscall.ERROR_INSUFFICIENT_BUFFER { | ||||
| 		return "", &AccountLookupError{name, err} | ||||
| 	} | ||||
| 	sidBuffer := make([]byte, sidSize) | ||||
| 	refDomainBuffer := make([]uint16, refDomainSize) | ||||
| 	err = lookupAccountName(nil, name, &sidBuffer[0], &sidSize, &refDomainBuffer[0], &refDomainSize, &sidNameUse) | ||||
| 	if err != nil { | ||||
| 		return "", &AccountLookupError{name, err} | ||||
| 	} | ||||
| 	var strBuffer *uint16 | ||||
| 	err = convertSidToStringSid(&sidBuffer[0], &strBuffer) | ||||
| 	if err != nil { | ||||
| 		return "", &AccountLookupError{name, err} | ||||
| 	} | ||||
| 	sid = syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(strBuffer))[:]) | ||||
| 	localFree(uintptr(unsafe.Pointer(strBuffer))) | ||||
| 	return sid, nil | ||||
| } | ||||
| 
 | ||||
| func SddlToSecurityDescriptor(sddl string) ([]byte, error) { | ||||
| 	var sdBuffer uintptr | ||||
| 	err := convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &sdBuffer, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, &SddlConversionError{sddl, err} | ||||
| 	} | ||||
| 	defer localFree(sdBuffer) | ||||
| 	sd := make([]byte, getSecurityDescriptorLength(sdBuffer)) | ||||
| 	copy(sd, (*[0xffff]byte)(unsafe.Pointer(sdBuffer))[:len(sd)]) | ||||
| 	return sd, nil | ||||
| } | ||||
| 
 | ||||
| func SecurityDescriptorToSddl(sd []byte) (string, error) { | ||||
| 	var sddl *uint16 | ||||
| 	// The returned string length seems to including an aribtrary number of terminating NULs. | ||||
| 	// Don't use it. | ||||
| 	err := convertSecurityDescriptorToStringSecurityDescriptor(&sd[0], 1, 0xff, &sddl, nil) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	defer localFree(uintptr(unsafe.Pointer(sddl))) | ||||
| 	return syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(sddl))[:]), nil | ||||
| } | ||||
							
								
								
									
										3
									
								
								vendor/src/github.com/Microsoft/go-winio/syscall.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/src/github.com/Microsoft/go-winio/syscall.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| package winio | ||||
| 
 | ||||
| //go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall.go file.go pipe.go sd.go fileinfo.go privilege.go backup.go | ||||
							
								
								
									
										492
									
								
								vendor/src/github.com/Microsoft/go-winio/zsyscall.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										492
									
								
								vendor/src/github.com/Microsoft/go-winio/zsyscall.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,492 @@ | |||
| // MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT | ||||
| 
 | ||||
| package winio | ||||
| 
 | ||||
| import "unsafe" | ||||
| import "syscall" | ||||
| 
 | ||||
| var _ unsafe.Pointer | ||||
| 
 | ||||
| var ( | ||||
| 	modkernel32 = syscall.NewLazyDLL("kernel32.dll") | ||||
| 	modwinmm    = syscall.NewLazyDLL("winmm.dll") | ||||
| 	modadvapi32 = syscall.NewLazyDLL("advapi32.dll") | ||||
| 
 | ||||
| 	procCancelIoEx                                           = modkernel32.NewProc("CancelIoEx") | ||||
| 	procCreateIoCompletionPort                               = modkernel32.NewProc("CreateIoCompletionPort") | ||||
| 	procGetQueuedCompletionStatus                            = modkernel32.NewProc("GetQueuedCompletionStatus") | ||||
| 	procSetFileCompletionNotificationModes                   = modkernel32.NewProc("SetFileCompletionNotificationModes") | ||||
| 	proctimeBeginPeriod                                      = modwinmm.NewProc("timeBeginPeriod") | ||||
| 	procConnectNamedPipe                                     = modkernel32.NewProc("ConnectNamedPipe") | ||||
| 	procCreateNamedPipeW                                     = modkernel32.NewProc("CreateNamedPipeW") | ||||
| 	procCreateFileW                                          = modkernel32.NewProc("CreateFileW") | ||||
| 	procWaitNamedPipeW                                       = modkernel32.NewProc("WaitNamedPipeW") | ||||
| 	procGetNamedPipeInfo                                     = modkernel32.NewProc("GetNamedPipeInfo") | ||||
| 	procGetNamedPipeHandleStateW                             = modkernel32.NewProc("GetNamedPipeHandleStateW") | ||||
| 	procLookupAccountNameW                                   = modadvapi32.NewProc("LookupAccountNameW") | ||||
| 	procConvertSidToStringSidW                               = modadvapi32.NewProc("ConvertSidToStringSidW") | ||||
| 	procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW") | ||||
| 	procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW") | ||||
| 	procLocalFree                                            = modkernel32.NewProc("LocalFree") | ||||
| 	procGetSecurityDescriptorLength                          = modadvapi32.NewProc("GetSecurityDescriptorLength") | ||||
| 	procGetFileInformationByHandleEx                         = modkernel32.NewProc("GetFileInformationByHandleEx") | ||||
| 	procSetFileInformationByHandle                           = modkernel32.NewProc("SetFileInformationByHandle") | ||||
| 	procAdjustTokenPrivileges                                = modadvapi32.NewProc("AdjustTokenPrivileges") | ||||
| 	procImpersonateSelf                                      = modadvapi32.NewProc("ImpersonateSelf") | ||||
| 	procRevertToSelf                                         = modadvapi32.NewProc("RevertToSelf") | ||||
| 	procOpenThreadToken                                      = modadvapi32.NewProc("OpenThreadToken") | ||||
| 	procGetCurrentThread                                     = modkernel32.NewProc("GetCurrentThread") | ||||
| 	procLookupPrivilegeValueW                                = modadvapi32.NewProc("LookupPrivilegeValueW") | ||||
| 	procLookupPrivilegeNameW                                 = modadvapi32.NewProc("LookupPrivilegeNameW") | ||||
| 	procLookupPrivilegeDisplayNameW                          = modadvapi32.NewProc("LookupPrivilegeDisplayNameW") | ||||
| 	procBackupRead                                           = modkernel32.NewProc("BackupRead") | ||||
| 	procBackupWrite                                          = modkernel32.NewProc("BackupWrite") | ||||
| ) | ||||
| 
 | ||||
| func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) { | ||||
| 	r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0) | ||||
| 	newport = syscall.Handle(r0) | ||||
| 	if newport == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func timeBeginPeriod(period uint32) (n int32) { | ||||
| 	r0, _, _ := syscall.Syscall(proctimeBeginPeriod.Addr(), 1, uintptr(period), 0, 0) | ||||
| 	n = int32(r0) | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) { | ||||
| 	var _p0 *uint16 | ||||
| 	_p0, err = syscall.UTF16PtrFromString(name) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa) | ||||
| } | ||||
| 
 | ||||
| func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *securityAttributes) (handle syscall.Handle, err error) { | ||||
| 	r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0) | ||||
| 	handle = syscall.Handle(r0) | ||||
| 	if handle == syscall.InvalidHandle { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func createFile(name string, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) { | ||||
| 	var _p0 *uint16 | ||||
| 	_p0, err = syscall.UTF16PtrFromString(name) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	return _createFile(_p0, access, mode, sa, createmode, attrs, templatefile) | ||||
| } | ||||
| 
 | ||||
| func _createFile(name *uint16, access uint32, mode uint32, sa *securityAttributes, createmode uint32, attrs uint32, templatefile syscall.Handle) (handle syscall.Handle, err error) { | ||||
| 	r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0) | ||||
| 	handle = syscall.Handle(r0) | ||||
| 	if handle == syscall.InvalidHandle { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func waitNamedPipe(name string, timeout uint32) (err error) { | ||||
| 	var _p0 *uint16 | ||||
| 	_p0, err = syscall.UTF16PtrFromString(name) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	return _waitNamedPipe(_p0, timeout) | ||||
| } | ||||
| 
 | ||||
| func _waitNamedPipe(name *uint16, timeout uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procWaitNamedPipeW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(timeout), 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { | ||||
| 	var _p0 *uint16 | ||||
| 	_p0, err = syscall.UTF16PtrFromString(accountName) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse) | ||||
| } | ||||
| 
 | ||||
| func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func convertSidToStringSid(sid *byte, str **uint16) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) { | ||||
| 	var _p0 *uint16 | ||||
| 	_p0, err = syscall.UTF16PtrFromString(str) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	return _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size) | ||||
| } | ||||
| 
 | ||||
| func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func localFree(mem uintptr) { | ||||
| 	syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0) | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func getSecurityDescriptorLength(sd uintptr) (len uint32) { | ||||
| 	r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0) | ||||
| 	len = uint32(r0) | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func getFileInformationByHandleEx(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func setFileInformationByHandle(h syscall.Handle, class uint32, buffer *byte, size uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(h), uintptr(class), uintptr(unsafe.Pointer(buffer)), uintptr(size), 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func adjustTokenPrivileges(token syscall.Handle, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) { | ||||
| 	var _p0 uint32 | ||||
| 	if releaseAll { | ||||
| 		_p0 = 1 | ||||
| 	} else { | ||||
| 		_p0 = 0 | ||||
| 	} | ||||
| 	r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize))) | ||||
| 	success = r0 != 0 | ||||
| 	if true { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func impersonateSelf(level uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func revertToSelf() (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *syscall.Handle) (err error) { | ||||
| 	var _p0 uint32 | ||||
| 	if openAsSelf { | ||||
| 		_p0 = 1 | ||||
| 	} else { | ||||
| 		_p0 = 0 | ||||
| 	} | ||||
| 	r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func getCurrentThread() (h syscall.Handle) { | ||||
| 	r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0) | ||||
| 	h = syscall.Handle(r0) | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) { | ||||
| 	var _p0 *uint16 | ||||
| 	_p0, err = syscall.UTF16PtrFromString(systemName) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	var _p1 *uint16 | ||||
| 	_p1, err = syscall.UTF16PtrFromString(name) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	return _lookupPrivilegeValue(_p0, _p1, luid) | ||||
| } | ||||
| 
 | ||||
| func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) { | ||||
| 	var _p0 *uint16 | ||||
| 	_p0, err = syscall.UTF16PtrFromString(systemName) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	return _lookupPrivilegeName(_p0, luid, buffer, size) | ||||
| } | ||||
| 
 | ||||
| func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) { | ||||
| 	var _p0 *uint16 | ||||
| 	_p0, err = syscall.UTF16PtrFromString(systemName) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId) | ||||
| } | ||||
| 
 | ||||
| func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) { | ||||
| 	var _p0 *byte | ||||
| 	if len(b) > 0 { | ||||
| 		_p0 = &b[0] | ||||
| 	} | ||||
| 	var _p1 uint32 | ||||
| 	if abort { | ||||
| 		_p1 = 1 | ||||
| 	} else { | ||||
| 		_p1 = 0 | ||||
| 	} | ||||
| 	var _p2 uint32 | ||||
| 	if processSecurity { | ||||
| 		_p2 = 1 | ||||
| 	} else { | ||||
| 		_p2 = 0 | ||||
| 	} | ||||
| 	r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) { | ||||
| 	var _p0 *byte | ||||
| 	if len(b) > 0 { | ||||
| 		_p0 = &b[0] | ||||
| 	} | ||||
| 	var _p1 uint32 | ||||
| 	if abort { | ||||
| 		_p1 = 1 | ||||
| 	} else { | ||||
| 		_p1 = 0 | ||||
| 	} | ||||
| 	var _p2 uint32 | ||||
| 	if processSecurity { | ||||
| 		_p2 = 1 | ||||
| 	} else { | ||||
| 		_p2 = 0 | ||||
| 	} | ||||
| 	r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		if e1 != 0 { | ||||
| 			err = error(e1) | ||||
| 		} else { | ||||
| 			err = syscall.EINVAL | ||||
| 		} | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
							
								
								
									
										52
									
								
								vendor/src/github.com/coreos/go-systemd/activation/files.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								vendor/src/github.com/coreos/go-systemd/activation/files.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,52 @@ | |||
| // Copyright 2015 CoreOS, Inc. | ||||
| // | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
| 
 | ||||
| // Package activation implements primitives for systemd socket activation. | ||||
| package activation | ||||
| 
 | ||||
| import ( | ||||
| 	"os" | ||||
| 	"strconv" | ||||
| 	"syscall" | ||||
| ) | ||||
| 
 | ||||
| // based on: https://gist.github.com/alberts/4640792 | ||||
| const ( | ||||
| 	listenFdsStart = 3 | ||||
| ) | ||||
| 
 | ||||
| func Files(unsetEnv bool) []*os.File { | ||||
| 	if unsetEnv { | ||||
| 		defer os.Unsetenv("LISTEN_PID") | ||||
| 		defer os.Unsetenv("LISTEN_FDS") | ||||
| 	} | ||||
| 
 | ||||
| 	pid, err := strconv.Atoi(os.Getenv("LISTEN_PID")) | ||||
| 	if err != nil || pid != os.Getpid() { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	nfds, err := strconv.Atoi(os.Getenv("LISTEN_FDS")) | ||||
| 	if err != nil || nfds == 0 { | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	files := make([]*os.File, 0, nfds) | ||||
| 	for fd := listenFdsStart; fd < listenFdsStart+nfds; fd++ { | ||||
| 		syscall.CloseOnExec(fd) | ||||
| 		files = append(files, os.NewFile(uintptr(fd), "LISTEN_FD_"+strconv.Itoa(fd))) | ||||
| 	} | ||||
| 
 | ||||
| 	return files | ||||
| } | ||||
							
								
								
									
										62
									
								
								vendor/src/github.com/coreos/go-systemd/activation/listeners.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								vendor/src/github.com/coreos/go-systemd/activation/listeners.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,62 @@ | |||
| // Copyright 2015 CoreOS, Inc. | ||||
| // | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
| 
 | ||||
| package activation | ||||
| 
 | ||||
| import ( | ||||
| 	"crypto/tls" | ||||
| 	"net" | ||||
| ) | ||||
| 
 | ||||
| // Listeners returns a slice containing a net.Listener for each matching socket type | ||||
| // passed to this process. | ||||
| // | ||||
| // The order of the file descriptors is preserved in the returned slice. | ||||
| // Nil values are used to fill any gaps. For example if systemd were to return file descriptors | ||||
| // corresponding with "udp, tcp, tcp", then the slice would contain {nil, net.Listener, net.Listener} | ||||
| func Listeners(unsetEnv bool) ([]net.Listener, error) { | ||||
| 	files := Files(unsetEnv) | ||||
| 	listeners := make([]net.Listener, len(files)) | ||||
| 
 | ||||
| 	for i, f := range files { | ||||
| 		if pc, err := net.FileListener(f); err == nil { | ||||
| 			listeners[i] = pc | ||||
| 		} | ||||
| 	} | ||||
| 	return listeners, nil | ||||
| } | ||||
| 
 | ||||
| // TLSListeners returns a slice containing a net.listener for each matching TCP socket type | ||||
| // passed to this process. | ||||
| // It uses default Listeners func and forces TCP sockets handlers to use TLS based on tlsConfig. | ||||
| func TLSListeners(unsetEnv bool, tlsConfig *tls.Config) ([]net.Listener, error) { | ||||
| 	listeners, err := Listeners(unsetEnv) | ||||
| 
 | ||||
| 	if listeners == nil || err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	if tlsConfig != nil && err == nil { | ||||
| 		tlsConfig.NextProtos = []string{"http/1.1"} | ||||
| 
 | ||||
| 		for i, l := range listeners { | ||||
| 			// Activate TLS only for TCP sockets | ||||
| 			if l.Addr().Network() == "tcp" { | ||||
| 				listeners[i] = tls.NewListener(l, tlsConfig) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return listeners, err | ||||
| } | ||||
							
								
								
									
										37
									
								
								vendor/src/github.com/coreos/go-systemd/activation/packetconns.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								vendor/src/github.com/coreos/go-systemd/activation/packetconns.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | |||
| // Copyright 2015 CoreOS, Inc. | ||||
| // | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
| 
 | ||||
| package activation | ||||
| 
 | ||||
| import ( | ||||
| 	"net" | ||||
| ) | ||||
| 
 | ||||
| // PacketConns returns a slice containing a net.PacketConn for each matching socket type | ||||
| // passed to this process. | ||||
| // | ||||
| // The order of the file descriptors is preserved in the returned slice. | ||||
| // Nil values are used to fill any gaps. For example if systemd were to return file descriptors | ||||
| // corresponding with "udp, tcp, udp", then the slice would contain {net.PacketConn, nil, net.PacketConn} | ||||
| func PacketConns(unsetEnv bool) ([]net.PacketConn, error) { | ||||
| 	files := Files(unsetEnv) | ||||
| 	conns := make([]net.PacketConn, len(files)) | ||||
| 
 | ||||
| 	for i, f := range files { | ||||
| 		if pc, err := net.FilePacketConn(f); err == nil { | ||||
| 			conns[i] = pc | ||||
| 		} | ||||
| 	} | ||||
| 	return conns, nil | ||||
| } | ||||
							
								
								
									
										94
									
								
								vendor/src/github.com/docker/docker/pkg/listeners/listeners_unix.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								vendor/src/github.com/docker/docker/pkg/listeners/listeners_unix.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,94 @@ | |||
| // +build !windows | ||||
| 
 | ||||
| package listeners | ||||
| 
 | ||||
| import ( | ||||
| 	"crypto/tls" | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"strconv" | ||||
| 
 | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	"github.com/coreos/go-systemd/activation" | ||||
| 	"github.com/docker/go-connections/sockets" | ||||
| ) | ||||
| 
 | ||||
| // Init creates new listeners for the server. | ||||
| // TODO: Clean up the fact that socketGroup and tlsConfig aren't always used. | ||||
| func Init(proto, addr, socketGroup string, tlsConfig *tls.Config) ([]net.Listener, error) { | ||||
| 	ls := []net.Listener{} | ||||
| 
 | ||||
| 	switch proto { | ||||
| 	case "fd": | ||||
| 		fds, err := listenFD(addr, tlsConfig) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		ls = append(ls, fds...) | ||||
| 	case "tcp": | ||||
| 		l, err := sockets.NewTCPSocket(addr, tlsConfig) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		ls = append(ls, l) | ||||
| 	case "unix": | ||||
| 		l, err := sockets.NewUnixSocket(addr, socketGroup) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("can't create unix socket %s: %v", addr, err) | ||||
| 		} | ||||
| 		ls = append(ls, l) | ||||
| 	default: | ||||
| 		return nil, fmt.Errorf("invalid protocol format: %q", proto) | ||||
| 	} | ||||
| 
 | ||||
| 	return ls, nil | ||||
| } | ||||
| 
 | ||||
| // listenFD returns the specified socket activated files as a slice of | ||||
| // net.Listeners or all of the activated files if "*" is given. | ||||
| func listenFD(addr string, tlsConfig *tls.Config) ([]net.Listener, error) { | ||||
| 	var ( | ||||
| 		err       error | ||||
| 		listeners []net.Listener | ||||
| 	) | ||||
| 	// socket activation | ||||
| 	if tlsConfig != nil { | ||||
| 		listeners, err = activation.TLSListeners(false, tlsConfig) | ||||
| 	} else { | ||||
| 		listeners, err = activation.Listeners(false) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	if len(listeners) == 0 { | ||||
| 		return nil, fmt.Errorf("no sockets found via socket activation: make sure the service was started by systemd") | ||||
| 	} | ||||
| 
 | ||||
| 	// default to all fds just like unix:// and tcp:// | ||||
| 	if addr == "" || addr == "*" { | ||||
| 		return listeners, nil | ||||
| 	} | ||||
| 
 | ||||
| 	fdNum, err := strconv.Atoi(addr) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to parse systemd fd address: should be a number: %v", addr) | ||||
| 	} | ||||
| 	fdOffset := fdNum - 3 | ||||
| 	if len(listeners) < int(fdOffset)+1 { | ||||
| 		return nil, fmt.Errorf("too few socket activated files passed in by systemd") | ||||
| 	} | ||||
| 	if listeners[fdOffset] == nil { | ||||
| 		return nil, fmt.Errorf("failed to listen on systemd activated file: fd %d", fdOffset+3) | ||||
| 	} | ||||
| 	for i, ls := range listeners { | ||||
| 		if i == fdOffset || ls == nil { | ||||
| 			continue | ||||
| 		} | ||||
| 		if err := ls.Close(); err != nil { | ||||
| 			// TODO: We shouldn't log inside a library. Remove this or error out. | ||||
| 			logrus.Errorf("failed to close systemd activated file: fd %d: %v", fdOffset+3, err) | ||||
| 		} | ||||
| 	} | ||||
| 	return []net.Listener{listeners[fdOffset]}, nil | ||||
| } | ||||
							
								
								
									
										54
									
								
								vendor/src/github.com/docker/docker/pkg/listeners/listeners_windows.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								vendor/src/github.com/docker/docker/pkg/listeners/listeners_windows.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,54 @@ | |||
| package listeners | ||||
| 
 | ||||
| import ( | ||||
| 	"crypto/tls" | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/Microsoft/go-winio" | ||||
| 	"github.com/docker/go-connections/sockets" | ||||
| ) | ||||
| 
 | ||||
| // Init creates new listeners for the server. | ||||
| func Init(proto, addr, socketGroup string, tlsConfig *tls.Config) ([]net.Listener, error) { | ||||
| 	ls := []net.Listener{} | ||||
| 
 | ||||
| 	switch proto { | ||||
| 	case "tcp": | ||||
| 		l, err := sockets.NewTCPSocket(addr, tlsConfig) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		ls = append(ls, l) | ||||
| 
 | ||||
| 	case "npipe": | ||||
| 		// allow Administrators and SYSTEM, plus whatever additional users or groups were specified | ||||
| 		sddl := "D:P(A;;GA;;;BA)(A;;GA;;;SY)" | ||||
| 		if socketGroup != "" { | ||||
| 			for _, g := range strings.Split(socketGroup, ",") { | ||||
| 				sid, err := winio.LookupSidByName(g) | ||||
| 				if err != nil { | ||||
| 					return nil, err | ||||
| 				} | ||||
| 				sddl += fmt.Sprintf("(A;;GRGW;;;%s)", sid) | ||||
| 			} | ||||
| 		} | ||||
| 		c := winio.PipeConfig{ | ||||
| 			SecurityDescriptor: sddl, | ||||
| 			MessageMode:        true,  // Use message mode so that CloseWrite() is supported | ||||
| 			InputBufferSize:    65536, // Use 64KB buffers to improve performance | ||||
| 			OutputBufferSize:   65536, | ||||
| 		} | ||||
| 		l, err := winio.ListenPipe(addr, &c) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		ls = append(ls, l) | ||||
| 
 | ||||
| 	default: | ||||
| 		return nil, fmt.Errorf("invalid protocol format: windows only supports tcp and npipe") | ||||
| 	} | ||||
| 
 | ||||
| 	return ls, nil | ||||
| } | ||||
|  | @ -1,11 +1,14 @@ | |||
| package system | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"syscall" | ||||
| 	"unsafe" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	ntuserApiset = syscall.NewLazyDLL("ext-ms-win-ntuser-window-l1-1-0") | ||||
| ) | ||||
| 
 | ||||
| // OSVersion is a wrapper for Windows version information | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx | ||||
| type OSVersion struct { | ||||
|  | @ -17,17 +20,18 @@ type OSVersion struct { | |||
| 
 | ||||
| // GetOSVersion gets the operating system version on Windows. Note that | ||||
| // docker.exe must be manifested to get the correct version information. | ||||
| func GetOSVersion() (OSVersion, error) { | ||||
| func GetOSVersion() OSVersion { | ||||
| 	var err error | ||||
| 	osv := OSVersion{} | ||||
| 	osv.Version, err = syscall.GetVersion() | ||||
| 	if err != nil { | ||||
| 		return osv, fmt.Errorf("Failed to call GetVersion()") | ||||
| 		// GetVersion never fails. | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	osv.MajorVersion = uint8(osv.Version & 0xFF) | ||||
| 	osv.MinorVersion = uint8(osv.Version >> 8 & 0xFF) | ||||
| 	osv.Build = uint16(osv.Version >> 16) | ||||
| 	return osv, nil | ||||
| 	return osv | ||||
| } | ||||
| 
 | ||||
| // Unmount is a platform-specific helper function to call | ||||
|  | @ -58,3 +62,12 @@ func CommandLineToArgv(commandLine string) ([]string, error) { | |||
| 
 | ||||
| 	return newArgs, nil | ||||
| } | ||||
| 
 | ||||
| // HasWin32KSupport determines whether containers that depend on win32k can | ||||
| // run on this machine. Win32k is the driver used to implement windowing. | ||||
| func HasWin32KSupport() bool { | ||||
| 	// For now, check for ntuser API support on the host. In the future, a host | ||||
| 	// may support win32k in containers even if the host does not support ntuser | ||||
| 	// APIs. | ||||
| 	return ntuserApiset.Load() == nil | ||||
| } | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ import ( | |||
| ) | ||||
| 
 | ||||
| // Umask sets current process's file mode creation mask to newmask | ||||
| // and return oldmask. | ||||
| // and returns oldmask. | ||||
| func Umask(newmask int) (oldmask int, err error) { | ||||
| 	return syscall.Umask(newmask), nil | ||||
| } | ||||
|  |  | |||
|  | @ -27,8 +27,6 @@ type State struct { | |||
| type Winsize struct { | ||||
| 	Height uint16 | ||||
| 	Width  uint16 | ||||
| 	x      uint16 | ||||
| 	y      uint16 | ||||
| } | ||||
| 
 | ||||
| // StdStreams returns the standard streams (stdin, stdout, stedrr). | ||||
|  |  | |||
|  | @ -23,14 +23,13 @@ type State struct { | |||
| type Winsize struct { | ||||
| 	Height uint16 | ||||
| 	Width  uint16 | ||||
| 	x      uint16 | ||||
| 	y      uint16 | ||||
| } | ||||
| 
 | ||||
| const ( | ||||
| 	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx | ||||
| 	enableVirtualTerminalInput      = 0x0200 | ||||
| 	enableVirtualTerminalProcessing = 0x0004 | ||||
| 	disableNewlineAutoReturn        = 0x0008 | ||||
| ) | ||||
| 
 | ||||
| // usingNativeConsole is true if we are using the Windows native console | ||||
|  | @ -58,21 +57,13 @@ func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) { | |||
| // console which supports ANSI emulation, or fall-back to the golang emulator | ||||
| // (github.com/azure/go-ansiterm). | ||||
| func useNativeConsole() bool { | ||||
| 	osv, err := system.GetOSVersion() | ||||
| 	if err != nil { | ||||
| 		return false | ||||
| 	} | ||||
| 	osv := system.GetOSVersion() | ||||
| 
 | ||||
| 	// Native console is not available before major version 10 | ||||
| 	if osv.MajorVersion < 10 { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	// Must have a late pre-release TP4 build of Windows Server 2016/Windows 10 TH2 or later | ||||
| 	if osv.Build < 10578 { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	// Get the console modes. If this fails, we can't use the native console | ||||
| 	state, err := getNativeConsole() | ||||
| 	if err != nil { | ||||
|  | @ -146,8 +137,14 @@ func probeNativeConsole(state State) error { | |||
| 
 | ||||
| // enableNativeConsole turns on native console mode | ||||
| func enableNativeConsole(state State) error { | ||||
| 	if err := winterm.SetConsoleMode(uintptr(state.outHandle), state.outMode|enableVirtualTerminalProcessing); err != nil { | ||||
| 		return err | ||||
| 	// First attempt both enableVirtualTerminalProcessing and disableNewlineAutoReturn | ||||
| 	if err := winterm.SetConsoleMode(uintptr(state.outHandle), | ||||
| 		state.outMode|(enableVirtualTerminalProcessing|disableNewlineAutoReturn)); err != nil { | ||||
| 
 | ||||
| 		// That may fail, so fallback to trying just enableVirtualTerminalProcessing | ||||
| 		if err := winterm.SetConsoleMode(uintptr(state.outHandle), state.outMode|enableVirtualTerminalProcessing); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if err := winterm.SetConsoleMode(uintptr(state.inHandle), state.inMode|enableVirtualTerminalInput); err != nil { | ||||
|  | @ -187,8 +184,7 @@ func GetWinsize(fd uintptr) (*Winsize, error) { | |||
| 	winsize := &Winsize{ | ||||
| 		Width:  uint16(info.Window.Right - info.Window.Left + 1), | ||||
| 		Height: uint16(info.Window.Bottom - info.Window.Top + 1), | ||||
| 		x:      0, | ||||
| 		y:      0} | ||||
| 	} | ||||
| 
 | ||||
| 	return winsize, nil | ||||
| } | ||||
|  |  | |||
							
								
								
									
										191
									
								
								vendor/src/github.com/docker/go-connections/LICENSE
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								vendor/src/github.com/docker/go-connections/LICENSE
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,191 @@ | |||
| 
 | ||||
|                                  Apache License | ||||
|                            Version 2.0, January 2004 | ||||
|                         https://www.apache.org/licenses/ | ||||
| 
 | ||||
|    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | ||||
| 
 | ||||
|    1. Definitions. | ||||
| 
 | ||||
|       "License" shall mean the terms and conditions for use, reproduction, | ||||
|       and distribution as defined by Sections 1 through 9 of this document. | ||||
| 
 | ||||
|       "Licensor" shall mean the copyright owner or entity authorized by | ||||
|       the copyright owner that is granting the License. | ||||
| 
 | ||||
|       "Legal Entity" shall mean the union of the acting entity and all | ||||
|       other entities that control, are controlled by, or are under common | ||||
|       control with that entity. For the purposes of this definition, | ||||
|       "control" means (i) the power, direct or indirect, to cause the | ||||
|       direction or management of such entity, whether by contract or | ||||
|       otherwise, or (ii) ownership of fifty percent (50%) or more of the | ||||
|       outstanding shares, or (iii) beneficial ownership of such entity. | ||||
| 
 | ||||
|       "You" (or "Your") shall mean an individual or Legal Entity | ||||
|       exercising permissions granted by this License. | ||||
| 
 | ||||
|       "Source" form shall mean the preferred form for making modifications, | ||||
|       including but not limited to software source code, documentation | ||||
|       source, and configuration files. | ||||
| 
 | ||||
|       "Object" form shall mean any form resulting from mechanical | ||||
|       transformation or translation of a Source form, including but | ||||
|       not limited to compiled object code, generated documentation, | ||||
|       and conversions to other media types. | ||||
| 
 | ||||
|       "Work" shall mean the work of authorship, whether in Source or | ||||
|       Object form, made available under the License, as indicated by a | ||||
|       copyright notice that is included in or attached to the work | ||||
|       (an example is provided in the Appendix below). | ||||
| 
 | ||||
|       "Derivative Works" shall mean any work, whether in Source or Object | ||||
|       form, that is based on (or derived from) the Work and for which the | ||||
|       editorial revisions, annotations, elaborations, or other modifications | ||||
|       represent, as a whole, an original work of authorship. For the purposes | ||||
|       of this License, Derivative Works shall not include works that remain | ||||
|       separable from, or merely link (or bind by name) to the interfaces of, | ||||
|       the Work and Derivative Works thereof. | ||||
| 
 | ||||
|       "Contribution" shall mean any work of authorship, including | ||||
|       the original version of the Work and any modifications or additions | ||||
|       to that Work or Derivative Works thereof, that is intentionally | ||||
|       submitted to Licensor for inclusion in the Work by the copyright owner | ||||
|       or by an individual or Legal Entity authorized to submit on behalf of | ||||
|       the copyright owner. For the purposes of this definition, "submitted" | ||||
|       means any form of electronic, verbal, or written communication sent | ||||
|       to the Licensor or its representatives, including but not limited to | ||||
|       communication on electronic mailing lists, source code control systems, | ||||
|       and issue tracking systems that are managed by, or on behalf of, the | ||||
|       Licensor for the purpose of discussing and improving the Work, but | ||||
|       excluding communication that is conspicuously marked or otherwise | ||||
|       designated in writing by the copyright owner as "Not a Contribution." | ||||
| 
 | ||||
|       "Contributor" shall mean Licensor and any individual or Legal Entity | ||||
|       on behalf of whom a Contribution has been received by Licensor and | ||||
|       subsequently incorporated within the Work. | ||||
| 
 | ||||
|    2. Grant of Copyright License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       copyright license to reproduce, prepare Derivative Works of, | ||||
|       publicly display, publicly perform, sublicense, and distribute the | ||||
|       Work and such Derivative Works in Source or Object form. | ||||
| 
 | ||||
|    3. Grant of Patent License. Subject to the terms and conditions of | ||||
|       this License, each Contributor hereby grants to You a perpetual, | ||||
|       worldwide, non-exclusive, no-charge, royalty-free, irrevocable | ||||
|       (except as stated in this section) patent license to make, have made, | ||||
|       use, offer to sell, sell, import, and otherwise transfer the Work, | ||||
|       where such license applies only to those patent claims licensable | ||||
|       by such Contributor that are necessarily infringed by their | ||||
|       Contribution(s) alone or by combination of their Contribution(s) | ||||
|       with the Work to which such Contribution(s) was submitted. If You | ||||
|       institute patent litigation against any entity (including a | ||||
|       cross-claim or counterclaim in a lawsuit) alleging that the Work | ||||
|       or a Contribution incorporated within the Work constitutes direct | ||||
|       or contributory patent infringement, then any patent licenses | ||||
|       granted to You under this License for that Work shall terminate | ||||
|       as of the date such litigation is filed. | ||||
| 
 | ||||
|    4. Redistribution. You may reproduce and distribute copies of the | ||||
|       Work or Derivative Works thereof in any medium, with or without | ||||
|       modifications, and in Source or Object form, provided that You | ||||
|       meet the following conditions: | ||||
| 
 | ||||
|       (a) You must give any other recipients of the Work or | ||||
|           Derivative Works a copy of this License; and | ||||
| 
 | ||||
|       (b) You must cause any modified files to carry prominent notices | ||||
|           stating that You changed the files; and | ||||
| 
 | ||||
|       (c) You must retain, in the Source form of any Derivative Works | ||||
|           that You distribute, all copyright, patent, trademark, and | ||||
|           attribution notices from the Source form of the Work, | ||||
|           excluding those notices that do not pertain to any part of | ||||
|           the Derivative Works; and | ||||
| 
 | ||||
|       (d) If the Work includes a "NOTICE" text file as part of its | ||||
|           distribution, then any Derivative Works that You distribute must | ||||
|           include a readable copy of the attribution notices contained | ||||
|           within such NOTICE file, excluding those notices that do not | ||||
|           pertain to any part of the Derivative Works, in at least one | ||||
|           of the following places: within a NOTICE text file distributed | ||||
|           as part of the Derivative Works; within the Source form or | ||||
|           documentation, if provided along with the Derivative Works; or, | ||||
|           within a display generated by the Derivative Works, if and | ||||
|           wherever such third-party notices normally appear. The contents | ||||
|           of the NOTICE file are for informational purposes only and | ||||
|           do not modify the License. You may add Your own attribution | ||||
|           notices within Derivative Works that You distribute, alongside | ||||
|           or as an addendum to the NOTICE text from the Work, provided | ||||
|           that such additional attribution notices cannot be construed | ||||
|           as modifying the License. | ||||
| 
 | ||||
|       You may add Your own copyright statement to Your modifications and | ||||
|       may provide additional or different license terms and conditions | ||||
|       for use, reproduction, or distribution of Your modifications, or | ||||
|       for any such Derivative Works as a whole, provided Your use, | ||||
|       reproduction, and distribution of the Work otherwise complies with | ||||
|       the conditions stated in this License. | ||||
| 
 | ||||
|    5. Submission of Contributions. Unless You explicitly state otherwise, | ||||
|       any Contribution intentionally submitted for inclusion in the Work | ||||
|       by You to the Licensor shall be under the terms and conditions of | ||||
|       this License, without any additional terms or conditions. | ||||
|       Notwithstanding the above, nothing herein shall supersede or modify | ||||
|       the terms of any separate license agreement you may have executed | ||||
|       with Licensor regarding such Contributions. | ||||
| 
 | ||||
|    6. Trademarks. This License does not grant permission to use the trade | ||||
|       names, trademarks, service marks, or product names of the Licensor, | ||||
|       except as required for reasonable and customary use in describing the | ||||
|       origin of the Work and reproducing the content of the NOTICE file. | ||||
| 
 | ||||
|    7. Disclaimer of Warranty. Unless required by applicable law or | ||||
|       agreed to in writing, Licensor provides the Work (and each | ||||
|       Contributor provides its Contributions) on an "AS IS" BASIS, | ||||
|       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||||
|       implied, including, without limitation, any warranties or conditions | ||||
|       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | ||||
|       PARTICULAR PURPOSE. You are solely responsible for determining the | ||||
|       appropriateness of using or redistributing the Work and assume any | ||||
|       risks associated with Your exercise of permissions under this License. | ||||
| 
 | ||||
|    8. Limitation of Liability. In no event and under no legal theory, | ||||
|       whether in tort (including negligence), contract, or otherwise, | ||||
|       unless required by applicable law (such as deliberate and grossly | ||||
|       negligent acts) or agreed to in writing, shall any Contributor be | ||||
|       liable to You for damages, including any direct, indirect, special, | ||||
|       incidental, or consequential damages of any character arising as a | ||||
|       result of this License or out of the use or inability to use the | ||||
|       Work (including but not limited to damages for loss of goodwill, | ||||
|       work stoppage, computer failure or malfunction, or any and all | ||||
|       other commercial damages or losses), even if such Contributor | ||||
|       has been advised of the possibility of such damages. | ||||
| 
 | ||||
|    9. Accepting Warranty or Additional Liability. While redistributing | ||||
|       the Work or Derivative Works thereof, You may choose to offer, | ||||
|       and charge a fee for, acceptance of support, warranty, indemnity, | ||||
|       or other liability obligations and/or rights consistent with this | ||||
|       License. However, in accepting such obligations, You may act only | ||||
|       on Your own behalf and on Your sole responsibility, not on behalf | ||||
|       of any other Contributor, and only if You agree to indemnify, | ||||
|       defend, and hold each Contributor harmless for any liability | ||||
|       incurred by, or claims asserted against, such Contributor by reason | ||||
|       of your accepting any such warranty or additional liability. | ||||
| 
 | ||||
|    END OF TERMS AND CONDITIONS | ||||
| 
 | ||||
|    Copyright 2015 Docker, Inc. | ||||
| 
 | ||||
|    Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|    you may not use this file except in compliance with the License. | ||||
|    You may obtain a copy of the License at | ||||
| 
 | ||||
|        https://www.apache.org/licenses/LICENSE-2.0 | ||||
| 
 | ||||
|    Unless required by applicable law or agreed to in writing, software | ||||
|    distributed under the License is distributed on an "AS IS" BASIS, | ||||
|    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|    See the License for the specific language governing permissions and | ||||
|    limitations under the License. | ||||
							
								
								
									
										0
									
								
								vendor/src/github.com/docker/go-connections/sockets/README.md
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								vendor/src/github.com/docker/go-connections/sockets/README.md
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
								
								
									
										89
									
								
								vendor/src/github.com/docker/go-connections/sockets/inmem_socket.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								vendor/src/github.com/docker/go-connections/sockets/inmem_socket.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,89 @@ | |||
| package sockets | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"net" | ||||
| 	"sync" | ||||
| ) | ||||
| 
 | ||||
| var errClosed = errors.New("use of closed network connection") | ||||
| 
 | ||||
| // InmemSocket implements net.Listener using in-memory only connections. | ||||
| type InmemSocket struct { | ||||
| 	chConn  chan net.Conn | ||||
| 	chClose chan struct{} | ||||
| 	addr    string | ||||
| 	mu      sync.Mutex | ||||
| } | ||||
| 
 | ||||
| // dummyAddr is used to satisfy net.Addr for the in-mem socket | ||||
| // it is just stored as a string and returns the string for all calls | ||||
| type dummyAddr string | ||||
| 
 | ||||
| // NewInmemSocket creates an in-memory only net.Listener | ||||
| // The addr argument can be any string, but is used to satisfy the `Addr()` part | ||||
| // of the net.Listener interface | ||||
| func NewInmemSocket(addr string, bufSize int) *InmemSocket { | ||||
| 	return &InmemSocket{ | ||||
| 		chConn:  make(chan net.Conn, bufSize), | ||||
| 		chClose: make(chan struct{}), | ||||
| 		addr:    addr, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Addr returns the socket's addr string to satisfy net.Listener | ||||
| func (s *InmemSocket) Addr() net.Addr { | ||||
| 	return dummyAddr(s.addr) | ||||
| } | ||||
| 
 | ||||
| // Accept implements the Accept method in the Listener interface; it waits for the next call and returns a generic Conn. | ||||
| func (s *InmemSocket) Accept() (net.Conn, error) { | ||||
| 	select { | ||||
| 	case conn := <-s.chConn: | ||||
| 		return conn, nil | ||||
| 	case <-s.chClose: | ||||
| 		return nil, errClosed | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Close closes the listener. It will be unavailable for use once closed. | ||||
| func (s *InmemSocket) Close() error { | ||||
| 	s.mu.Lock() | ||||
| 	defer s.mu.Unlock() | ||||
| 	select { | ||||
| 	case <-s.chClose: | ||||
| 	default: | ||||
| 		close(s.chClose) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // Dial is used to establish a connection with the in-mem server | ||||
| func (s *InmemSocket) Dial(network, addr string) (net.Conn, error) { | ||||
| 	srvConn, clientConn := net.Pipe() | ||||
| 	select { | ||||
| 	case s.chConn <- srvConn: | ||||
| 	case <-s.chClose: | ||||
| 		return nil, errClosed | ||||
| 	} | ||||
| 
 | ||||
| 	return clientConn, nil | ||||
| } | ||||
| 
 | ||||
| // Network returns the addr string, satisfies net.Addr | ||||
| func (a dummyAddr) Network() string { | ||||
| 	return string(a) | ||||
| } | ||||
| 
 | ||||
| // String returns the string form | ||||
| func (a dummyAddr) String() string { | ||||
| 	return string(a) | ||||
| } | ||||
| 
 | ||||
| // timeoutError is used when there is a timeout with a connection | ||||
| // this implements the net.Error interface | ||||
| type timeoutError struct{} | ||||
| 
 | ||||
| func (e *timeoutError) Error() string   { return "i/o timeout" } | ||||
| func (e *timeoutError) Timeout() bool   { return true } | ||||
| func (e *timeoutError) Temporary() bool { return true } | ||||
							
								
								
									
										51
									
								
								vendor/src/github.com/docker/go-connections/sockets/proxy.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								vendor/src/github.com/docker/go-connections/sockets/proxy.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | |||
| package sockets | ||||
| 
 | ||||
| import ( | ||||
| 	"net" | ||||
| 	"net/url" | ||||
| 	"os" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"golang.org/x/net/proxy" | ||||
| ) | ||||
| 
 | ||||
| // GetProxyEnv allows access to the uppercase and the lowercase forms of | ||||
| // proxy-related variables.  See the Go specification for details on these | ||||
| // variables. https://golang.org/pkg/net/http/ | ||||
| func GetProxyEnv(key string) string { | ||||
| 	proxyValue := os.Getenv(strings.ToUpper(key)) | ||||
| 	if proxyValue == "" { | ||||
| 		return os.Getenv(strings.ToLower(key)) | ||||
| 	} | ||||
| 	return proxyValue | ||||
| } | ||||
| 
 | ||||
| // DialerFromEnvironment takes in a "direct" *net.Dialer and returns a | ||||
| // proxy.Dialer which will route the connections through the proxy using the | ||||
| // given dialer. | ||||
| func DialerFromEnvironment(direct *net.Dialer) (proxy.Dialer, error) { | ||||
| 	allProxy := GetProxyEnv("all_proxy") | ||||
| 	if len(allProxy) == 0 { | ||||
| 		return direct, nil | ||||
| 	} | ||||
| 
 | ||||
| 	proxyURL, err := url.Parse(allProxy) | ||||
| 	if err != nil { | ||||
| 		return direct, err | ||||
| 	} | ||||
| 
 | ||||
| 	proxyFromURL, err := proxy.FromURL(proxyURL, direct) | ||||
| 	if err != nil { | ||||
| 		return direct, err | ||||
| 	} | ||||
| 
 | ||||
| 	noProxy := GetProxyEnv("no_proxy") | ||||
| 	if len(noProxy) == 0 { | ||||
| 		return proxyFromURL, nil | ||||
| 	} | ||||
| 
 | ||||
| 	perHost := proxy.NewPerHost(proxyFromURL, direct) | ||||
| 	perHost.AddFromString(noProxy) | ||||
| 
 | ||||
| 	return perHost, nil | ||||
| } | ||||
							
								
								
									
										42
									
								
								vendor/src/github.com/docker/go-connections/sockets/sockets.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								vendor/src/github.com/docker/go-connections/sockets/sockets.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | |||
| // Package sockets provides helper functions to create and configure Unix or TCP sockets. | ||||
| package sockets | ||||
| 
 | ||||
| import ( | ||||
| 	"net" | ||||
| 	"net/http" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| // Why 32? See https://github.com/docker/docker/pull/8035. | ||||
| const defaultTimeout = 32 * time.Second | ||||
| 
 | ||||
| // ConfigureTransport configures the specified Transport according to the | ||||
| // specified proto and addr. | ||||
| // If the proto is unix (using a unix socket to communicate) or npipe the | ||||
| // compression is disabled. | ||||
| func ConfigureTransport(tr *http.Transport, proto, addr string) error { | ||||
| 	switch proto { | ||||
| 	case "unix": | ||||
| 		// No need for compression in local communications. | ||||
| 		tr.DisableCompression = true | ||||
| 		tr.Dial = func(_, _ string) (net.Conn, error) { | ||||
| 			return net.DialTimeout(proto, addr, defaultTimeout) | ||||
| 		} | ||||
| 	case "npipe": | ||||
| 		// No need for compression in local communications. | ||||
| 		tr.DisableCompression = true | ||||
| 		tr.Dial = func(_, _ string) (net.Conn, error) { | ||||
| 			return DialPipe(addr, defaultTimeout) | ||||
| 		} | ||||
| 	default: | ||||
| 		tr.Proxy = http.ProxyFromEnvironment | ||||
| 		dialer, err := DialerFromEnvironment(&net.Dialer{ | ||||
| 			Timeout: defaultTimeout, | ||||
| 		}) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		tr.Dial = dialer.Dial | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										15
									
								
								vendor/src/github.com/docker/go-connections/sockets/sockets_unix.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/src/github.com/docker/go-connections/sockets/sockets_unix.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| // +build !windows | ||||
| 
 | ||||
| package sockets | ||||
| 
 | ||||
| import ( | ||||
| 	"net" | ||||
| 	"syscall" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| // DialPipe connects to a Windows named pipe. | ||||
| // This is not supported on other OSes. | ||||
| func DialPipe(_ string, _ time.Duration) (net.Conn, error) { | ||||
| 	return nil, syscall.EAFNOSUPPORT | ||||
| } | ||||
							
								
								
									
										13
									
								
								vendor/src/github.com/docker/go-connections/sockets/sockets_windows.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/src/github.com/docker/go-connections/sockets/sockets_windows.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| package sockets | ||||
| 
 | ||||
| import ( | ||||
| 	"net" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/Microsoft/go-winio" | ||||
| ) | ||||
| 
 | ||||
| // DialPipe connects to a Windows named pipe. | ||||
| func DialPipe(addr string, timeout time.Duration) (net.Conn, error) { | ||||
| 	return winio.DialPipe(addr, &timeout) | ||||
| } | ||||
							
								
								
									
										22
									
								
								vendor/src/github.com/docker/go-connections/sockets/tcp_socket.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vendor/src/github.com/docker/go-connections/sockets/tcp_socket.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| // Package sockets provides helper functions to create and configure Unix or TCP sockets. | ||||
| package sockets | ||||
| 
 | ||||
| import ( | ||||
| 	"crypto/tls" | ||||
| 	"net" | ||||
| ) | ||||
| 
 | ||||
| // NewTCPSocket creates a TCP socket listener with the specified address and | ||||
| // and the specified tls configuration. If TLSConfig is set, will encapsulate the | ||||
| // TCP listener inside a TLS one. | ||||
| func NewTCPSocket(addr string, tlsConfig *tls.Config) (net.Listener, error) { | ||||
| 	l, err := net.Listen("tcp", addr) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if tlsConfig != nil { | ||||
| 		tlsConfig.NextProtos = []string{"http/1.1"} | ||||
| 		l = tls.NewListener(l, tlsConfig) | ||||
| 	} | ||||
| 	return l, nil | ||||
| } | ||||
							
								
								
									
										80
									
								
								vendor/src/github.com/docker/go-connections/sockets/unix_socket.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								vendor/src/github.com/docker/go-connections/sockets/unix_socket.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,80 @@ | |||
| // +build linux freebsd solaris | ||||
| 
 | ||||
| package sockets | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net" | ||||
| 	"os" | ||||
| 	"strconv" | ||||
| 	"syscall" | ||||
| 
 | ||||
| 	"github.com/Sirupsen/logrus" | ||||
| 	"github.com/opencontainers/runc/libcontainer/user" | ||||
| ) | ||||
| 
 | ||||
| // NewUnixSocket creates a unix socket with the specified path and group. | ||||
| func NewUnixSocket(path, group string) (net.Listener, error) { | ||||
| 	if err := syscall.Unlink(path); err != nil && !os.IsNotExist(err) { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	mask := syscall.Umask(0777) | ||||
| 	defer syscall.Umask(mask) | ||||
| 	l, err := net.Listen("unix", path) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if err := setSocketGroup(path, group); err != nil { | ||||
| 		l.Close() | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if err := os.Chmod(path, 0660); err != nil { | ||||
| 		l.Close() | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return l, nil | ||||
| } | ||||
| 
 | ||||
| func setSocketGroup(path, group string) error { | ||||
| 	if group == "" { | ||||
| 		return nil | ||||
| 	} | ||||
| 	if err := changeGroup(path, group); err != nil { | ||||
| 		if group != "docker" { | ||||
| 			return err | ||||
| 		} | ||||
| 		logrus.Debugf("Warning: could not change group %s to docker: %v", path, err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func changeGroup(path string, nameOrGid string) error { | ||||
| 	gid, err := lookupGidByName(nameOrGid) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	logrus.Debugf("%s group found. gid: %d", nameOrGid, gid) | ||||
| 	return os.Chown(path, 0, gid) | ||||
| } | ||||
| 
 | ||||
| func lookupGidByName(nameOrGid string) (int, error) { | ||||
| 	groupFile, err := user.GetGroupPath() | ||||
| 	if err != nil { | ||||
| 		return -1, err | ||||
| 	} | ||||
| 	groups, err := user.ParseGroupFileFilter(groupFile, func(g user.Group) bool { | ||||
| 		return g.Name == nameOrGid || strconv.Itoa(g.Gid) == nameOrGid | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return -1, err | ||||
| 	} | ||||
| 	if groups != nil && len(groups) > 0 { | ||||
| 		return groups[0].Gid, nil | ||||
| 	} | ||||
| 	gid, err := strconv.Atoi(nameOrGid) | ||||
| 	if err == nil { | ||||
| 		logrus.Warnf("Could not find GID %d", gid) | ||||
| 		return gid, nil | ||||
| 	} | ||||
| 	return -1, fmt.Errorf("Group %s not found", nameOrGid) | ||||
| } | ||||
							
								
								
									
										18
									
								
								vendor/src/golang.org/x/net/proxy/direct.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								vendor/src/golang.org/x/net/proxy/direct.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | |||
| // Copyright 2011 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package proxy | ||||
| 
 | ||||
| import ( | ||||
| 	"net" | ||||
| ) | ||||
| 
 | ||||
| type direct struct{} | ||||
| 
 | ||||
| // Direct is a direct proxy: one that makes network connections directly. | ||||
| var Direct = direct{} | ||||
| 
 | ||||
| func (direct) Dial(network, addr string) (net.Conn, error) { | ||||
| 	return net.Dial(network, addr) | ||||
| } | ||||
							
								
								
									
										140
									
								
								vendor/src/golang.org/x/net/proxy/per_host.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								vendor/src/golang.org/x/net/proxy/per_host.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,140 @@ | |||
| // Copyright 2011 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package proxy | ||||
| 
 | ||||
| import ( | ||||
| 	"net" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| // A PerHost directs connections to a default Dialer unless the hostname | ||||
| // requested matches one of a number of exceptions. | ||||
| type PerHost struct { | ||||
| 	def, bypass Dialer | ||||
| 
 | ||||
| 	bypassNetworks []*net.IPNet | ||||
| 	bypassIPs      []net.IP | ||||
| 	bypassZones    []string | ||||
| 	bypassHosts    []string | ||||
| } | ||||
| 
 | ||||
| // NewPerHost returns a PerHost Dialer that directs connections to either | ||||
| // defaultDialer or bypass, depending on whether the connection matches one of | ||||
| // the configured rules. | ||||
| func NewPerHost(defaultDialer, bypass Dialer) *PerHost { | ||||
| 	return &PerHost{ | ||||
| 		def:    defaultDialer, | ||||
| 		bypass: bypass, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Dial connects to the address addr on the given network through either | ||||
| // defaultDialer or bypass. | ||||
| func (p *PerHost) Dial(network, addr string) (c net.Conn, err error) { | ||||
| 	host, _, err := net.SplitHostPort(addr) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return p.dialerForRequest(host).Dial(network, addr) | ||||
| } | ||||
| 
 | ||||
| func (p *PerHost) dialerForRequest(host string) Dialer { | ||||
| 	if ip := net.ParseIP(host); ip != nil { | ||||
| 		for _, net := range p.bypassNetworks { | ||||
| 			if net.Contains(ip) { | ||||
| 				return p.bypass | ||||
| 			} | ||||
| 		} | ||||
| 		for _, bypassIP := range p.bypassIPs { | ||||
| 			if bypassIP.Equal(ip) { | ||||
| 				return p.bypass | ||||
| 			} | ||||
| 		} | ||||
| 		return p.def | ||||
| 	} | ||||
| 
 | ||||
| 	for _, zone := range p.bypassZones { | ||||
| 		if strings.HasSuffix(host, zone) { | ||||
| 			return p.bypass | ||||
| 		} | ||||
| 		if host == zone[1:] { | ||||
| 			// For a zone "example.com", we match "example.com" | ||||
| 			// too. | ||||
| 			return p.bypass | ||||
| 		} | ||||
| 	} | ||||
| 	for _, bypassHost := range p.bypassHosts { | ||||
| 		if bypassHost == host { | ||||
| 			return p.bypass | ||||
| 		} | ||||
| 	} | ||||
| 	return p.def | ||||
| } | ||||
| 
 | ||||
| // AddFromString parses a string that contains comma-separated values | ||||
| // specifying hosts that should use the bypass proxy. Each value is either an | ||||
| // IP address, a CIDR range, a zone (*.example.com) or a hostname | ||||
| // (localhost). A best effort is made to parse the string and errors are | ||||
| // ignored. | ||||
| func (p *PerHost) AddFromString(s string) { | ||||
| 	hosts := strings.Split(s, ",") | ||||
| 	for _, host := range hosts { | ||||
| 		host = strings.TrimSpace(host) | ||||
| 		if len(host) == 0 { | ||||
| 			continue | ||||
| 		} | ||||
| 		if strings.Contains(host, "/") { | ||||
| 			// We assume that it's a CIDR address like 127.0.0.0/8 | ||||
| 			if _, net, err := net.ParseCIDR(host); err == nil { | ||||
| 				p.AddNetwork(net) | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
| 		if ip := net.ParseIP(host); ip != nil { | ||||
| 			p.AddIP(ip) | ||||
| 			continue | ||||
| 		} | ||||
| 		if strings.HasPrefix(host, "*.") { | ||||
| 			p.AddZone(host[1:]) | ||||
| 			continue | ||||
| 		} | ||||
| 		p.AddHost(host) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // AddIP specifies an IP address that will use the bypass proxy. Note that | ||||
| // this will only take effect if a literal IP address is dialed. A connection | ||||
| // to a named host will never match an IP. | ||||
| func (p *PerHost) AddIP(ip net.IP) { | ||||
| 	p.bypassIPs = append(p.bypassIPs, ip) | ||||
| } | ||||
| 
 | ||||
| // AddNetwork specifies an IP range that will use the bypass proxy. Note that | ||||
| // this will only take effect if a literal IP address is dialed. A connection | ||||
| // to a named host will never match. | ||||
| func (p *PerHost) AddNetwork(net *net.IPNet) { | ||||
| 	p.bypassNetworks = append(p.bypassNetworks, net) | ||||
| } | ||||
| 
 | ||||
| // AddZone specifies a DNS suffix that will use the bypass proxy. A zone of | ||||
| // "example.com" matches "example.com" and all of its subdomains. | ||||
| func (p *PerHost) AddZone(zone string) { | ||||
| 	if strings.HasSuffix(zone, ".") { | ||||
| 		zone = zone[:len(zone)-1] | ||||
| 	} | ||||
| 	if !strings.HasPrefix(zone, ".") { | ||||
| 		zone = "." + zone | ||||
| 	} | ||||
| 	p.bypassZones = append(p.bypassZones, zone) | ||||
| } | ||||
| 
 | ||||
| // AddHost specifies a hostname that will use the bypass proxy. | ||||
| func (p *PerHost) AddHost(host string) { | ||||
| 	if strings.HasSuffix(host, ".") { | ||||
| 		host = host[:len(host)-1] | ||||
| 	} | ||||
| 	p.bypassHosts = append(p.bypassHosts, host) | ||||
| } | ||||
							
								
								
									
										94
									
								
								vendor/src/golang.org/x/net/proxy/proxy.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								vendor/src/golang.org/x/net/proxy/proxy.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,94 @@ | |||
| // Copyright 2011 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| // Package proxy provides support for a variety of protocols to proxy network | ||||
| // data. | ||||
| package proxy // import "golang.org/x/net/proxy" | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"net" | ||||
| 	"net/url" | ||||
| 	"os" | ||||
| ) | ||||
| 
 | ||||
| // A Dialer is a means to establish a connection. | ||||
| type Dialer interface { | ||||
| 	// Dial connects to the given address via the proxy. | ||||
| 	Dial(network, addr string) (c net.Conn, err error) | ||||
| } | ||||
| 
 | ||||
| // Auth contains authentication parameters that specific Dialers may require. | ||||
| type Auth struct { | ||||
| 	User, Password string | ||||
| } | ||||
| 
 | ||||
| // FromEnvironment returns the dialer specified by the proxy related variables in | ||||
| // the environment. | ||||
| func FromEnvironment() Dialer { | ||||
| 	allProxy := os.Getenv("all_proxy") | ||||
| 	if len(allProxy) == 0 { | ||||
| 		return Direct | ||||
| 	} | ||||
| 
 | ||||
| 	proxyURL, err := url.Parse(allProxy) | ||||
| 	if err != nil { | ||||
| 		return Direct | ||||
| 	} | ||||
| 	proxy, err := FromURL(proxyURL, Direct) | ||||
| 	if err != nil { | ||||
| 		return Direct | ||||
| 	} | ||||
| 
 | ||||
| 	noProxy := os.Getenv("no_proxy") | ||||
| 	if len(noProxy) == 0 { | ||||
| 		return proxy | ||||
| 	} | ||||
| 
 | ||||
| 	perHost := NewPerHost(proxy, Direct) | ||||
| 	perHost.AddFromString(noProxy) | ||||
| 	return perHost | ||||
| } | ||||
| 
 | ||||
| // proxySchemes is a map from URL schemes to a function that creates a Dialer | ||||
| // from a URL with such a scheme. | ||||
| var proxySchemes map[string]func(*url.URL, Dialer) (Dialer, error) | ||||
| 
 | ||||
| // RegisterDialerType takes a URL scheme and a function to generate Dialers from | ||||
| // a URL with that scheme and a forwarding Dialer. Registered schemes are used | ||||
| // by FromURL. | ||||
| func RegisterDialerType(scheme string, f func(*url.URL, Dialer) (Dialer, error)) { | ||||
| 	if proxySchemes == nil { | ||||
| 		proxySchemes = make(map[string]func(*url.URL, Dialer) (Dialer, error)) | ||||
| 	} | ||||
| 	proxySchemes[scheme] = f | ||||
| } | ||||
| 
 | ||||
| // FromURL returns a Dialer given a URL specification and an underlying | ||||
| // Dialer for it to make network requests. | ||||
| func FromURL(u *url.URL, forward Dialer) (Dialer, error) { | ||||
| 	var auth *Auth | ||||
| 	if u.User != nil { | ||||
| 		auth = new(Auth) | ||||
| 		auth.User = u.User.Username() | ||||
| 		if p, ok := u.User.Password(); ok { | ||||
| 			auth.Password = p | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	switch u.Scheme { | ||||
| 	case "socks5": | ||||
| 		return SOCKS5("tcp", u.Host, auth, forward) | ||||
| 	} | ||||
| 
 | ||||
| 	// If the scheme doesn't match any of the built-in schemes, see if it | ||||
| 	// was registered by another package. | ||||
| 	if proxySchemes != nil { | ||||
| 		if f, ok := proxySchemes[u.Scheme]; ok { | ||||
| 			return f(u, forward) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return nil, errors.New("proxy: unknown scheme: " + u.Scheme) | ||||
| } | ||||
							
								
								
									
										210
									
								
								vendor/src/golang.org/x/net/proxy/socks5.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								vendor/src/golang.org/x/net/proxy/socks5.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,210 @@ | |||
| // Copyright 2011 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package proxy | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"io" | ||||
| 	"net" | ||||
| 	"strconv" | ||||
| ) | ||||
| 
 | ||||
| // SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address | ||||
| // with an optional username and password. See RFC 1928. | ||||
| func SOCKS5(network, addr string, auth *Auth, forward Dialer) (Dialer, error) { | ||||
| 	s := &socks5{ | ||||
| 		network: network, | ||||
| 		addr:    addr, | ||||
| 		forward: forward, | ||||
| 	} | ||||
| 	if auth != nil { | ||||
| 		s.user = auth.User | ||||
| 		s.password = auth.Password | ||||
| 	} | ||||
| 
 | ||||
| 	return s, nil | ||||
| } | ||||
| 
 | ||||
| type socks5 struct { | ||||
| 	user, password string | ||||
| 	network, addr  string | ||||
| 	forward        Dialer | ||||
| } | ||||
| 
 | ||||
| const socks5Version = 5 | ||||
| 
 | ||||
| const ( | ||||
| 	socks5AuthNone     = 0 | ||||
| 	socks5AuthPassword = 2 | ||||
| ) | ||||
| 
 | ||||
| const socks5Connect = 1 | ||||
| 
 | ||||
| const ( | ||||
| 	socks5IP4    = 1 | ||||
| 	socks5Domain = 3 | ||||
| 	socks5IP6    = 4 | ||||
| ) | ||||
| 
 | ||||
| var socks5Errors = []string{ | ||||
| 	"", | ||||
| 	"general failure", | ||||
| 	"connection forbidden", | ||||
| 	"network unreachable", | ||||
| 	"host unreachable", | ||||
| 	"connection refused", | ||||
| 	"TTL expired", | ||||
| 	"command not supported", | ||||
| 	"address type not supported", | ||||
| } | ||||
| 
 | ||||
| // Dial connects to the address addr on the network net via the SOCKS5 proxy. | ||||
| func (s *socks5) Dial(network, addr string) (net.Conn, error) { | ||||
| 	switch network { | ||||
| 	case "tcp", "tcp6", "tcp4": | ||||
| 	default: | ||||
| 		return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network) | ||||
| 	} | ||||
| 
 | ||||
| 	conn, err := s.forward.Dial(s.network, s.addr) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	closeConn := &conn | ||||
| 	defer func() { | ||||
| 		if closeConn != nil { | ||||
| 			(*closeConn).Close() | ||||
| 		} | ||||
| 	}() | ||||
| 
 | ||||
| 	host, portStr, err := net.SplitHostPort(addr) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	port, err := strconv.Atoi(portStr) | ||||
| 	if err != nil { | ||||
| 		return nil, errors.New("proxy: failed to parse port number: " + portStr) | ||||
| 	} | ||||
| 	if port < 1 || port > 0xffff { | ||||
| 		return nil, errors.New("proxy: port number out of range: " + portStr) | ||||
| 	} | ||||
| 
 | ||||
| 	// the size here is just an estimate | ||||
| 	buf := make([]byte, 0, 6+len(host)) | ||||
| 
 | ||||
| 	buf = append(buf, socks5Version) | ||||
| 	if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 { | ||||
| 		buf = append(buf, 2 /* num auth methods */, socks5AuthNone, socks5AuthPassword) | ||||
| 	} else { | ||||
| 		buf = append(buf, 1 /* num auth methods */, socks5AuthNone) | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err := conn.Write(buf); err != nil { | ||||
| 		return nil, errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err := io.ReadFull(conn, buf[:2]); err != nil { | ||||
| 		return nil, errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error()) | ||||
| 	} | ||||
| 	if buf[0] != 5 { | ||||
| 		return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0]))) | ||||
| 	} | ||||
| 	if buf[1] == 0xff { | ||||
| 		return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication") | ||||
| 	} | ||||
| 
 | ||||
| 	if buf[1] == socks5AuthPassword { | ||||
| 		buf = buf[:0] | ||||
| 		buf = append(buf, 1 /* password protocol version */) | ||||
| 		buf = append(buf, uint8(len(s.user))) | ||||
| 		buf = append(buf, s.user...) | ||||
| 		buf = append(buf, uint8(len(s.password))) | ||||
| 		buf = append(buf, s.password...) | ||||
| 
 | ||||
| 		if _, err := conn.Write(buf); err != nil { | ||||
| 			return nil, errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) | ||||
| 		} | ||||
| 
 | ||||
| 		if _, err := io.ReadFull(conn, buf[:2]); err != nil { | ||||
| 			return nil, errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) | ||||
| 		} | ||||
| 
 | ||||
| 		if buf[1] != 0 { | ||||
| 			return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	buf = buf[:0] | ||||
| 	buf = append(buf, socks5Version, socks5Connect, 0 /* reserved */) | ||||
| 
 | ||||
| 	if ip := net.ParseIP(host); ip != nil { | ||||
| 		if ip4 := ip.To4(); ip4 != nil { | ||||
| 			buf = append(buf, socks5IP4) | ||||
| 			ip = ip4 | ||||
| 		} else { | ||||
| 			buf = append(buf, socks5IP6) | ||||
| 		} | ||||
| 		buf = append(buf, ip...) | ||||
| 	} else { | ||||
| 		if len(host) > 255 { | ||||
| 			return nil, errors.New("proxy: destination hostname too long: " + host) | ||||
| 		} | ||||
| 		buf = append(buf, socks5Domain) | ||||
| 		buf = append(buf, byte(len(host))) | ||||
| 		buf = append(buf, host...) | ||||
| 	} | ||||
| 	buf = append(buf, byte(port>>8), byte(port)) | ||||
| 
 | ||||
| 	if _, err := conn.Write(buf); err != nil { | ||||
| 		return nil, errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err := io.ReadFull(conn, buf[:4]); err != nil { | ||||
| 		return nil, errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	failure := "unknown error" | ||||
| 	if int(buf[1]) < len(socks5Errors) { | ||||
| 		failure = socks5Errors[buf[1]] | ||||
| 	} | ||||
| 
 | ||||
| 	if len(failure) > 0 { | ||||
| 		return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure) | ||||
| 	} | ||||
| 
 | ||||
| 	bytesToDiscard := 0 | ||||
| 	switch buf[3] { | ||||
| 	case socks5IP4: | ||||
| 		bytesToDiscard = net.IPv4len | ||||
| 	case socks5IP6: | ||||
| 		bytesToDiscard = net.IPv6len | ||||
| 	case socks5Domain: | ||||
| 		_, err := io.ReadFull(conn, buf[:1]) | ||||
| 		if err != nil { | ||||
| 			return nil, errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error()) | ||||
| 		} | ||||
| 		bytesToDiscard = int(buf[0]) | ||||
| 	default: | ||||
| 		return nil, errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr) | ||||
| 	} | ||||
| 
 | ||||
| 	if cap(buf) < bytesToDiscard { | ||||
| 		buf = make([]byte, bytesToDiscard) | ||||
| 	} else { | ||||
| 		buf = buf[:bytesToDiscard] | ||||
| 	} | ||||
| 	if _, err := io.ReadFull(conn, buf); err != nil { | ||||
| 		return nil, errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	// Also need to discard the port number | ||||
| 	if _, err := io.ReadFull(conn, buf[:2]); err != nil { | ||||
| 		return nil, errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error()) | ||||
| 	} | ||||
| 
 | ||||
| 	closeConn = nil | ||||
| 	return conn, nil | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue