Skip to content

Commit 8cb9d4f

Browse files
committed
Merge branch 'ua/os-version-capability' into jch
The value of "uname -s" is by default sent over the wire as a new capability, with an opt-out for privacy-concious folks. * ua/os-version-capability: version: introduce osversion.command config for os-version output connect: advertise OS version t5701: add setup test to remove side-effect dependency version: extend get_uname_info() to hide system details version: refactor get_uname_info() version: refactor redact_non_printables()
2 parents 099b60c + 923f6a8 commit 8cb9d4f

File tree

10 files changed

+309
-22
lines changed

10 files changed

+309
-22
lines changed

Documentation/config/transfer.adoc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,19 @@ transfer.bundleURI::
125125
transfer.advertiseObjectInfo::
126126
When `true`, the `object-info` capability is advertised by
127127
servers. Defaults to false.
128+
129+
transfer.advertiseOSVersion::
130+
When `true`, the `os-version` capability is advertised by clients and
131+
servers. It makes clients and servers send to each other a string
132+
representing the operating system name, like "Linux" or "Windows".
133+
This string is retrieved from the `sysname` field of the struct returned
134+
by the uname(2) system call. If the `osVersion.command` is set, the
135+
output of the command specified will be the string exchanged by the clients
136+
and the servers. Defaults to true.
137+
138+
osVersion.command::
139+
If this variable is set, the specified command will be run and the output
140+
will be used as the value `X` for `os-version` capability (in the form
141+
`os-version=X`). `osVersion.command` is only used if `transfer.advertiseOSVersion`
142+
is true. Refer to the linkgit:git-config[1] documentation to learn more about
143+
`transfer.advertiseOSVersion` config option.

