7
votes

I am currently using TFS 2013 (local installation) to try to build from an internal GitHub Enterprise installation using LDAP Authentication.

The problem I am getting is that it cannot access the source code, how can I configure TFS Build to use a specific authentication?

From the TFS Build Log

Exception Message: An error was raised by libgit2. Category = Net (Error).

VS30063: You are not authorized to access https://user:[email protected]. (type LibGit2SharpException)

Exception Data Dictionary:

libgit2.code = -1

libgit2.category = 11

Exception Stack Trace:

Server stack trace:

at LibGit2Sharp.Core.Ensure.HandleError(Int32 result) at LibGit2Sharp.Core.Proxy.git_clone(String url, String workdir, GitCloneOptions opts) at LibGit2Sharp.Repository.Clone(String sourceUrl, String workdirPath, Boolean bare, Boolean checkout, TransferProgressHandler onTransferProgress, CheckoutProgressHandler onCheckoutProgress, Credentials credentials) at Microsoft.TeamFoundation.Build.Activities.Git.GitPull.GitClone.GetRepository(String repositoryUrl, String workingFolder) at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs) at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)

Exception rethrown at [0]:

at System.Runtime.Remoting.Proxies.RealProxy.EndInvokeHelper(Message reqMsg, Boolean bProxyCase) at System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(Object NotUsed, MessageData& msgData) at System.Func3.EndInvoke(IAsyncResult result) at Microsoft.TeamFoundation.Build.Activities.Git.GitPull.GitRepositoryBase.EndExecute(AsyncCodeActivityContext context, IAsyncResult result) at System.Activities.AsyncCodeActivity1.System.Activities.IAsyncCodeActivity.FinishExecution(AsyncCodeActivityContext context, IAsyncResult result) at System.Activities.AsyncCodeActivity.CompleteAsyncCodeActivityData.CompleteAsyncCodeActivityWorkItem.Execute(ActivityExecutor executor, BookmarkManager bookmarkManager)

Follow up

I have tried the URL params for authentication (example)

https://username:[email protected]/user/project.git

More Follow up

Completely uninstalled and update to the 2013 RC, error message has been updated as well, as it is different.

I have also tried setting up the build controller to run as an authenticated LDAP user in the github enterprise installation.

2

2 Answers

3
votes

Libgit2 does support the url credentials, however TFS build activities for GitPull overrides the default behavior with a Microsoft.TeamFoundation.Build.Activities.Git.TfsSmartSubtransport class for the http and https protocol.

This class unfortunately ignores credentials in the URL and instead tries to retrieve credentials from the registry.

I was able to successfully get a TFS build server to pull source code from a gitlab server using TFS build with the default GitTemplate.12.xaml workflow.

Setup the TFS build's repository URL without any credentials in the URL.

Encrypted your credential's password with the following bit of code. This needs to get run on the build server as the encryption process is specific to the local machine it's executed on.

var password = "your_password";
var bytes = Encoding.Unicode.GetBytes(password);
var bytes2 = ProtectedData.Protect(bytes, null, DataProtectionScope.LocalMachine);
var base64 = Convert.ToBase64String(bytes2);

Add the following registry settings to your build server.

NOTE: The URL in the registry must exactly match the absolute URL of your repository or TFS won't find the credentials.

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\TeamFoundationServer\12.0\HostedServiceAccounts\Build\http://githubrepository.corp.company.net]
"Microsoft_TFS_UserName"="<username goes here>"
"Microsoft_TFS_Password"="<bas64 encrypted password goes here>"
"Microsoft_TFS_CredentialsType"="Windows"

The only other alternatives to this approach that I could think of is to modify the default workflow and replace the GitPull activity with something else.

I'm not suggesting that this is the best method, but it worked for me.

0
votes

That's odd. It looks like the HTTP transport should honor url-encoded credentials.

In any case, it might be better and safer to set up the remote to get the credentials from elsewhere. The clone code is a good example of how to do this: here's how to set up the callback, and here's an example of how to generate the credential object.