github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/libkb/socket_windows.go (about)

     1  // Copyright 2015 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  //go:build windows
     5  // +build windows
     6  
     7  package libkb
     8  
     9  import (
    10  	"errors"
    11  	"net"
    12  	"path/filepath"
    13  	"strings"
    14  	"time"
    15  
    16  	"github.com/keybase/client/go/logger"
    17  	mspipe "github.com/keybase/go-winio"
    18  )
    19  
    20  func NewSocket(g *GlobalContext) (ret Socket, err error) {
    21  	var s string
    22  	s, err = g.Env.GetSocketBindFile()
    23  	if err != nil {
    24  		return
    25  	}
    26  	if len(s) == 0 {
    27  		err = errors.New("Empty SocketFile, can't make pipe")
    28  		return
    29  	}
    30  	s = `\\.\pipe\kbservice` + strings.TrimPrefix(s, filepath.VolumeName(s))
    31  	log := g.Log
    32  	if log == nil {
    33  		log = logger.NewNull()
    34  	}
    35  
    36  	// ownership tests fail when server is in same proces, as in tests
    37  	return SocketInfo{
    38  		log:       log,
    39  		bindFile:  s,
    40  		dialFiles: []string{s},
    41  		testOwner: g.Env.Test == nil,
    42  	}, nil
    43  }
    44  
    45  func NewSocketWithFiles(
    46  	log logger.Logger, bindFile string, _ []string) Socket {
    47  	s := `\\.\pipe\kbservice` +
    48  		strings.TrimPrefix(bindFile, filepath.VolumeName(bindFile))
    49  	return SocketInfo{
    50  		log:       log,
    51  		bindFile:  s,
    52  		dialFiles: []string{s},
    53  	}
    54  }
    55  
    56  func (s SocketInfo) BindToSocket() (ret net.Listener, err error) {
    57  	s.log.Info("Binding to pipe:%s", s.bindFile)
    58  	return mspipe.ListenPipe(s.bindFile, nil)
    59  }
    60  
    61  func (s SocketInfo) DialSocket() (ret net.Conn, err error) {
    62  	timeout := time.Duration(1) * time.Second
    63  	pipe, err := mspipe.DialPipe(s.dialFiles[0], &timeout)
    64  	if err != nil {
    65  		// Be sure to return a nil interface, and not a nil npipe.PipeConn
    66  		// See https://keybase.atlassian.net/browse/CORE-2675 for when this
    67  		// bit us.
    68  		return nil, err
    69  	}
    70  	// This can't happen right now, but in the future it might, so protect against ourselves
    71  	// so we don't get vexing (*foo)(nil)/interface{}(nil) bugs.
    72  	if pipe == nil {
    73  		return nil, errors.New("bad npipe result; nil npipe.PipeConn but no error")
    74  	}
    75  
    76  	// Test ownership
    77  	if s.testOwner {
    78  		owner, err := IsPipeowner(s.log, s.dialFiles[0])
    79  		if err != nil {
    80  			return nil, err
    81  		}
    82  		if !owner.IsOwner {
    83  			return nil, errors.New("failed to verify pipe ownership")
    84  		}
    85  	}
    86  	// Success case
    87  	return pipe, err
    88  }
    89  
    90  func IsSocketClosedError(e error) bool {
    91  	return e == mspipe.ErrPipeListenerClosed
    92  }