Subject: [PATCH v4 0/6][Outreachy] extend agent capability to include OS name

From: Usman Akinyemi <[email-masked]>
Date: Thu, 6 Feb 2025 00:22:30 +0530

For debugging, statistical analysis, and security purposes, it can
be valuable for Git servers to know the operating system the clients
are using.

For example:
- A server noticing that a client is using an old Git version with
security issues on one platform, like macOS, could verify if the
user is indeed running macOS before sending a message to upgrade."
- Similarly, a server identifying a client that could benefit from
an upgrade (e.g., for performance reasons) could better customize the
message it sends to nudge the client to upgrade.

Our current agent capability is in the form of "package/version" (e.g.,
"git/1.8.3.1"). Let's extend it to include the operating system name (os)
i.e in the form "package/version os" (e.g., "git/1.8.3.1 Linux").
The operating system name is retrieved using the 'sysname' field of 
he `uname(2)` system call or its equivalent.

Including OS details in the agent capability simplifies implementation,
maintains backward compatibility, avoids introducing a new capability,
encourages adoption across Git-compatible software, and enhances
debugging by providing complete environment information without affecting
functionality.

Due to privacy issues and concerns, let's add the `transfer.advertiseOSVersion`
config option. It defaults to `true` and can be changed to `false`. When `true`,
both the client and server independently append their operating system name(os)
to the `agent` capability value. The `agent` capability will now be in form of
"package/version os" (e.g., "git/1.8.3.1 Linux"). When `false`, the `agent`
capability will be in the form of "package/version" e.g "git/1.8.3.1". The server's
configuration is independent of the client's. Defaults to `true`. 

Note that, due to differences between `uname(1)` (command-line
utility) and `uname(2)` (system call) outputs on Windows,
`transfer.advertiseOSVersion` is set to false on Windows during
testing. See the message part of patch 5/6 for more details.

My mentor, Christian Couder, sent a previous patch series about this
before. You can find it here
https://lore.kernel.org/git/[email-masked]/

Changes since v3
================
 - Dropped the last patch which introduced `os-version` capability. This
   was as a result of discussion on the mailing list on why adding the
   operating system name to the existing agent capability might be better.
   I stated the reasons above and you can also check the discussion
   here.
   https://public-inbox.org/git/[email-masked]/
 - Extend the agent capability to include the operating system name.

Usman Akinyemi (6):
  version: replace manual ASCII checks with isprint() for clarity
  version: refactor redact_non_printables()
  version: refactor get_uname_info()
  version: extend get_uname_info() to hide system details
  t5701: add setup test to remove side-effect dependency
  agent: advertise OS name via agent capability

 Documentation/config/transfer.txt |  8 ++++
 Documentation/gitprotocol-v2.txt  | 15 ++++--
 builtin/bugreport.c               | 13 +----
 t/t5555-http-smart-common.sh      | 10 +++-
 t/t5701-git-serve.sh              | 19 ++++++--
 t/test-lib-functions.sh           |  8 ++++
 version.c                         | 79 +++++++++++++++++++++++++++++--
 version.h                         | 22 +++++++++
 8 files changed, 149 insertions(+), 25 deletions(-)

Range-diff versus v3:

1:  82b62c5e66 = 1:  82b62c5e66 version: replace manual ASCII checks with isprint() for clarity
2:  0a7d7ce871 = 2:  0a7d7ce871 version: refactor redact_non_printables()
3:  0187db59a4 = 3:  0187db59a4 version: refactor get_uname_info()
4:  d3a3573594 = 4:  d3a3573594 version: extend get_uname_info() to hide system details
5:  d9edd2ffc8 ! 5:  3e0e98f23d t5701: add setup test to remove side-effect dependency
    @@ t/t5701-git-serve.sh: export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
      
     -test_expect_success 'test capability advertisement' '
     +test_expect_success 'setup to generate files with expected content' '
    -+	printf "agent=git/%s\n" "$(git version | cut -d" " -f3)" >agent_and_osversion &&
    ++	printf "agent=git/%s\n" "$(git version | cut -d" " -f3)" >agent_capability &&
     +
      	test_oid_cache <<-EOF &&
      	wrong_algo sha1:sha256
    @@ t/t5701-git-serve.sh: export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
      	cat >expect.base <<-EOF &&
      	version 2
     -	agent=git/$(git version | cut -d" " -f3)
    -+	$(cat agent_and_osversion)
    ++	$(cat agent_capability)
      	ls-refs=unborn
      	fetch=shallow wait-for-done
      	server-option
6:  351d1eeddb < -:  ---------- connect: advertise OS version
-:  ---------- > 6:  67a2767026 agent: advertise OS name via agent capability

-- 
2.48.1