Documentation/gitprotocol-v2.adoc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,23 @@ printable ASCII characters except space (i.e., the byte range 32 < x <
190190
and debugging purposes, and MUST NOT be used to programmatically assume
191191
the presence or absence of particular features.
192192
193+
os-version
194+
~~~~~~~~~~
195+
196+
In the same way as the `agent` capability above, the server can advertise
197+
the `os-version` capability to notify the client the kind of operating system
198+
it is running on. The client may optionally send its own `os-version` capability,
199+
to notify the server the kind of operating system it is also running on in its
200+
request to the server (but it MUST NOT do so if the server did not advertise the
201+
os-version capability). The value of this capability may consist of ASCII printable
202+
characters(from 33 to 126 inclusive) and are typically made from the result of
203+
`uname -s`(OS name e.g Linux). If the `osVersion.command` is set, the value of this
204+
capability are made from the ouput of the command specified. The os-version capability
205+
can be disabled entirely by setting the `transfer.advertiseOSVersion` config option
206+
to `false`. The `os-version` strings are purely informative for statistics and
207+
debugging purposes, and MUST NOT be used to programmatically assume the presence or
208+
absence of particular features.
209+
193210
ls-refs
194211
~~~~~~~
195212

builtin/bugreport.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
#include "diagnose.h"
1313
#include "object-file.h"
1414
#include "setup.h"
15+
#include "version.h"
1516

1617
static void get_system_info(struct strbuf *sys_info)
1718
{
18-
struct utsname uname_info;
1919
char *shell = NULL;
2020

2121
/* get git version from native cmd */
@@ -24,16 +24,7 @@ static void get_system_info(struct strbuf *sys_info)
2424

2525
/* system call for other version info */
2626
strbuf_addstr(sys_info, "uname: ");
27-
if (uname(&uname_info))
28-
strbuf_addf(sys_info, _("uname() failed with error '%s' (%d)\n"),
29-
strerror(errno),
30-
errno);
31-
else
32-
strbuf_addf(sys_info, "%s %s %s %s\n",
33-
uname_info.sysname,
34-
uname_info.release,
35-
uname_info.version,
36-
uname_info.machine);
27+
get_uname_info(sys_info, 1);
3728

3829
strbuf_addstr(sys_info, _("compiler info: "));
3930
get_compiler_info(sys_info);

connect.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,9 @@ static void send_capabilities(int fd_out, struct packet_reader *reader)
491491
if (server_supports_v2("agent"))
492492
packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized());
493493

494+
if (server_supports_v2("os-version") && advertise_os_version(the_repository))
495+
packet_write_fmt(fd_out, "os-version=%s", os_version_sanitized());
496+
494497
if (server_feature_v2("object-format", &hash_name)) {
495498
int hash_algo = hash_algo_by_name(hash_name);
496499
if (hash_algo == GIT_HASH_UNKNOWN)

serve.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ static int agent_advertise(struct repository *r UNUSED,
2929
return 1;
3030
}
3131

32+
static int os_version_advertise(struct repository *r,
33+
struct strbuf *value)
34+
{
35+
if (!advertise_os_version(r))
36+
return 0;
37+
if (value)
38+
strbuf_addstr(value, os_version_sanitized());
39+
return 1;
40+
}
41+
3242
static int object_format_advertise(struct repository *r,
3343
struct strbuf *value)
3444
{
@@ -123,6 +133,10 @@ static struct protocol_capability capabilities[] = {
123133
.name = "agent",
124134
.advertise = agent_advertise,
125135
},
136+
{
137+
.name = "os-version",
138+
.advertise = os_version_advertise,
139+
},
126140
{
127141
.name = "ls-refs",
128142
.advertise = ls_refs_advertise,

t/t5555-http-smart-common.sh

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,45 @@ test_expect_success 'git receive-pack --advertise-refs: v1' '
123123
'
124124

125125
test_expect_success 'git upload-pack --advertise-refs: v2' '
126+
printf "agent=FAKE" >agent_and_osversion &&
127+
if test_have_prereq WINDOWS
128+
then
129+
git config transfer.advertiseOSVersion false
130+
else
131+
printf "\nos-version=%s\n" $(uname -s | test_redact_non_printables) >>agent_and_osversion
132+
fi &&
133+
134+
cat >expect <<-EOF &&
135+
version 2
136+
$(cat agent_and_osversion)
137+
ls-refs=unborn
138+
fetch=shallow wait-for-done
139+
server-option
140+
object-format=$(test_oid algo)
141+
0000
142+
EOF
143+
144+
GIT_PROTOCOL=version=2 \
145+
GIT_USER_AGENT=FAKE \
146+
git upload-pack --advertise-refs . >out 2>err &&
147+
148+
test-tool pkt-line unpack <out >actual &&
149+
test_must_be_empty err &&
150+
test_cmp actual expect
151+
'
152+
153+
test_expect_success 'git upload-pack --advertise-refs: v2 with osVersion.command config set' '
154+
test_config osVersion.command "uname -srvm" &&
155+
printf "agent=FAKE" >agent_and_long_osversion &&
156+
157+
if test_have_prereq !WINDOWS
158+
then
159+
printf "\nos-version=%s\n" $(uname -srvm | test_redact_non_printables) >>agent_and_long_osversion
160+
fi &&
161+
126162
cat >expect <<-EOF &&
127163
version 2
128-
agent=FAKE
164+
$(cat agent_and_long_osversion)
129165
ls-refs=unborn
130166
fetch=shallow wait-for-done
131167
server-option

t/t5701-git-serve.sh

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
77

88
. ./test-lib.sh
99

10-
test_expect_success 'test capability advertisement' '
10+
test_expect_success 'setup to generate files with expected content' '
11+
printf "agent=git/$(git version | cut -d" " -f3)" >agent_and_osversion &&
12+
1113
test_oid_cache <<-EOF &&
1214
wrong_algo sha1:sha256
1315
wrong_algo sha256:sha1
1416
EOF
17+
1518
cat >expect.base <<-EOF &&
1619
version 2
17-
agent=git/$(git version | cut -d" " -f3)
20+
$(cat agent_and_osversion)
1821
ls-refs=unborn
1922
fetch=shallow wait-for-done
2023
server-option
@@ -23,7 +26,55 @@ test_expect_success 'test capability advertisement' '
2326
cat >expect.trailer <<-EOF &&
2427
0000
2528
EOF
26-
cat expect.base expect.trailer >expect &&
29+
30+
if test_have_prereq WINDOWS
31+
then
32+
git config transfer.advertiseOSVersion false
33+
else
34+
printf "\nos-version=%s\n" $(uname -s | test_redact_non_printables) >>agent_and_osversion
35+
fi &&
36+
37+
cat >expect_osversion.base <<-EOF
38+
version 2
39+
$(cat agent_and_osversion)
40+
ls-refs=unborn
41+
fetch=shallow wait-for-done
42+
server-option
43+
object-format=$(test_oid algo)
44+
EOF
45+
'
46+
47+
test_expect_success 'test capability advertisement' '
48+
cat expect_osversion.base expect.trailer >expect &&
49+
50+
GIT_TEST_SIDEBAND_ALL=0 test-tool serve-v2 \
51+
--advertise-capabilities >out &&
52+
test-tool pkt-line unpack <out >actual &&
53+
test_cmp expect actual
54+
'
55+
56+
test_expect_success 'test capability advertisement with osVersion.command config set' '
57+
test_config osVersion.command "uname -srvm" &&
58+
printf "agent=git/$(git version | cut -d" " -f3)" >agent_and_long_osversion &&
59+
60+
if test_have_prereq !WINDOWS
61+
then
62+
printf "\nos-version=%s\n" $(uname -srvm | test_redact_non_printables) >>agent_and_long_osversion
63+
fi &&
64+
65+
test_oid_cache <<-EOF &&
66+
wrong_algo sha1:sha256
67+
wrong_algo sha256:sha1
68+
EOF
69+
cat >expect_long.base <<-EOF &&
70+
version 2
71+
$(cat agent_and_long_osversion)
72+
ls-refs=unborn
73+
fetch=shallow wait-for-done
74+
server-option
75+
object-format=$(test_oid algo)
76+
EOF
77+
cat expect_long.base expect.trailer >expect &&
2778
2879
GIT_TEST_SIDEBAND_ALL=0 test-tool serve-v2 \
2980
--advertise-capabilities >out &&
@@ -351,7 +402,7 @@ test_expect_success 'test capability advertisement with uploadpack.advertiseBund
351402
cat >expect.extra <<-EOF &&
352403
bundle-uri
353404
EOF
354-
cat expect.base \
405+
cat expect_osversion.base \
355406
expect.extra \
356407
expect.trailer >expect &&
357408

t/test-lib-functions.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2043,3 +2043,11 @@ test_trailing_hash () {
20432043
test-tool hexdump |
20442044
sed "s/ //g"
20452045
}
2046+
2047+
# Trim and replace each character with ascii code below 32 or above
2048+
# 127 (included) using a dot '.' character.
2049+
# Octal intervals \001-\040 and \177-\377
2050+
# corresponds to decimal intervals 1-32 and 127-255
2051+
test_redact_non_printables () {
2052+
tr -d "\n\r" | tr "[\001-\040][\177-\377]" "."
2053+
}

0 commit comments

Comments
 (0)