> On Aug 4, 2022, at 04:27, Junio C Hamano <gitster@xxxxxxxxx> wrote: > > "Sun Chao via GitGitGadget" <gitgitgadget@xxxxxxxxx> writes: > >> Gerrit is implemented by JGit and is known as a centralized workflow system >> which supports reference-level access control for repository. If we choose >> to work in centralized workflow like what Gerrit provided, reference-level >> access control is needed and is possible if we add a reference advertise >> filter hook just like what Gerrit did. > > It may be one starting point, but is it sufficient to call it > "possible"? The server side needs to tighten "fetch by object name" > to refuse to serve objects that are not reachable from any of the > refs advertised to the client requesting them. IIRC, fetch protocol > v2 is wide open and does not limit the requests to those that are > only reachable from the advertised refs. > > Hi Junio, thanks for you reply. I agree with you that the server need to refuse the fetch requests that want to steal objects not reachable from the advertised refs. So I have tried to understand the source codes of of `ls-refs.c` and `upload-pack.c` (maybe I lost some important files), and I put a new function `filter_advertise_object` to call `refs-advertise` hook checks the `want` objects. ```diff @@ -1118,7 +1119,7 @@ static void receive_needs(struct upload_pack_data *data, } o = parse_object(the_repository, &oid_buf); - if (!o) { + if ((!o) || (filter_advertise_object(&oid_buf))) { packet_writer_error(&data->writer, "upload-pack: not our ref %s", oid_to_hex(&oid_buf)); ... @@ -1421,7 +1445,7 @@ static int parse_want(struct packet_writer *writer, const char *line, else o = parse_object(the_repository, &oid); - if (!o) { + if ((!o) || (filter_advertise_object(&oid))) { packet_writer_error(writer, "upload-pack: not our ref %s", oid_to_hex(&oid)); ``` The `filter_advertise_object` will exchange messages with the hook by pkt-line messages, eg: # Send commit filter request to hook G: PKT-LINE(obj <oid>) G: flush-pkt # Receive result from the hook. # Case 1: this object is valid H: PKT-LINE(ok obj <oid>) H: flush-pkt # Case 2: this object is filtered out H: PKT-LINE(ng obj <oid>) H: flush-pkt the hook can check if the `oid` is valid for the client and returns `ng` message if not, so git server will hide the objects to the client. And I added some test cases for upload-pack V1 and V2 and looks like it works, but maybe I lost some important points and I'm still trying to understand other codes for upload-pack and receive-pack because currently I only implements the filter process for upload-pack and receive-pack. Thanks for your reply again.