Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in
Deleted user
Level
0 / 0 points
Next:
badges earned

Your Points Tracker
Challenges
Leaderboard
  • Global
  • Feed

Badge for your thoughts?

You're enrolled in our new beta rewards program. Join our group to get the inside scoop and share your feedback.

Join group
Recognition
Give the gift of kudos
You have 0 kudos available to give
Who do you want to recognize?
Why do you want to recognize them?
Kudos
Great job appreciating your peers!
Check back soon to give more kudos.

Past Kudos Given
No kudos given
You haven't given any kudos yet. Share the love above and you'll see it here.

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

How does Verify Committer pre-receive hook work with SSH (appears to bypass)?

VERSION- Bitbucket 6.7.1 Server

The problem I'm trying to solve, though irrelevant to the question, is that we have a mass email domain migration and I want to fuzzy match committer (ie. verify last names match in emails, ignoring domain).

I'm dumbfounded here as I understand how the pre-recieve hook mostly works.  I'm wrote a custom filesystem hook using <repo_dir>/hooks/pre-receive.d/25_myhook.  The script basically does this:

  1. Get the Bitbucket user from env variable GIT_COMMITTER_NAME (apparently this is only for HTTP pushes), or GIT_COMMITTER_IDENT
  2. Query Bitbucket on localhost REST API to get email associated with username from prior step.  (I don't think Bitbucket provides the email to the script.)
    • Email is actually set to IP address (and actually that of reverse proxy)
    • remote: GIT_COMMITTER_EMAIL=jsuarezx@http.172.X.X.X     
    • OR...
    • remote: GIT_COMMITTER_IDENT=jsuarezx <jsuarezx@http.172.X.X.X> 1585962883 -0400
  3. Iterate through 'git rev-list' and check fuzzy match of lastname in committer email with that of user.

This seems to be workable for HTTP connections.

The problem however is that when I switch to SSH authentication, it appears to completely bypass the built in Verify Commiter hook, and for my script, there appears to be no easy way to check which Bitbucket account is doing the commit.

When using SSH, the following environment variables are not set: GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL.

GIT_COMMITTER_IDENT=xadmin <xadmin@server.com> 1585963121 -0400

It appears that when SSH is used, this variable is replaced by the local user that Bitbucket is run as.  

Question is, for SSH connections, is the Verify Committer hook applicable?  

Is this fixed in later versions?  (We are installing Dataceter 7.1 soon, but I haven't ready any info on this situation being broken prior, so not optimistic that behavior would be different,)

 

1 answer

1 accepted

0 votes
Answer accepted
Bryan Turner Atlassian Team Sep 22, 2020

@Jorge Suarez

Our built-in Verify Committer hook runs fine on SSH--identically to HTTP, in fact. It doesn't rely on environment variables with either protocol; the identity of the pushing user is read directly from the application state since our Verify Committer hook is implemented in Java.

$ git push ssh://git@localhost:7999/qa/foo.git HEAD
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 230 bytes | 230.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: You can only push your own commits in this repository
remote: Commit 76dcc3151090930fed73b37c004d2461bf1f6bcb was committed by Bryan Turner <bturner@atlassian.com>
To ssh://localhost:7999/qa/foo.git
! [remote rejected] HEAD -> master (pre-receive hook declined)
error: failed to push some refs to 'ssh://git@localhost:7999/qa/foo.git'

$ git push http://localhost:7990/bitbucket/scm/qa/foo.git HEAD
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 230 bytes | 230.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: You can only push your own commits in this repository
remote: Commit 76dcc3151090930fed73b37c004d2461bf1f6bcb was committed by Bryan Turner <bturner@atlassian.com>
To http://localhost:7990/bitbucket/scm/qa/foo.git
! [remote rejected] HEAD -> master (pre-receive hook declined)
error: failed to push some refs to 'http://localhost:7990/bitbucket/scm/qa/foo.git

We don't export `GIT_COMMITTER_NAME` or `GIT_COMMITTER_IDENT` anywhere in our HTTP (or SSH) hosting handling, and attaching with a debugger and looking at the environment we pass to `git http-backend` shows neither is set:

"CONTENT_LENGTH" -> "383"
"CONTENT_TYPE" -> "application/x-git-receive-pack-request"
"GATEWAY_INTERFACE" -> "CGI/1.1"
"GIT_CEILING_DIRECTORIES" -> "/path/to/bitbucket/home/shared/data/repositories:/path/to/bitbucket/home"
"GIT_HTTP_EXPORT_ALL" -> "true"
"GIT_PROJECT_ROOT" -> "/path/to/bitbucket/home/shared/data/repositories/12"
"HTTPS" -> "OFF"
"HTTP_ACCEPT" -> "application/x-git-receive-pack-result"
"HTTP_ACCEPT_ENCODING" -> "deflate, gzip"
"HTTP_AUTHORIZATION" -> "Basic YWRtaW46YWRtaW4="
"HTTP_CONTENT_LENGTH" -> "383"
"HTTP_CONTENT_TYPE" -> "application/x-git-receive-pack-request"
"HTTP_HOST" -> "localhost:7990"
"HTTP_USER_AGENT" -> "git/2.20.1"
"LC_ALL" -> "C"
"PATH_INFO" -> "/git-receive-pack"
"REMOTE_ADDR" -> "0:0:0:0:0:0:0:1"
"REMOTE_HOST" -> "0:0:0:0:0:0:0:1"
"REMOTE_USER" -> "jdoe"
"REQUEST_METHOD" -> "POST"
"SCRIPT_NAME" -> "/git-receive-pack"
"SERVER_NAME" -> "localhost"
"SERVER_PORT" -> "7990"
"SERVER_PROTOCOL" -> "HTTP/1.1"
"SERVER_SOFTWARE" -> "Apache Tomcat/9.0.37"
"STASH_GIT_TRANSCODE_HOST" -> "127.0.0.1"
"STASH_GIT_TRANSCODE_PORT" -> "50300"
"STASH_HOOK_ADDRESS" -> "127.0.0.1"
"STASH_HOOK_CALLBACK" -> "/path/to/bitbucket/home/bin/git-hooks/hook-callback.pl"
"STASH_HOOK_COORDINATOR" -> "/path/to/bitbucket/home/bin/git-hooks/hook-coordinator.sh"
"STASH_HOOK_PORT" -> "50301"
"STASH_HOOK_REQUEST_ID" -> "b3f6effbcdd0138fe78699312ce6352f66bd44a6"

What you're seeing is this Git code, which defaults the `GIT_COMMITTER_*` variables from the "REMOTE_USER" and "REMOTE_ADDR". There's no equivalent code in `receive-pack.c`, which is what SSH hosting uses, and so you don't get the same behavior.

These sorts of issues are why we recommend administrators and app developers write Java-based hooks instead of script-based ones. What you're trying to do can be done much more efficiently from Java, where the current user is available from the `AuthenticationContext`--no need to try and reverse engineer it from environment variables and make REST requests--and where we provide a way to register a callback to have your hook receive the newly pushed commits which is implemented in a way that allows that data to be reused by/shared with other hooks. (In other words, instead of every hook running its own `git rev-list` commands, your hook can register its interest and the system runs `git rev-list` once and streams the commits to every interested hook.)

If you choose to write it as a script anyway, you might check the "REMOTE_USER" environment variable. Bitbucket Server exports that before it forks out any `git` processes, if there's a currently-authenticated user. (Of course, whether that propagates to hook scripts is up to Git, but I'd expect it to retain the environment when forking subprocesses.)

Best regards,
Bryan Turner
Atlassian Bitbucket

Thanks Bryan, for future hooks I will look into implementing them using Java.  My use case required just a quick and dirty one-time solution while we transitioned users accounts and I do not use Java regularly, but I am much more familiar with bash.

Suggest an answer

Log in or Sign up to answer
DEPLOYMENT TYPE
SERVER
VERSION
6.7.1
TAGS
Community showcase
Published in Bitbucket

Calling any interview participants for Bitbucket Data Center

Hi everyone,  We are looking to learn more about development teams’ workflows and pain points, especially around DevOps, integrations, administration, scale, security, and the related challeng...

515 views 6 4
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you