Skip to content
This repository has been archived by the owner on Jul 15, 2023. It is now read-only.

If git username is an email address, credential manager fails #587

Closed
simonech opened this issue Mar 15, 2018 · 9 comments
Closed

If git username is an email address, credential manager fails #587

simonech opened this issue Mar 15, 2018 · 9 comments
Labels
bug Marks an issue as tracking a bug, or marks a pull request as fixing a bug.
Milestone

Comments

@simonech
Copy link
Contributor

simonech commented Mar 15, 2018

If the git username is an email address like name.surname@example.com the credential manager fails with the error:

fatal: UriFormatException encountered.
{{ queryUrl}}
fatal: UriFormatException encountered.
{{ queryUrl}}
fatal: UriFormatException encountered.
{{ queryUrl}
}fatal: UriFormatException encountered.
{{ queryUrl}}
fatal: Authentication failed for ....

The problem is that the target of format {protocol}://{username}@{host}/{path] then becomes https://name.surname@example.com@mygiteserver.com and then the Uri validation fails.

I'm debugging it and will send a PR as soon as I solve the problem.

There is no problem when using the standard credential manager that comes with git for windows

@whoisj
Copy link
Contributor

whoisj commented Mar 16, 2018

@simonech thanks - again! I think this is a fix I can get done rather quickly.

Race? 😄

@whoisj whoisj added the bug Marks an issue as tracking a bug, or marks a pull request as fixing a bug. label Mar 16, 2018
@whoisj whoisj added this to the vNext milestone Mar 16, 2018
@whoisj
Copy link
Contributor

whoisj commented Mar 16, 2018

I'm not going to win any coding races. Ran outta time tonight. If there's no pull-request tomorrow I'll look into it. Thanks again!

@simonech
Copy link
Contributor Author

simonech commented Mar 16, 2018 via email

@simonech
Copy link
Contributor Author

This bug was introduced in commit cli-shared: Remove the concept to of actual vs query URI values..

Before username was escaped with Uri.EscapeDataString .

I'll submit a PR this afternoon.

@whoisj
Copy link
Contributor

whoisj commented Mar 16, 2018

@simonech the Uri.EscapeDataString was causing double encoding issues - we likely ought to find a separate solution. Thanks!

@simonech
Copy link
Contributor Author

simonech commented Mar 16, 2018 via email

@simonech
Copy link
Contributor Author

According to RFC3986, reserved characters in URIs are :/?#[]@!$&'()*+,;=
Apart from @ sign I don't think any of the others are likely to appear in an email address or a git username.
I'll just manually escape @ with %40

@whoisj
Copy link
Contributor

whoisj commented Mar 16, 2018

Perhaps something like

internal virtual void CreateTargetUri()
{
    string queryUrl = null;
    string proxyUrl = _proxyUri?.OriginalString;

    StringBuilder buffer = new StringBuilder();

    // URI format is {protocol}://{username}@{host}/{path] with
    // everything optional except for {host}.

    // Protocol.
    if (!string.IsNullOrWhiteSpace(_queryProtocol))
    {
        buffer.Append(_queryProtocol)
                .Append("://");
    }

    // Username.
    if (!string.IsNullOrWhiteSpace(_username))
    {
        // !!! --- FIX BEGINS HERE ---
        var username = NeedsToBeEscaped(_username)
            ? Uri.EscapeDataString(_username)
            : _username;

        buffer.Append(username)
                .Append('@');

        // --- END OF FIX !!!
    }

    // Host.
    buffer.Append(_queryHost)
            .Append('/');

    // Path
    if (!string.IsNullOrWhiteSpace(_queryPath))
    {
        buffer.Append(_queryPath);
    }

    queryUrl = buffer.ToString();

    // Create the target URI object.
    _targetUri = new TargetUri(queryUrl, proxyUrl);
}

private static bool NeedsToBeEscaped(string value)
{
    for (int i = 0; i < value.Length; i += 1)
    {
        switch (value[i])
        {
            case ':':
            case '/':
            case '?':
            case '#':
            case '[':
            case ']':
            case '@':
            case '!':
            case '$':
            case '&':
            case '\'':
            case '(':
            case ')':
            case '*':
            case '+':
            case ',':
            case ';':
            case '=':
                return true;
        }
    }

    return false;
}

would be the right answer?

@simonech
Copy link
Contributor Author

I've done two implementation, the easy one (just replacing @ with %40) in #593 and the one that uses your code as #594
Choose whichever you prefer 😄

kgybels added a commit to kgybels/Git-Credential-Manager-for-Windows that referenced this issue Mar 26, 2018
Extend solution for microsoft#587 to also handle:
username=DOMAIN\username
kgybels added a commit to kgybels/Git-Credential-Manager-for-Windows that referenced this issue Mar 26, 2018
Extend solution for microsoft#587 to also handle:
username=DOMAIN\username
whoisj pushed a commit to whoisj/Git-Credential-Manager-for-Windows that referenced this issue Mar 30, 2018
Extend solution for microsoft#587 to also handle:
username=DOMAIN\username
@whoisj whoisj modified the milestones: vNext, v1.16.0-preview.1 May 3, 2018
@whoisj whoisj modified the milestones: v1.16.0-preview.1, v1.16.0 May 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Marks an issue as tracking a bug, or marks a pull request as fixing a bug.
Projects
None yet
Development

No branches or pull requests

2 participants