github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/pinentry/pinentry_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 pinentry
     8  
     9  import (
    10  	"fmt"
    11  	"os"
    12  	"os/exec"
    13  	"path/filepath"
    14  	"strings"
    15  
    16  	"github.com/keybase/client/go/logger"
    17  	"golang.org/x/sys/windows/registry"
    18  )
    19  
    20  func HasWindows() bool {
    21  	// We're assuming you aren't using Windows remotely.
    22  	return true
    23  }
    24  
    25  // LookPath searches for an executable binary named file
    26  // in the directories named by the PATH environment variable.
    27  // If file contains a slash, it is tried directly and the PATH is not consulted.
    28  
    29  func canExec(s string) error {
    30  	if strings.IndexAny(s, `:\/`) == -1 {
    31  		s += string(filepath.Separator)
    32  	}
    33  	_, err := exec.LookPath(s)
    34  	return err
    35  }
    36  
    37  func FindPinentry(log logger.Logger) (string, error) {
    38  
    39  	//		// If you install GPG you'll wind up with this pinentry
    40  	//		C:\Program Files (x86)\GNU\GnuPG\pinentry-gtk-2.exe
    41  	//		C:\Program Files (x86)\GNU\GnuPG\pinentry-qt4.exe
    42  	//		C:\Program Files (x86)\GNU\GnuPG\pinentry-w32.exe
    43  	//		C:\Program Files (x86)\GNU\GnuPG\pinentry.exe
    44  
    45  	k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Wow6432Node\GNU\GnuPG`, registry.QUERY_VALUE)
    46  	if err != nil {
    47  		k, err = registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\GNU\GnuPG`, registry.QUERY_VALUE)
    48  	}
    49  	if err != nil {
    50  		log.Debug("- FindPinentry: can't open registry")
    51  	}
    52  	defer k.Close()
    53  
    54  	installDir, _, err := k.GetStringValue("Install Directory")
    55  	if err != nil {
    56  		log.Debug("- FindPinentry: can't get string from registry")
    57  	}
    58  
    59  	extraPaths := []string{}
    60  
    61  	log.Debug("+ FindPinentry()")
    62  
    63  	cmds := []string{
    64  		"pinentry-gtk-2.exe",
    65  		"pinentry-qt4.exe",
    66  		"pinentry-w32.exe",
    67  		"pinentry.exe",
    68  	}
    69  
    70  	// First, look where the registry points
    71  	for _, c := range cmds {
    72  		full := filepath.Join(installDir, c)
    73  		log.Debug("| (registry) Looking for %s", full)
    74  		_, err := exec.LookPath(full)
    75  		if err == nil {
    76  			return full, nil
    77  		}
    78  	}
    79  
    80  	// Look in program files, just in case
    81  	extraPaths = append(extraPaths, os.Getenv("ProgramFiles"))
    82  	extraPaths = append(extraPaths, os.Getenv("ProgramFiles(x86)"))
    83  
    84  	for _, ep := range extraPaths {
    85  		for _, c := range cmds {
    86  			full := filepath.Join(ep, "GNU", "GnuPG", c)
    87  			log.Debug("| Looking for %s", full)
    88  			_, err := exec.LookPath(full)
    89  			if err == nil {
    90  				return full, nil
    91  			}
    92  		}
    93  	}
    94  
    95  	log.Debug("- FindPinentry: none found")
    96  	return "", fmt.Errorf("No pinentry found, checked a bunch of different places")
    97  }
    98  
    99  func (pe *Pinentry) GetTerminalName() {
   100  	pe.tty = "windows"
   101  }