Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let git-lfs HTTPS transport send cookies #3825

Merged
merged 7 commits into from
Sep 30, 2019
Merged

Conversation

kupson
Copy link
Contributor

@kupson kupson commented Sep 19, 2019

This allows Git LFS to use the same cookies as configured for Git
(http.cookieFile). Those cookies may be needed for e.g. Gcloud Identity-Aware
Proxy.

Cookies are sent only over HTTPS.

Fixes #3824

Copy link
Member

@bk2204 bk2204 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey,,

Thanks for sending in this patch, and welcome to Git LFS! I think this is a great start. I'd like to see an integration test in the t/ directory so we don't regress this case, and I think there are some test failures on Windows that should be addressed.

For writing the test, it may be useful to add a special repository name to t/cmd/lfstest-gitserver.go that handles the special requirements of persisting a cookie properly. If you have any questions, I'm happy to answer them.

}

func getCookieJarForHost(c *Client, host string) (http.CookieJar, error) {
cookieFile, _ := c.uc.Get("http", fmt.Sprintf("https://%v", host), "cookieFile")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line doesn't seem to be indented properly. Could you run goimports or go fmt to make sure your code is tidy?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be fixed now.

"fmt"
"net/http"

"github.com/google/slothfs/cookie"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume we need this dependency because the builtin Go cookie jar can't read from a file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Git-lfs should read the same file as git and libcurl - a parser for Netscape cookie jar file format is needed (https://curl.haxx.se/docs/http-cookies.html).

The format is quite simple and the parser can be added directly to lfshttp/cookies.go if you would like to avoid additional dependencies.

@kupson kupson requested a review from bk2204 September 23, 2019 06:40
Copy link
Member

@bk2204 bk2204 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good; I found just one more thing that may be worth cleaning up.

I suspect you'll want to wait until #3833 is merged and then squash rebase them on top so that we can verify that the tests do indeed pass on Windows.


# golang net.http.Cookie ignores cookies with IP instead of domain/hostname
GITSERVER_SAVED="$GITSERVER"
GITSERVER=$(echo "$GITSERVER" | sed 's/127\.0\.0\.1/localhost/')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is in a subshell, so you need not save the old version and restore it. Any variables you modify here are not persisted in other tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be fixed now.

@slonopotamus
Copy link
Contributor

@kupson Please, rebase onto latest master to make sure tests pass on Windows

Rafal Kupka and others added 5 commits September 28, 2019 19:02
This allows Git LFS to use the same cookies as configured for Git
(http.cookieFile). Those cookies may be needed for e.g. Gcloud Identity-Aware
Proxy.
The script has to overwrite GITSERVER because golang http library refuses to
accept cookies for 127.0.0.1.
The `t-credentials.sh` requires no credentials for localhost
@kupson kupson requested a review from bk2204 September 29, 2019 09:03
Copy link
Member

@bk2204 bk2204 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good. Thanks again for the patch.

@bk2204 bk2204 merged commit e132c34 into git-lfs:master Sep 30, 2019
ssgelm added a commit to ssgelm/git-lfs that referenced this pull request Oct 27, 2019
The original parser that was used in git-lfs#3825 brings in a lot of
dependencies that complicate packaging git-lfs.  This replaces it with a
small parser I wrote with almost no dependencies.  I've tested this as
extensively as i can and it seems to work correctly.
chrisd8088 added a commit to chrisd8088/git-lfs that referenced this pull request Sep 15, 2024
In commit b9602f3 of PR git-lfs#5616 we
resolved a problem which caused flaky test results in our CI jobs
by ensuring that the t/t-credential.sh test script used a unique
directory for the credential record files we provide to our
git-credential-lfstest helper program.

This change ensured that when the "clone (HTTP server/proxy require
cookies)" test in our t/t-clone.sh script creates a record file named
"localhost" in the common directory specified by the CREDSDIR
environment variable, as a copy of the "127.0.0.1" file our
setup_creds() shell library function creates, this does not conflict
with the "credentials from netrc" test and other related tests
in the t/t-credential.sh test script, which depend on there not
existing a credential for the "localhost" hostname.

