This is an automated email from the ASF dual-hosted git repository.

sjanc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newt.git

commit bcad5f88dcaa59b78135d6f1a9dbfb4b8d3bd607
Author: Szymon Janc <[email protected]>
AuthorDate: Wed Oct 21 10:38:15 2026 +0200

    newt/downloader: Hide password when cloning private GitHub repos
    
    For a private repository the clone URL contains the login and the
    password. The git clone command was logged as-is, so the password
    was printed with "-l debug", and in verbose mode the error of a failed
    clone included the whole command, e.g.:
    
      Error: Error downloading repository privrepo: command
      [/usr/bin/git clone -b master https://user:PASSWORD@host/...]
      exited with nonzero status 128
    
    Hide the password in the logged command and in the error text, the
    same way setOriginUrl() already does for "git remote set-url".
    
    Assisted-by: Claude:claude-opus-5-5
---
 newt/downloader/downloader.go | 31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/newt/downloader/downloader.go b/newt/downloader/downloader.go
index b96d7082..da653b8f 100644
--- a/newt/downloader/downloader.go
+++ b/newt/downloader/downloader.go
@@ -951,14 +951,20 @@ func (gd *GithubDownloader) remoteUrls() (string, string) 
{
        return url, publicUrl
 }
 
-func (gd *GithubDownloader) setOriginUrl(path string, url string) error {
-       // Hide password in logged command.
-       safeUrl := url
+// hidePassword replaces the password in s, e.g. a URL or a command, so that
+// it can be logged or shown in an error message.
+func (gd *GithubDownloader) hidePassword(s string) string {
        pw := gd.password()
-       if pw != "" {
-               safeUrl = strings.Replace(safeUrl, pw, "<password-hidden>", -1)
+       if pw == "" {
+               return s
        }
-       util.LogShellCmd(setRemoteUrlCmd("origin", safeUrl), nil)
+
+       return strings.Replace(s, pw, "<password-hidden>", -1)
+}
+
+func (gd *GithubDownloader) setOriginUrl(path string, url string) error {
+       // Hide password in logged command.
+       util.LogShellCmd(setRemoteUrlCmd("origin", gd.hidePassword(url)), nil)
 
        return setRemoteUrl(path, "origin", url, false)
 }
@@ -1005,12 +1011,23 @@ func (gd *GithubDownloader) Clone(commit string, 
dstPath string) error {
 
        cmd = append(cmd, url, dstPath)
 
+       // The URL may contain the password.  Hide it in the logged command and
+       // in the error, which includes the command if it failed in verbose 
mode.
+       safeCmd := make([]string, len(cmd))
+       for i, arg := range cmd {
+               safeCmd[i] = gd.hidePassword(arg)
+       }
+       util.LogShellCmd(safeCmd, nil)
+
        if util.Verbosity >= util.VERBOSITY_VERBOSE {
                err = util.ShellInteractiveCommand(cmd, nil, false)
        } else {
-               _, err = util.ShellCommand(cmd, nil)
+               _, err = util.ShellCommandLimitDbgOutput(cmd, nil, false, -1)
        }
        if err != nil {
+               if ne, ok := err.(*util.NewtError); ok {
+                       ne.Text = gd.hidePassword(ne.Text)
+               }
                return err
        }
        defer gd.clearRemoteAuth(dstPath)

Reply via email to