Subject: [PATCH 0/4][Outreachy] Introduce os-version Capability with Configurable Options

From: Usman Akinyemi <[email-masked]>
Date: Mon, 6 Jan 2025 16:00:48 +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.

So let's add a new 'os-version' capability to the v2 protocol, in the
same way as the existing 'agent' capability that lets clients and servers
exchange the Git version they are running.

By default this sends similar info as `git bugreport` is already sending,
which uses uname(2). The difference is that it is sanitized in the same
way as the Git version sent by the 'agent' capability is sanitized
(by replacing characters having an ascii code less than 32 or more
than 127 with '.'). Also, it only sends the result of `uname -s` i.e
just only the operating system name (e.g "Linux").

Due to privacy issues and concerns, let's add the `transfer.advertiseOSVersion`
config option. This boolean option is enabled by default, but allows users to
disable this feature completely by setting it to "false".

To provide flexibility and customization, let also add the `osversion.command`
config option. This allows users to specify a custom command whose output will
be used as the string exchanged via the "os-version" capability. If this option
is not set, the default behavior exchanges only the operating system name,
such as "Linux" or "Windows".

Planned Feature: osversion.format
While the above configurations are already implemented, we will be introducing
an additional config option, `osversion.format`. This option would allow users
to fully customize the string sent to the other side using placeholders,
similar to how git for-each-ref uses %() syntax.

For example:
Format: "OS: %(os_name), Distro: %(distro), Arch: %(arch)"
Result: "OS: Linux, Distro: Fedora, Arch: x86_64"

We are wondering if it's worth it for placeholders to use the %()
syntax or if they could use another simpler syntax like $OS_NAME or
just OS_NAME instead of %(os_name).

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 3/4 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]/

Usman Akinyemi (4):
  version: refactor redact_non_printables()
  version: refactor get_uname_info()
  connect: advertise OS version
  version: introduce osversion.command config for os-version output

 Documentation/config/transfer.txt |  16 ++++
 Documentation/gitprotocol-v2.txt  |  21 +++++
 builtin/bugreport.c               |  13 +--
 connect.c                         |   3 +
 serve.c                           |  14 +++
 t/t5555-http-smart-common.sh      |  41 ++++++++-
 t/t5701-git-serve.sh              |  45 +++++++++-
 t/test-lib-functions.sh           |   8 ++
 version.c                         | 136 ++++++++++++++++++++++++++++--
 version.h                         |  13 +++
 10 files changed, 291 insertions(+), 19 deletions(-)

-- 
2.47.1