However, a previous attempt to resolve this problem was already
made in commits bb87944 and
bcb9eb3 of PR git-lfs#3825, but assumed that
our test scripts would always run sequentially rather than in parallel.
In that PR, the "clone (HTTP server/proxy require cookies)" was
added, and at the end of the test, it removes the "localhost"
credential record file it creates at the beginning of the test.

Of course, if the test ever failed, then it would leave the "localhost"
file in place, so even if our test scripts always ran sequentially
there would still be a conflict with the tests in the t/t-credential.sh
script.

We can more comprehensively ensure that these two test scripts do
not conflict again in the future by using the same technique applied
in commit b9602f3 to the
t/t-credential.sh script in the t/t-clone.sh script as well.

We therefore add a call to setup_creds() at the start of the
t/t-clone.sh script, so it will also use a separate copy of the
credential record files in the CREDSDIR directory.  This means
that the "localhost" file will only exist in a credential record
directory used by the t/t-clone.sh script.  We can then also drop
the attempt to clean up the "localhost" file from the end of the
"clone (HTTP server/proxy require cookies)" test.

To make this change, we also need to slightly refactor our
t/testhelpers.sh library so that the setup_creds() function can
generate the appropriate credential record filenames on its own.
At the moment, it depends on some local variables defined in the
setup() function, but these are used nowhere else except in the
setup_creds() function, so we can just move their values directly
into the strings concatenated and passed to the write_creds_path()
function by the setup_creds() function.
chrisd8088 added a commit to chrisd8088/git-lfs that referenced this pull request Oct 7, 2024
In commit b9602f3 of PR git-lfs#5616 we
resolved a problem which caused flaky test results in our CI jobs
by ensuring that the t/t-credential.sh test script used a unique
directory for the credential record files we provide to our
git-credential-lfstest helper program.

This change ensured that when the "clone (HTTP server/proxy require
cookies)" test in our t/t-clone.sh script creates a record file named
"localhost" in the common directory specified by the CREDSDIR
environment variable, as a copy of the "127.0.0.1" file our
setup_creds() shell library function creates, this does not conflict
with the "credentials from netrc" test and other related tests
in the t/t-credential.sh test script, which depend on there not
existing a credential for the "localhost" hostname.

However, a previous attempt to resolve this problem was already
made in commits bb87944 and
bcb9eb3 of PR git-lfs#3825, but assumed that
our test scripts would always run sequentially rather than in parallel.
In that PR, the "clone (HTTP server/proxy require cookies)" was
added, and at the end of the test, it removes the "localhost"
credential record file it creates at the beginning of the test.

Of course, if the test ever failed, then it would leave the "localhost"
file in place, so even if our test scripts always ran sequentially
there would still be a conflict with the tests in the t/t-credential.sh
script.

We can more comprehensively ensure that these two test scripts do
not conflict again in the future by using the same technique applied
in commit b9602f3 to the
t/t-credential.sh script in the t/t-clone.sh script as well.

We therefore add a call to setup_creds() at the start of the
t/t-clone.sh script, so it will also use a separate copy of the
credential record files in the CREDSDIR directory.  This means
that the "localhost" file will only exist in a credential record
directory used by the t/t-clone.sh script.  We can then also drop
the attempt to clean up the "localhost" file from the end of the
"clone (HTTP server/proxy require cookies)" test.

To make this change, we also need to slightly refactor our
t/testhelpers.sh library so that the setup_creds() function can
generate the appropriate credential record filenames on its own.
At the moment, it depends on some local variables defined in the
setup() function, but these are used nowhere else except in the
setup_creds() function, so we can just move their values directly
into the strings concatenated and passed to the write_creds_path()
function by the setup_creds() function.
chrisd8088 added a commit to chrisd8088/git-lfs that referenced this pull request Oct 30, 2024
In commit b9602f3 of PR git-lfs#5616 we
resolved a problem which caused flaky test results in our CI jobs
by ensuring that the t/t-credential.sh test script used a unique
directory for the credential record files we provide to our
git-credential-lfstest helper program.

