git - git ://protocol? 到底是什么

标签 git ssl ssh https

我正在检查 ISO OSI 图表,您可以在其中看到 git 使用的其他两个协议(protocol):

https:(这是基于 ssl 的 http)

ssh

但没有提到 git://

这是 ISO OSI:

https://en.wikipedia.org/wiki/OSI_model

最佳答案

git protocol 是 Git 自带的一个特殊守护进程;它监听专用端口 (9418),该端口提供类似于 SSH 协议(protocol)的服务,但绝对不需要身份验证。

它是在 Git 的最开始引入的,在 commit 2386d65 (July 2005, Git 0.99.1)

Add first cut at "git protocol" connect logic.

Useful for pulling stuff off a dedicated server. Instead of connecting with ssh or just starting a local pipeline, we connect over TCP to the other side and try to see if there's a git server listening.

Of course, since I haven't written the git server yet, that will never happen. But the server really just needs to listen on a port, and execute a "git-upload-pack" when somebody connects.

(It should read one packet-line, which should be of the format

"git-upload-pack directoryname\n"

and eventually we might have other commands the server might accept).

该协议(protocol)最初在 next commit 9b011b2 中描述

There are two Pack push-pull protocols.

  • upload-pack (S) | fetch/clone-pack (C) protocol:
  • send-pack | receive-pack protocol

如今,在 Documentation/git-daemon.txt 中描述了 git 守护进程服务器的完整特性。 .

A really simple TCP Git daemon that normally listens on port "DEFAULT_GIT_PORT" aka 9418.
It waits for a connection asking for a service, and will serve that service if it is enabled.

请注意,即使 is 未在 OSI 模型中列出,9418 仍从一开始就列为 IANA (Internet Assigned Numbers Authority)

参见 commit ba8a497 (Setp. 2005, Git 0.99.7a :

[PATCH] Add note about IANA confirmation

The git port (9418) is officially listed by IANA now.
So document it.


在 Git 2.31(2021 年第一季度)中,现在禁止在 git:// URL 的主机和路径部分中使用换行符。

参见 commit 6aed567 , commit a02ea57 (2021 年 1 月 7 日)Jeff King (peff) .
(由 Junio C Hamano -- gitster -- merge 于 commit c7b1aaf ,2021 年 1 月 25 日)

git_connect_git(): forbid newlines in host and path

Reported-by: Harold Kim
Signed-off-by: Jeff King

When we connect to a git:// server, we send an initial request that looks something like:

002dgit-upload-pack repo.git\0host=example.com

If the repo path contains a newline, then it's included literally, and we get:

002egit-upload-pack repo
.git\0host=example.com

This works fine if you really do have a newline in your repository name; the server side uses the pktline framing to parse the string, not newlines.

However, there are many other protocols in the wild that do parse on newlines, such as HTTP.

So a carefully constructed git:// URL can actually turn into a valid HTTP request.
For example:

git://localhost:1234/%0d%0a%0d%0aGET%20/%20HTTP/1.1 %0d%0aHost:localhost%0d%0a%0d%0a

becomes:

0050git-upload-pack /
GET / HTTP/1.1
Host:localhost

host=localhost:1234

on the wire.
Again, this isn't a problem for a real Git server, but it does mean that feeding a malicious URL to Git (e.g., through a submodule) can cause it to make unexpected cross-protocol requests.

Since repository names with newlines are presumably quite rare (and indeed, we already disallow them in git-over-http), let's just disallow them over this protocol.

Hostnames could likewise inject a newline, but this is unlikely a problem in practice; we'd try resolving the hostname with a newline in it, which wouldn't work.
Still, it doesn't hurt to err on the side of caution there, since we would not expect them to work in the first place.

The ssh and local code paths are unaffected by this patch.
In both cases we're trying to run upload-pack via a shell, and will quote the newline so that it makes it intact.
An attacker can point an ssh url at an arbitrary port, of course, but unless there's an actual ssh server there, we'd never get as far as sending our shell command anyway.
We could similarly restrict newlines in those protocols out of caution, but there seems little benefit to doing so.

The new test here is run alongside the git-daemon(man) tests, which cover the same protocol, but it shouldn't actually contact the daemon at all.
In theory we could make the test more robust by setting up an actual repository with a newline in it (so that our clone would succeed if our new check didn't kick in).
But a repo directory with newline in it is likely not portable across all filesystems.
Likewise, we could check git-daemon's log that it was not contacted at all, but we do not currently record the log (and anyway, it would make the test racy with the daemon's log write).
We'll just check the client-side stderr to make sure we hit the expected code path.

关于git - git ://protocol? 到底是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33846856/

相关文章:

git - 忽略对git中文件的特定更改,而不是整个文件

apache - Mod_Rewrite 对除一个文件之外的所有文件强制 HTTP

ruby - 我如何使用 Rugged 来创建和提交文件,就像从命令行一样?

git - 幂等 git rebase 因虚假冲突而失败?

linux - 执行每个 git 命令后如何在 git bash 中打印时间戳?

python - 使用 SSL 的 Heroku 站点在 SSL 实验室测试中获得 "B"

ssl - Azure IoT 中心 MQTT 故障

laravel - 在SSH Laravel 5.2中运行工匠代码

ssh - 如何在cloud9本地ssh安装中显示文件树中的根文件夹

ssh - 使用 SSH 的 Composer 私有(private)存储库