private static string GetDefaultStore() { if (PlatformUtils.IsWindows()) { return(StoreNames.WindowsCredentialManager); } if (PlatformUtils.IsMacOS()) { return(StoreNames.MacOSKeychain); } // Other platforms have no default store return(null); }
private void ValidateGpgPass(out string storeRoot, out string execPath) { if (!PlatformUtils.IsPosix()) { throw new Exception( $"Can only use the '{StoreNames.Gpg}' credential store on POSIX systems." + Environment.NewLine + $"See {Constants.HelpUrls.GcmCredentialStores} for more information." ); } execPath = GetGpgPath(); // If we are in a headless environment, and don't have the GPG_TTY or SSH_TTY // variables set, then error - we need a TTY device path for pin-entry to work headless. if (!_context.SessionManager.IsDesktopSession && !_context.Environment.Variables.ContainsKey("GPG_TTY") && !_context.Environment.Variables.ContainsKey("SSH_TTY")) { throw new Exception( "GPG_TTY is not set; add `export GPG_TTY=$(tty)` to your profile." + Environment.NewLine + $"See {Constants.HelpUrls.GcmCredentialStores} for more information." ); } // Check for a redirected pass store location if (!_context.Settings.TryGetSetting( GpgPassCredentialStore.PasswordStoreDirEnvar, null, null, out storeRoot)) { // Use default store root at ~/.password-store storeRoot = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".password-store"); } // Check we have a GPG ID to sign credential files with string gpgIdFile = Path.Combine(storeRoot, ".gpg-id"); if (!_context.FileSystem.FileExists(gpgIdFile)) { throw new Exception( $"Password store has not been initialized at '{storeRoot}'; run `pass init <gpg-id>` to initialize the store." + Environment.NewLine + $"See {Constants.HelpUrls.GcmCredentialStores} for more information." ); } }
private string GetGitConfigAppPath() { string path = _appPath; // On Windows we must use UNIX style path separators if (PlatformUtils.IsWindows()) { path = path.Replace('\\', '/'); } // We must escape escape characters like ' ', '(', and ')' return(path .Replace(" ", "\\ ") .Replace("(", "\\(") .Replace(")", "\\)"));; }
private static string GetGitPath(IEnvironment environment, IFileSystem fileSystem) { string programName = PlatformUtils.IsWindows() ? "git.exe" : "git"; // Use the GIT_EXEC_PATH environment variable if set if (environment.Variables.TryGetValue(Constants.EnvironmentVariables.GitExecutablePath, out string gitExecPath)) { string candidatePath = Path.Combine(gitExecPath, programName); if (fileSystem.FileExists(candidatePath)) { return(candidatePath); } } // Otherwise try to locate the git(.exe) on the current PATH return(environment.LocateExecutable(programName)); }
protected override async Task <int> RunInternalAsync(string[] args) { var rootCommand = new RootCommand(); // Add standard commands rootCommand.AddCommand(new GetCommand(Context, _providerRegistry)); rootCommand.AddCommand(new StoreCommand(Context, _providerRegistry)); rootCommand.AddCommand(new EraseCommand(Context, _providerRegistry)); rootCommand.AddCommand(new ConfigureCommand(Context, _configurationService)); rootCommand.AddCommand(new UnconfigureCommand(Context, _configurationService)); // Add any custom provider commands foreach (ProviderCommand providerCommand in _providerCommands) { rootCommand.AddCommand(providerCommand); } // Trace the current version, OS, runtime, and program arguments PlatformInformation info = PlatformUtils.GetPlatformInformation(); Context.Trace.WriteLine($"Version: {Constants.GcmVersion}"); Context.Trace.WriteLine($"Runtime: {info.ClrVersion}"); Context.Trace.WriteLine($"Platform: {info.OperatingSystemType} ({info.CpuArchitecture})"); Context.Trace.WriteLine($"AppPath: {_appPath}"); Context.Trace.WriteLine($"Arguments: {string.Join(" ", args)}"); try { return(await rootCommand.InvokeAsync(args)); } catch (Exception e) { if (e is AggregateException ae) { ae.Handle(WriteException); } else { WriteException(e); } return(-1); } }
private static string GetApplicationPath() { Assembly entryAssembly = Assembly.GetExecutingAssembly(); if (entryAssembly is null) { throw new InvalidOperationException(); } string candidatePath = entryAssembly.Location; // Strip the .dll from assembly name on Mac and Linux if (!PlatformUtils.IsWindows() && Path.HasExtension(candidatePath)) { return(Path.ChangeExtension(candidatePath, null)); } return(candidatePath); }
protected override async Task <int> RunInternalAsync(string[] args) { var rootCommand = new RootCommand(); var diagnoseCommand = new DiagnoseCommand(Context); // Add standard commands rootCommand.AddCommand(new GetCommand(Context, _providerRegistry)); rootCommand.AddCommand(new StoreCommand(Context, _providerRegistry)); rootCommand.AddCommand(new EraseCommand(Context, _providerRegistry)); rootCommand.AddCommand(new ConfigureCommand(Context, _configurationService)); rootCommand.AddCommand(new UnconfigureCommand(Context, _configurationService)); rootCommand.AddCommand(diagnoseCommand); // Add any custom provider commands foreach (ProviderCommand providerCommand in _providerCommands) { rootCommand.AddCommand(providerCommand); } // Add any custom provider diagnostic tests foreach (IDiagnostic providerDiagnostic in _diagnostics) { diagnoseCommand.AddDiagnostic(providerDiagnostic); } // Trace the current version, OS, runtime, and program arguments PlatformInformation info = PlatformUtils.GetPlatformInformation(); Context.Trace.WriteLine($"Version: {Constants.GcmVersion}"); Context.Trace.WriteLine($"Runtime: {info.ClrVersion}"); Context.Trace.WriteLine($"Platform: {info.OperatingSystemType} ({info.CpuArchitecture})"); Context.Trace.WriteLine($"OSVersion: {info.OperatingSystemVersion}"); Context.Trace.WriteLine($"AppPath: {Context.ApplicationPath}"); Context.Trace.WriteLine($"Arguments: {string.Join(" ", args)}"); var parser = new CommandLineBuilder(rootCommand) .UseDefaults() .UseExceptionHandler(OnException) .Build(); return(await parser.InvokeAsync(args)); }
private void ValidateSecretService() { if (!PlatformUtils.IsLinux()) { throw new Exception( $"Can only use the '{StoreNames.SecretService}' credential store on Linux." + Environment.NewLine + $"See {Constants.HelpUrls.GcmCredentialStores} for more information." ); } if (!_context.SessionManager.IsDesktopSession) { throw new Exception( $"Cannot use the '{StoreNames.SecretService}' credential backing store without a graphical interface present." + Environment.NewLine + $"See {Constants.HelpUrls.GcmCredentialStores} for more information." ); } }
private void ValidateWindowsCredentialManager() { if (!PlatformUtils.IsWindows()) { throw new Exception( $"Can only use the '{StoreNames.WindowsCredentialManager}' credential store on Windows." + Environment.NewLine + $"See {Constants.HelpUrls.GcmCredentialStores} for more information." ); } if (!WindowsCredentialManager.CanPersist()) { throw new Exception( $"Unable to persist credentials with the '{StoreNames.WindowsCredentialManager}' credential store." + Environment.NewLine + $"See {Constants.HelpUrls.GcmCredentialStores} for more information." ); } }
public CommandContext() { Streams = new StandardStreams(); Trace = new Trace(); Git = new LibGit2(Trace); if (PlatformUtils.IsWindows()) { FileSystem = new WindowsFileSystem(); Environment = new WindowsEnvironment(FileSystem); Terminal = new WindowsTerminal(Trace); SessionManager = new WindowsSessionManager(); CredentialStore = WindowsCredentialManager.Open(); SystemPrompts = new WindowsSystemPrompts(); } else if (PlatformUtils.IsPosix()) { if (PlatformUtils.IsMacOS()) { FileSystem = new MacOSFileSystem(); SessionManager = new MacOSSessionManager(); CredentialStore = MacOSKeychain.Open(); SystemPrompts = new MacOSSystemPrompts(); } else if (PlatformUtils.IsLinux()) { throw new NotImplementedException(); } Environment = new PosixEnvironment(FileSystem); Terminal = new PosixTerminal(Trace); } string repoPath = Git.GetRepositoryPath(FileSystem.GetCurrentDirectory()); Settings = new Settings(Environment, Git, repoPath); HttpClientFactory = new HttpClientFactory(Trace, Settings, Streams); // Set the parent window handle/ID SystemPrompts.ParentWindowId = Settings.ParentWindowId; }
public override async Task <ICredential> GenerateCredentialAsync(InputArguments input) { ThrowIfDisposed(); Uri uri = GetUriFromInput(input); // Determine the if the host supports Windows Integration Authentication (WIA) if (IsWindowsAuthAllowed) { if (PlatformUtils.IsWindows()) { Context.Trace.WriteLine($"Checking host '{uri.AbsoluteUri}' for Windows Integrated Authentication..."); bool isWiaSupported = await _winAuth.GetIsSupportedAsync(uri); if (!isWiaSupported) { Context.Trace.WriteLine("Host does not support WIA."); } else { Context.Trace.WriteLine("Host supports WIA - generating empty credential..."); // WIA is signaled to Git using an empty username/password return(new GitCredential(string.Empty, string.Empty)); } } else { string osType = PlatformUtils.GetPlatformInformation().OperatingSystemType; Context.Trace.WriteLine($"Skipping check for Windows Integrated Authentication on {osType}."); } } else { Context.Trace.WriteLine("Windows Integrated Authentication detection has been disabled."); } Context.Trace.WriteLine("Prompting for basic credentials..."); return(_basicAuth.GetCredentials(uri.AbsoluteUri, uri.UserInfo)); }
private void ValidateDpapi(out string storeRoot) { if (!PlatformUtils.IsWindows()) { throw new Exception( $"Can only use the '{StoreNames.Dpapi}' credential store on Windows." + Environment.NewLine + $"See {Constants.HelpUrls.GcmCredentialStores} for more information." ); } // Check for a redirected credential store location if (!_context.Settings.TryGetSetting( Constants.EnvironmentVariables.GcmDpapiStorePath, Constants.GitConfiguration.Credential.SectionName, Constants.GitConfiguration.Credential.DpapiStorePath, out storeRoot)) { // Use default store root at ~/.gcm/dpapi_store storeRoot = Path.Combine(_context.FileSystem.UserDataDirectoryPath, "dpapi_store"); } }
/// <summary> /// Ensure the store root directory exists. If it does not, create a new directory with /// permissions that only permit the owner to read/write/execute. Permissions on an existing /// directory are not modified. /// </summary> private void EnsureStoreRoot() { if (FileSystem.DirectoryExists(StoreRoot)) { // Don't touch the permissions on the existing directory return; } FileSystem.CreateDirectory(StoreRoot); // We only set file system permissions on POSIX platforms if (!PlatformUtils.IsPosix()) { return; } // Set store root permissions such that only the owner can read/write/execute var mode = Interop.Posix.Native.NativeFileMode.S_IRUSR | Interop.Posix.Native.NativeFileMode.S_IWUSR | Interop.Posix.Native.NativeFileMode.S_IXUSR; // Ignore the return code.. this is a best effort only Interop.Posix.Native.Stat.chmod(StoreRoot, mode); }
/// <summary> /// Get standard program header title for Git Credential Manager, including the current version and OS information. /// </summary> /// <returns>Standard program header.</returns> public static string GetProgramHeader() { PlatformInformation info = PlatformUtils.GetPlatformInformation(); return($"Git Credential Manager version {GcmVersion} ({info.OperatingSystemType}, {info.ClrVersion})"); }
public CommandContext() { Streams = new StandardStreams(); Trace = new Trace(); if (PlatformUtils.IsWindows()) { FileSystem = new WindowsFileSystem(); SessionManager = new WindowsSessionManager(); SystemPrompts = new WindowsSystemPrompts(); Environment = new WindowsEnvironment(FileSystem); Terminal = new WindowsTerminal(Trace); string gitPath = GetGitPath(Environment, FileSystem); Git = new GitProcess( Trace, gitPath, FileSystem.GetCurrentDirectory() ); Settings = new Settings(Environment, Git); CredentialStore = new WindowsCredentialManager(Settings.CredentialNamespace); } else if (PlatformUtils.IsMacOS()) { FileSystem = new MacOSFileSystem(); SessionManager = new MacOSSessionManager(); SystemPrompts = new MacOSSystemPrompts(); Environment = new PosixEnvironment(FileSystem); Terminal = new PosixTerminal(Trace); string gitPath = GetGitPath(Environment, FileSystem); Git = new GitProcess( Trace, gitPath, FileSystem.GetCurrentDirectory() ); Settings = new Settings(Environment, Git); CredentialStore = new MacOSKeychain(Settings.CredentialNamespace); } else if (PlatformUtils.IsLinux()) { FileSystem = new LinuxFileSystem(); // TODO: support more than just 'Posix' or X11 SessionManager = new PosixSessionManager(); SystemPrompts = new LinuxSystemPrompts(); Environment = new PosixEnvironment(FileSystem); Terminal = new PosixTerminal(Trace); string gitPath = GetGitPath(Environment, FileSystem); Git = new GitProcess( Trace, gitPath, FileSystem.GetCurrentDirectory() ); Settings = new Settings(Environment, Git); IGpg gpg = new Gpg( Environment.LocateExecutable("gpg"), SessionManager ); CredentialStore = new LinuxCredentialStore(FileSystem, Settings, SessionManager, gpg, Environment); } else { throw new PlatformNotSupportedException(); } HttpClientFactory = new HttpClientFactory(Trace, Settings, Streams); // Set the parent window handle/ID SystemPrompts.ParentWindowId = Settings.ParentWindowId; }
public CommandContext(string appPath) { EnsureArgument.NotNullOrWhiteSpace(appPath, nameof(appPath)); ApplicationPath = appPath; Streams = new StandardStreams(); Trace = new Trace(); if (PlatformUtils.IsWindows()) { FileSystem = new WindowsFileSystem(); SessionManager = new WindowsSessionManager(); SystemPrompts = new WindowsSystemPrompts(); Environment = new WindowsEnvironment(FileSystem); Terminal = new WindowsTerminal(Trace); string gitPath = GetGitPath(Environment, FileSystem, Trace); Git = new GitProcess( Trace, Environment, gitPath, FileSystem.GetCurrentDirectory() ); Settings = new WindowsSettings(Environment, Git, Trace); } else if (PlatformUtils.IsMacOS()) { FileSystem = new MacOSFileSystem(); SessionManager = new MacOSSessionManager(); SystemPrompts = new MacOSSystemPrompts(); Environment = new PosixEnvironment(FileSystem); Terminal = new MacOSTerminal(Trace); string gitPath = GetGitPath(Environment, FileSystem, Trace); Git = new GitProcess( Trace, Environment, gitPath, FileSystem.GetCurrentDirectory() ); Settings = new Settings(Environment, Git); } else if (PlatformUtils.IsLinux()) { FileSystem = new LinuxFileSystem(); // TODO: support more than just 'Posix' or X11 SessionManager = new PosixSessionManager(); SystemPrompts = new LinuxSystemPrompts(); Environment = new PosixEnvironment(FileSystem); Terminal = new LinuxTerminal(Trace); string gitPath = GetGitPath(Environment, FileSystem, Trace); Git = new GitProcess( Trace, Environment, gitPath, FileSystem.GetCurrentDirectory() ); Settings = new Settings(Environment, Git); } else { throw new PlatformNotSupportedException(); } HttpClientFactory = new HttpClientFactory(FileSystem, Trace, Settings, Streams); CredentialStore = new CredentialStore(this); // Set the parent window handle/ID SystemPrompts.ParentWindowId = Settings.ParentWindowId; }