This change ensured that when the "clone (HTTP server/proxy require
cookies)" test in our t/t-clone.sh script creates a record file named
"localhost" in the common directory specified by the CREDSDIR
environment variable, as a copy of the "127.0.0.1" file our
setup_creds() shell library function creates, this does not conflict
with the "credentials from netrc" test and other related tests
in the t/t-credential.sh test script, which depend on there not
existing a credential for the "localhost" hostname.

However, a previous attempt to resolve this problem was already
made in commits bb87944 and
bcb9eb3 of PR git-lfs#3825, but assumed that
our test scripts would always run sequentially rather than in parallel.
In that PR, the "clone (HTTP server/proxy require cookies)" was
added, and at the end of the test, it removes the "localhost"
credential record file it creates at the beginning of the test.

Of course, if the test ever failed, then it would leave the "localhost"
file in place, so even if our test scripts always ran sequentially
there would still be a conflict with the tests in the t/t-credential.sh
script.

We can more comprehensively ensure that these two test scripts do
not conflict again in the future by using the same technique applied
in commit b9602f3 to the
t/t-credential.sh script in the t/t-clone.sh script as well.

We therefore add a call to setup_creds() at the start of the
t/t-clone.sh script, so it will also use a separate copy of the
credential record files in the CREDSDIR directory.  This means
that the "localhost" file will only exist in a credential record
directory used by the t/t-clone.sh script.  We can then also drop
the attempt to clean up the "localhost" file from the end of the
"clone (HTTP server/proxy require cookies)" test.

To make this change, we also need to slightly refactor our
t/testhelpers.sh library so that the setup_creds() function can
generate the appropriate credential record filenames on its own.
At the moment, it depends on some local variables defined in the
setup() function, but these are used nowhere else except in the
setup_creds() function, so we can just move their values directly
into the strings concatenated and passed to the write_creds_path()
function by the setup_creds() function.
chrisd8088 added a commit to chrisd8088/git-lfs that referenced this pull request Nov 18, 2024
In commit b9602f3 of PR git-lfs#5616 we
resolved a problem which caused flaky test results in our CI jobs
by ensuring that the t/t-credential.sh test script used a unique
directory for the credential record files we provide to our
git-credential-lfstest helper program.

This change ensured that when the "clone (HTTP server/proxy require
cookies)" test in our t/t-clone.sh script creates a record file named
"localhost" in the common directory specified by the CREDSDIR
environment variable, specifically a copy of the "127.0.0.1" file
created by the setup_creds() shell library function, this does not
conflict with the "credentials from netrc" test and other related
tests in the t/t-credential.sh test script, which depend on there
being no credential records associated with the "localhost" hostname.

However, we already made a previous attempt to resolve this problem
in commits bb87944 and
bcb9eb3 of PR git-lfs#3825, but that change
assumes that our test scripts always run sequentially rather than in
parallel.  In PR git-lfs#3825 the "clone (HTTP server/proxy require cookies)"
test was added, and at the end of the test, it removes the "localhost"
credential record file it creates at the beginning of the test.

Of course, if the test ever fails, then it leaves the "localhost" record
file in place, so even if our test scripts always ran sequentially
there would still be a potential conflict with the tests in the
t/t-credential.sh script.

We can more comprehensively ensure that these two test scripts do
not conflict again in the future by using the same technique applied
in commit b9602f3 to the
t/t-credential.sh script in the t/t-clone.sh script as well.

First, we add a call to setup_creds() at the start of the t/t-clone.sh
script after setting the CREDSDIR environment variable to a path
unique to the t/t-clone.sh script.  This ensures that a separate copy
of the default credential record file for the 127.0.0.1 hostname is
available for the exclusive use of the tests in the script.

Next, we move the creation of the credential record files associated
with the TLS/SSL client certificate used in the "clone ClientCert"
test from the generic setup_creds() function into the test itself.
We would otherwise need to define the "certpath" and "keypath" variables,
as their values are interpolated by the function into the names of
these credential record files.

