Would anyone know how I can restrict users from pushing to an hg repository if I give then access via hg-ssh?
Some details to help eliminate the obvious:
1) This is a for a shared hosting situation where I don't have root access to install mercurial-server nor can I create the "hg" username that it requires.
2) When I allow a user to connect via SSH to a shared hosting site, they will basically have their public key in my authorized_keys file and they will have be authenticated as me (i.e. they will have my credentials on the server). I can restrict their access to only a few hg repositories by specifying a "command=" clause in my authorized_keys file as documented here: https://www.mercurial-scm.org/repo/hg-stable/raw-file/tip/contrib/hg-ssh. However that gives the user full access to these repositories. Can I restrict this to pull-only access?
Any of these would solve my problem:
1) I know that mercurial-server solves this problem somehow because all the users their share the same user account called "hg". How do they do it? Can I do the same without root-access to set up things?
OR 2) Is there is a patch that I can add to hg-ssh such that hg-ssh can take some permissions on its command-line. Something like "hg-ssh -read-only repo1 repo2 -read-write repo3".
OR 3) Get "hg -R {repo} serve --stdio" to take a command line option such that it will not allow push.
The quick and dirty way would be to tweak the command= value to be something like this:
command=hg-ssh --config hooks.pretxnchangegroup=false repo1 repo2
but that's just the AclExtension done sloppily.
mercurial-server gives you the simplest control over this. You can install it as a non-root user, but you have to take a little longer to understand how it works.
Use the AclExtension. It lets you block access for ssh actions as well as http actions, and since it's enabled/disabled by hooks you'll be able to bypass it when you're logged in interactively.
Related
I have a centos server with code maintained using a mercurial repo.
To allow a new person to commit code to mercurial, I create a new user, add them to the webdev group, and they can push / pull code by
hg pull ssh://name#server.com.
However, there are some files (config files) that I would not like new users to have access to. Mercurial has been asked not to track these files, so the only way to access them is to ssh into the system and look at the files. Which I dont want new users to be able to do.
In essence, I want my new developers to only pull/push files through hg and disallow ssh-ing directly into the system. What the best way to do this? Can I provide hg access to a repo without providing ssh access to the files?
(or is my approach to the problem flawed?)
Thanks!
This can be really easily done by taking advantage of the command option available in .ssh\authorized_keys files. When you're granting their key access in that file you can prepend a "command=...." argument to their key and that's the only command they can run.
Mercurial ships with a handy script for doing exactly that. It has instructions inside:
https://www.mercurial-scm.org/repo/hg/file/tip/contrib/hg-ssh
In term of an authorization layer (similar to Gitolite for Git), you have mercurial-server (not to be mixed up with the Mercurial light-weight web server hgserve)
mercurial-server gives your developers remote read/write access to centralized Mercurial repositories using SSH public key authentication; it provides convenient and fine-grained key management and access control.
See its repository here.
It is based on the same SSH forced-command mechanism than the script mentioned by Ry4an in his answer (+1 on his answer, because it is already packaged with Mercurial).
See for illustration the "mercurial-server" source of refreshauth.py.
I'm running into a problem with a user not being able to push his commits into a Mercurial repository and am perplexed as to why it's not working for him. I've tried several things to figure out what's up, Googling doesn't turn up anything helpful... so here I am.
First, the configuration. We have a Windows XP SP2 x64 machine on our network acting as our official repository server. This contains several repositories on it. We clone / push / pull using a folder on that drive that is shared. Permissions are given to everyone for read access. Users that can push (including the user that has problems), are given full control. The user's machine is Win XP based. My machine (used to help troubleshoot things) is also Win XP based.
Second, the symptoms. The user is using TortoiseHg 2.1.1 to do his work. He can clone just fine, commits to his local repo are a-o-k, etc. When he tries to push, however, TortoiseHg returns a "abort, ret 255" code. Not very helpful. So, we've gone to the command line and have issued "hg push -v --debug". Here it returns "abort: Access is Denied". This same user can write to the server's shared folder no problem -- he can create files, directories and delete the same as well. So, reading / writing access the drive / folder is not an issue.
Third, our experimentation results. Here are some weird results from testing. The user created a new, local test repo. I logged into the server machine and created a test repo for him to push to. The user checked in a file and then pushed it up to the test repo on the server machine. This worked fine. No aborts. Life was good. He was able to do a few more pushes and it continued to work as expected. I then cloned the repo to my machine, updated a file, and pushed it back out. After the user then pulled in my changes and tried to push back to the server, he once again encountered the dreaded "Access is Denied" message. Meanwhile, I can still update the project without any problems.
As another experiment, we had the user log out and another user log in. They did so and were able to push to the server repo without a problem. Original user logs back in, makes some changes, etc. and once again hits the brick wall of "Access is Denied".
As far as we can tell, the problem is not related to Windows credentials. Otherwise, we'd expect that creating arbitrary files on the server's shared folder would not work. Further, until I made an update to the test repo the user created, he could push to that particular repo just fine.
Any ideas? What additional credential checks is Mercurial making that might cause this?
UPDATE:
After a tip from Wim, I started to look at the permissions on the various objects of the repo using 'cacls'. This is a Windows tool that "displays or modifies access control lists of files". I had the user create a new repo and then took a snapshot of the permissions. I then checked in a file to the same repo and took another snapshot of the changes.
It turns out that there are several repo file permissions that get updated as a result of this: undo.bookmarks, undo.branch, undo.desc, undo.dirstate, branchheads, 00changelog.i, 00manifest.i, undo, and the single file of the repository. All of these files had permissions similar to the following:
C:\Projects\Mercurial\hgtest4\.hg\store\undo BUILTIN\Administrators:F
NT AUTHORITY\SYSTEM:F
DOMAINxxxx\USERIDxxxx:F
BUILTIN\Users:R
(actual DOMAINxxxx and USERIDxxxx values have been altered). Prior to my check-in, DOMAINxxxx & USERIDxxxx reflected the user's domain and userid. After my check-in, these got updated to mine (we're on the same domain, but the userid is obviously different.) I was able to check things in and out even though my userid wasn't listed because I'm a member of the BUILTIN\Administrators group. The user with the problem is not. So, I'm guessing that after I checked things in, the system no longer saw him as a credentialed user with write-access (BUILTIN\User:R indicates Read-only access) and therefore caused the access denial.
I've got a terribly Q&D fix in place right now (user is now part of the Admin group...) The real fix is going to be to get the repo off of Windows Sharing and on to a proper server configuration.
He was able to do a few more pushes and it continued to work as expected. I then cloned the repo to my machine, updated a file, and pushed it back out. After the user then pulled in my changes and tried to push back to the server, he once again encountered the dreaded "Access is Denied" message.
It sounds like your push creates or modifies files in the .hg folder in such a way that they are (or become) inaccessible for the other user.
I'm no expert on NTFS file permissions, but I think you can fix such situations by forcing all the content of the folder to inherit its permissions. Try selecting "Replace all child object permissions with inheritable permissions from this object" in the Advanced Security settings of the folder.
However, sharing the repository files directly with Windows file sharing is not recommended. You need a server process between the users and the repository files for the sake of performance, data integrity and security. Without such a gatekeeper, granting commit access also means granting the ability to destroy/corrupt the repository files (or as you found out in this case, changing their permissions).
See Publishing Mercurial Repositories on the Mercurial wiki for more information about other options.
When trying to commit on my locally cloned repository of a code repo on my network share, I was getting the same error message:
00manifest.i Access is denied
Probably overly simplistic, but removing some of the read only permissions to the offending files made my hg commit work fine.
I just had the same issue abort: Access is denied. The cause was my firewall (Privatefirewall) silently blocking some actions of hg.
I was getting exactly the same error message when trying to hg push at the windows command prompt. I'd recently received a new user profile after the old one had corrupted. I then ran into this "Access Denied" error. In TortoiseHg I received a similar message of "Aborted: Error 255".
I tried the advice given here by Wim Coenen as it seemed to fit; given my new user credentials. Eventually, I tracked the error to a badly installed Windows Git. It was only failing when I used repositories with git sub-repos.
In case others are having a similar problem with Git sub-repos:
Check that Git is installed correctly. I removed and re-installed it completely. (See: https://code.google.com/p/msysgit/downloads/list for latest version).
Ensure that the path to Git is in the path environment variable. (Right-click My Computer -> Advanced tab -> Environment Variables). Don't forget that some applications do not like windows paths with spaces in so you might need to replace "Program Files" with "PROGRA~1" (possibly "PROGRA~2" on 64-bit systems).
If you are using a proxy, ensure that HTTP_PROXY and HTTPS_PROXY in the environment variables are also set correctly.
I am trying to set up a hook to notify me about new commits via mail.
Because of the issue described in Mercurial hook not executing properly, I can't seem to get it running by simply adding the following to my .hg/hgrc, since the script wouldn't run:
[hooks]
changegroup = /path/to/script
As a workaround, I added the hook in the hgweb.config where it runs as expected. Now since I'm pushing through HTTP, the actual user running the script is apache (as determined by running id from within the hook), which means that I get errors like
Not trusting file .hg/hgrc from untrusted user u, group g
I added
[trusted]
users = u
but the same errors remain. What am I doing wrong? Am I understanding this completly wrong? Appreciate any help!
You should add both the hook and the trust blocks not in the hgweb.config but in a .hgrc file in the apache user's home directory. One doesn't usually think of system users having home directories, but they all do, and you can find in in /etc/password. It's often something like /var/www, so if you create a /var/www/.hgrc file, make sure it's owned by the Apache user, and add the hook and the trust you'll be good to go.
I'm trying to propose switching from CVS and SVN to Mercurial at work. Before I do, I'd like to have any foreseeable questions answered.
How can I set up a repository to allow push and authenticate users?
I'm more familiar with administering SVN, and in SVN it was just a few lines like:
[users]
userA = passwordA
userB = passwordB
And then for permissions it was like:
[general]
userA = write
userB = read
I would really like something like svnserve that allowed me to circumvent using a full-blown apache, since all I need is a central location for pushing change sets. I know that Mercurial doesn't necessarily require a central location, but I think it would be convenient in my workplace.
Thanks!
Try using SCM Manager. It works well for Mercurial. It has a built-in HTTP/HTTPS server and allows you to manage authentication. The only requirement is Java.
http://www.scm-manager.org
https://bitbucket.org/sdorra/scm-manager
Briefly, to setup Mercurial with authentication:
Follow the Getting Started Guide here. If you're using Windows, be sure to use
scm-server\bin\scm-server.bat
to start SCM Manager.
Click on Repository Types > Mercurial Settings > Start Configuration Wizard > Select: Download and Install to install the Mercurial plugin for SCM Manager.
Be patient, downloading takes a while.
When it's finished installing, the screen will go back to the Repository Config window. Restart SCM Manager. After you restart and you should now be able to create and host Mercurial repositories over HTTP.
Double check security: General > Config and uncheck Allow Anonymous Access.Security > Users and deactivate anonymous.
You can also use SCM Manager to host Git and SVN repositories as well.
Mercurial Server is an awesome solution, which I've used on a few occasions.
As #nlucaroni mentioned in the comment, one option is using SSH authentication. It allows authenticated pull and push. We use it in our company together with Apache-hosted HTTP access for anonymous pull-only repositories. See the "ssh" solution at the Publishing Mercurial Repositories.
You can try the textauth extension. Please give it a go and send some feedback to Mercurial mailing list, then perhaps you will see it integrated into a coming release of Mercurial.
This is probably a simple problem and I'm feeling exceptionally dumb because I can't find a any kind of documentation.
I've just installed TeamCity 5 and I want to get files from my Mercurial hosting and there is two fields I just can't figure out.
HG Command path. What should I put here? The path to a file containing what? Can I get an example of that file somewhere?
The host is using Mercurial over SSH where do I define my private key?
Pull changes from? Should I put the address I'm cloning from i.e. ssh://username#myhost.something/project
I figured this out for my TeamCity 5 server last week.
HG Command path: HG
Pull changes from: https://bitbucket.org/.../.../
Don't put the username# in the URL. This is specificed as in the Username/Password fields. If you include the username in the URL it'll fail as there is a bug in the configuration tool. You'll also see a screenshot of the configuration attached to the thread:
http://www.jetbrains.net/devnet/message/5254640#5254640
I'd suggest getting things working with HTTPS and then moving to SSH if possible. This breaks things down into two easier to solve configuration problems. I used the following tutorial to get SSH going on my Windows client machine.
http://www.codza.com/mercurial-with-ssh-setup-on-windows
I've not set this up on my TeamCity server yet. However I did get TeamCity to pick up my Mercurial.ini settings by putting the ini file in \Documents and Settings\TeamCity, which is the account the service runs under.
I've not used team city, but I think hg command path is probably the full path to your local mercurial executable. For me (on linux) that's:
$ type hg
hg is /usr/bin/hg
On windows it's where the 'hg' executable in your system path was placed by whichever (of the many) windows installers for mercurial you used.
Pull changes from sounds like the URL to the repo, so:
ssh://username#myhost.something/project
or
ssh://username#myhost.something//project # note the _two_ double slashes
if you're using absolute paths on the server side.
Your private key location/specification depends on what you're using for ssh and whether or not you're running ssh-agent, but here's a links that explicitly points from within mercurial.ini, which seems sound:
http://dev.openttdcoop.org/projects/home/wiki/Configuring_TortoiseHg_(Windows)#Pointing-to-you-Private-key