The TLS/SSL client certificate and key files are generated by our
lfstest-gitserver utility when it is first executed.  Their locations
are defined by the LFSTEST_CLIENT_* environment variables passed by
the setup() function in our t/testhelpers.sh shell library to the
lfstest-count-tests utility, which then runs the lfstest-gitserver
program.  The values of these environment variables are set from the
LFS_CLIENT_CERT_FILE and LFS_CLIENT_KEY_FILE* variables defined by
our t/testenv.sh script.  We now use these variables in the
"clone ClientCert" test when we call the write_creds_file() function
directly, instead of allowing the setup_creds() function to perform
those calls.

We could define the "certpath" and "keypath" variables (using the
LFS_CLIENT_CERT_FILE and LFS_CLIENT_KEY_FILE_ENCRYPTED variables)
prior to calling setup_creds() at the start of the t/t-clone.sh script.
However, the "clone ClientCert" test is the only one which actually
makes use of these credential record files, as this is the only test
which actively checks the use of an encrypted TLS/SSL client certificate,
and so is the only place where we need to create these record files.

Further, we can also move into the test the "git config" commands that
set the "http.<url>.sslCert" and "http.<url>.sslKey" Git configuration
options with the locations of the TLS/SSL client certificate files.
Previously, we set these configuration options in the setup() function
in our t/testhelpers.sh shell library, so they were configured for all
tests in all test scripts, although only the "clone ClientCert" test
makes use of them.

Finally, the "clone (HTTP server/proxy require cookies)" test no
longer needs to attempt to delete the credential record file for
the "localhost" hostname after the test is complete, so we can
simply remove that code.

Note that the "clone ClientCert" test was first introduced in
commit daba49a of PR git-lfs#1893, at
which time the "git config" commands to set the "http.<url>.sslCert"
and "http.<url>.sslKey" options were added to the setup() function,
and the LFS_CLIENT_CERT_FILE and LFS_CLIENT_KEY_FILE variables
were defined in what was then the test/testenv.sh script.  Later,
in commit 52f94c2 of PR git-lfs#3270,
the LFS_CLIENT_KEY_FILE_ENCRYPTED variable was added along with
support in the lfstest-gitserver program to generate an encrypted
certificate key file.  In another commit in PR git-lfs#3270, commit
706beca, the "clone ClientCert"
test was then expanded to validate use of the encrypted key file
with the "git lfs clone" command.

(Note too that the following test, the "clone ClientCert with homedir
certs" test, appears to also depend on credential record files for
the TLS/SSL client certificate files it creates in the dedicated home
directory used by our tests.  However, because this test does not
set the "http.sslCertPasswordProtected" Git configuration option or
the GIT_SSL_CERT_PASSWORD_PROTECTED environment variable, Git does
not attempt to retrieve a passphrase for the certificate files, and
so the associated credential record files are never actually used.
We will address this issue in a subsequent commit in this PR.)
chrisd8088 added a commit to chrisd8088/git-lfs that referenced this pull request Nov 18, 2024
In commit b9602f3 of PR git-lfs#5616 we
resolved a problem which caused flaky test results in our CI jobs
by ensuring that the t/t-credential.sh test script used a unique
directory for the credential record files we provide to our
git-credential-lfstest helper program.

This change ensured that when the "clone (HTTP server/proxy require
cookies)" test in our t/t-clone.sh script creates a record file named
"localhost" in the common directory specified by the CREDSDIR
environment variable, specifically a copy of the "127.0.0.1" file
created by the setup_creds() shell library function, this does not
conflict with the "credentials from netrc" test and other related
tests in the t/t-credential.sh test script, which depend on there
being no credential records associated with the "localhost" hostname.

However, we already made a previous attempt to resolve this problem
in commits bb87944 and
bcb9eb3 of PR git-lfs#3825, but that change
assumes that our test scripts always run sequentially rather than in
parallel.  In PR git-lfs#3825 the "clone (HTTP server/proxy require cookies)"
test was added, and at the end of the test, it removes the "localhost"
credential record file it creates at the beginning of the test.

Of course, if the test ever fails, then it leaves the "localhost" record
file in place, so even if our test scripts always ran sequentially
there would still be a potential conflict with the tests in the
t/t-credential.sh script.

We can more comprehensively ensure that these two test scripts do
not conflict again in the future by using the same technique applied
in commit b9602f3 to the
t/t-credential.sh script in the t/t-clone.sh script as well.

First, we add a call to setup_creds() at the start of the t/t-clone.sh
script after setting the CREDSDIR environment variable to a path
unique to the t/t-clone.sh script.  This ensures that a separate copy
of the default credential record file for the 127.0.0.1 hostname is
available for the exclusive use of the tests in the script.

Next, we move the creation of the credential record files associated
with the TLS/SSL client certificate used in the "clone ClientCert"
test from the generic setup_creds() function into the test itself.
We would otherwise need to define the "certpath" and "keypath" variables,
as their values are interpolated by the function into the names of
these credential record files.

The TLS/SSL client certificate and key files are generated by our
lfstest-gitserver utility when it is first executed.  Their locations
are defined by the LFSTEST_CLIENT_* environment variables passed by
the setup() function in our t/testhelpers.sh shell library to the
lfstest-count-tests utility, which then runs the lfstest-gitserver
program.  The values of these environment variables are set from the
LFS_CLIENT_CERT_FILE and LFS_CLIENT_KEY_FILE* variables defined by
our t/testenv.sh script.  We now use these variables in the
"clone ClientCert" test when we call the write_creds_file() function
directly, instead of allowing the setup_creds() function to perform
those calls.

We could define the "certpath" and "keypath" variables (using the
LFS_CLIENT_CERT_FILE and LFS_CLIENT_KEY_FILE_ENCRYPTED variables)
prior to calling setup_creds() at the start of the t/t-clone.sh script.
However, the "clone ClientCert" test is the only one which actually
makes use of these credential record files, as this is the only test
which actively checks the use of an encrypted TLS/SSL client certificate,
and so is the only place where we need to create these record files.

Further, we can also move into the test the "git config" commands that
set the "http.<url>.sslCert" and "http.<url>.sslKey" Git configuration
options with the locations of the TLS/SSL client certificate files, and
we do the same for the "create lock with server using client cert" test
in the t/t-lock.sh test script.

Previously, we set these configuration options in the setup() function
in our t/testhelpers.sh shell library, so they were configured for all
tests in all test scripts, although only the "clone ClientCert" test and
the "create lock with server using client cert" test make use of them.

Finally, the "clone (HTTP server/proxy require cookies)" test no
longer needs to attempt to delete the credential record file for
the "localhost" hostname after the test is complete, so we can
simply remove that code.

Note that the "clone ClientCert" test was first introduced in
commit daba49a of PR git-lfs#1893, at
which time the "git config" commands to set the "http.<url>.sslCert"
and "http.<url>.sslKey" options were added to the setup() function,
and the LFS_CLIENT_CERT_FILE and LFS_CLIENT_KEY_FILE variables
were defined in what was then the test/testenv.sh script.  Later,
in commit 52f94c2 of PR git-lfs#3270,
the LFS_CLIENT_KEY_FILE_ENCRYPTED variable was added along with
support in the lfstest-gitserver program to generate an encrypted
certificate key file.  In another commit in PR git-lfs#3270, commit
706beca, the "clone ClientCert"
test was then expanded to validate use of the encrypted key file
with the "git lfs clone" command.

(Note too that the following test, the "clone ClientCert with homedir
certs" test, appears to also depend on credential record files for
the TLS/SSL client certificate files it creates in the dedicated home
directory used by our tests.  However, because this test does not
set the "http.sslCertPasswordProtected" Git configuration option or
the GIT_SSL_CERT_PASSWORD_PROTECTED environment variable, Git does
not attempt to retrieve a passphrase for the certificate files, and
so the associated credential record files are never actually used.
We will address this issue in a subsequent commit in this PR.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Git-lfs cannot access repositories behind Google Cloud Identity-Aware Proxy
3 participants