gitprotocolio

package module
v0.0.0-...-b5a5682 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 4, 2021 License: Apache-2.0 Imports: 6 Imported by: 2

README

gitprotocolio

A Git protocol parser written in Go.

This is more like an experimental project to better understand the protocol.

This is not an official Google product (i.e. a 20% project).

Background

Git protocol is defined in Documentation/technical/pack-protocol.txt. This is not a complete definition. Also, a transport specific spec Documentation/technical/http-protocol.txt is not complete. This project was started so that these upstream protocol spec becomes more accurate. To verify the written syntax is accurate, this project includes a Git protocol parser written in Go, and have end-to-end test suites.

This makes it easy to write a test case for Git client. Currently the test cases are run against the canonical Git implementation, but this can be extended to run against JGit, etc.. Also it makes it easy to test an attack case. With this library, one can write an attack case like git-bomb against Git protocol by producing a request that is usually not produced by a sane Git client. Protocol properties can also be checked. For example, it's possible to write a test to check valid request/response's prefixes are not a valid request/response. This property makes sure a client won't process an incomplete response thinking it's complete.

TODOs

  • Protocol semantics is not defined.

    The syntax is relatively complete. The semantics is not even mentioned. One idea is to define the semantics by treating the request/response as an operation to modify Git repositories. This perspective makes it possible to define a formal protocol semantics in a same way as programming language formal semantics.

    Defining a simple git-push semantics seems easy. Defining a pack negotiation semantics for shallow cloned repositories seems difficult.

  • Upstream pack-protocol.txt is not updated.

    The initial purpose, create a complete pack-protocol.txt, is not yet done. We can start from a minor fix (e.g. capability separator in some places is space not NUL). Also relationship between Git protocol and network transports (HTTPS, SSH, Git wire) are good to be mentioned.

  • Bidi-transports are not tested and defined.

    Git's bidi-transports, SSH and Git-wire protocol, are not tested with this project and the protocol syntax is also not defined. The majority of the syntax is same, but there's a slight difference. Go has an SSH library, so it's easy to run a test SSH server.

Documentation

Overview

Package gitprotocolio is a Git protocol parser written in Go.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BytePayloadPacket

type BytePayloadPacket interface {
	Packet
	Bytes() []byte
}

BytePayloadPacket is the interface of Packets that the payload is []byte.

func ParseSideBandPacket

func ParseSideBandPacket(bp BytesPacket) BytePayloadPacket

ParseSideBandPacket parses the BytesPacket as a sideband packet. Returns nil if the packet is not a sideband packet.

type BytesPacket

type BytesPacket []byte

BytesPacket is a packet with a content.

func (BytesPacket) EncodeToPktLine

func (b BytesPacket) EncodeToPktLine() []byte

EncodeToPktLine serializes the packet.

type DelimPacket

type DelimPacket struct{}

DelimPacket is the delim packet ("0001").

func (DelimPacket) EncodeToPktLine

func (DelimPacket) EncodeToPktLine() []byte

EncodeToPktLine serializes the packet.

type ErrorPacket

type ErrorPacket string

ErrorPacket is a packet that indicates an error.

func (ErrorPacket) EncodeToPktLine

func (e ErrorPacket) EncodeToPktLine() []byte

EncodeToPktLine serializes the packet.

func (ErrorPacket) Error

func (e ErrorPacket) Error() string

type FlushPacket

type FlushPacket struct{}

FlushPacket is the flush packet ("0000").

func (FlushPacket) EncodeToPktLine

func (FlushPacket) EncodeToPktLine() []byte

EncodeToPktLine serializes the packet.

type InfoRefsResponse

type InfoRefsResponse struct {
	// contains filtered or unexported fields
}

InfoRefsResponse provides an interface for reading an /info/refs response. The usage is same as bufio.Scanner.

func NewInfoRefsResponse

func NewInfoRefsResponse(rd io.Reader) (r *InfoRefsResponse)

NewInfoRefsResponse returns a new InfoRefsResponse to read from rd.

func (*InfoRefsResponse) Chunk

Chunk returns the most recent response chunk generated by a call to Scan.

func (*InfoRefsResponse) Err

func (r *InfoRefsResponse) Err() error

Err returns the first non-EOF error that was encountered by the InfoRefsResponse.

func (*InfoRefsResponse) Scan

func (r *InfoRefsResponse) Scan() bool

Scan advances the scanner to the next chunk. It returns false when the scan stops, either by reaching the end of the input or an error. After Scan returns false, the Err method will return any error that occurred during scanning, except that if it was io.EOF, Err will return nil.

type InfoRefsResponseChunk

type InfoRefsResponseChunk struct {
	ServiceHeader      string
	ServiceHeaderFlush bool
	ProtocolVersion    uint64
	Capabilities       []string
	ObjectID           string
	Ref                string
	EndOfRequest       bool
}

InfoRefsResponseChunk is a chunk of an /info/refs response.

func (*InfoRefsResponseChunk) EncodeToPktLine

func (c *InfoRefsResponseChunk) EncodeToPktLine() []byte

EncodeToPktLine serializes the chunk.

type PackFileIndicatorPacket

type PackFileIndicatorPacket struct{}

PackFileIndicatorPacket is the indicator of the beginning of the pack file ("PACK").

func (PackFileIndicatorPacket) EncodeToPktLine

func (PackFileIndicatorPacket) EncodeToPktLine() []byte

EncodeToPktLine serializes the packet.

type PackFilePacket

type PackFilePacket []byte

PackFilePacket is a chunk of the pack file.

func (PackFilePacket) EncodeToPktLine

func (p PackFilePacket) EncodeToPktLine() []byte

EncodeToPktLine serializes the packet.

type Packet

type Packet interface {
	EncodeToPktLine() []byte
}

Packet is the interface that wraps a packet line.

type PacketScanner

type PacketScanner struct {
	// contains filtered or unexported fields
}

PacketScanner provides an interface for reading packet line data. The usage is same as bufio.Scanner.

func NewPacketScanner

func NewPacketScanner(r io.Reader) *PacketScanner

NewPacketScanner returns a new PacketScanner to read from r.

func (*PacketScanner) Err

func (s *PacketScanner) Err() error

Err returns the first non-EOF error that was encountered by the PacketScanner.

func (*PacketScanner) Packet

func (s *PacketScanner) Packet() Packet

Packet returns the most recent packet generated by a call to Scan.

func (*PacketScanner) Scan

func (s *PacketScanner) Scan() bool

Scan advances the scanner to the next packet. It returns false when the scan stops, either by reaching the end of the input or an error. After scan returns false, the Err method will return any error that occurred during scanning, except that if it was io.EOF, Err will return nil.

type ProtocolV1ReceivePackRequest

type ProtocolV1ReceivePackRequest struct {
	// contains filtered or unexported fields
}

ProtocolV1ReceivePackRequest provides an interface for reading a protocol v1 git-receive-pack request.

func NewProtocolV1ReceivePackRequest

func NewProtocolV1ReceivePackRequest(rd io.Reader) *ProtocolV1ReceivePackRequest

NewProtocolV1ReceivePackRequest returns a new ProtocolV1ReceivePackRequest to read from rd.

func (*ProtocolV1ReceivePackRequest) Chunk

Chunk returns the most recent chunk generated by a call to Scan.

func (*ProtocolV1ReceivePackRequest) Err

Err returns the first non-EOF error that was encountered by the ProtocolV1ReceivePackRequest.

func (*ProtocolV1ReceivePackRequest) Scan

Scan advances the scanner to the next packet. It returns false when the scan stops, either by reaching the end of the input or an error. After scan returns false, the Err method will return any error that occurred during scanning, except that if it was io.EOF, Err will return nil.

type ProtocolV1ReceivePackRequestChunk

type ProtocolV1ReceivePackRequestChunk struct {
	ClientShallow string

	Capabilities  []string
	OldObjectID   string
	NewObjectID   string
	RefName       string
	EndOfCommands bool

	StartOfPushCert      bool
	PushCertHeader       bool
	Pusher               string
	Pushee               string
	Nonce                string
	CertPushOption       string
	EndOfCertPushOptions bool
	GPGSignaturePart     []byte
	EndOfPushCert        bool

	PushOption       string
	EndOfPushOptions bool

	PackStream []byte
}

ProtocolV1ReceivePackRequestChunk is a chunk of a protocol v1 git-receive-pack request.

func (*ProtocolV1ReceivePackRequestChunk) EncodeToPktLine

func (c *ProtocolV1ReceivePackRequestChunk) EncodeToPktLine() []byte

EncodeToPktLine serializes the chunk.

type ProtocolV1ReceivePackResponse

type ProtocolV1ReceivePackResponse struct {
	// contains filtered or unexported fields
}

ProtocolV1ReceivePackResponse provides an interface for reading a protocol v1 git-receive-pack response.

func NewProtocolV1ReceivePackResponse

func NewProtocolV1ReceivePackResponse(rd io.Reader) *ProtocolV1ReceivePackResponse

NewProtocolV1ReceivePackResponse returns a new ProtocolV1ReceivePackResponse to read from rd.

func (*ProtocolV1ReceivePackResponse) Chunk

Chunk returns the most recent response chunk generated by a call to Scan.

func (*ProtocolV1ReceivePackResponse) Err

Err returns the first non-EOF error that was encountered by the ProtocolV1ReceivePackResponse.

func (*ProtocolV1ReceivePackResponse) Scan

Scan advances the scanner to the next packet. It returns false when the scan stops, either by reaching the end of the input or an error. After scan returns false, the Err method will return any error that occurred during scanning, except that if it was io.EOF, Err will return nil.

type ProtocolV1ReceivePackResponseChunk

type ProtocolV1ReceivePackResponseChunk struct {
	UnpackStatus         string
	RefUpdateStatus      string
	RefName              string
	RefUpdateFailMessage string
	EndOfResponse        bool
}

ProtocolV1ReceivePackResponseChunk is a chunk of a protocol v1 git-receive-pack response.

func (*ProtocolV1ReceivePackResponseChunk) EncodeToPktLine

func (c *ProtocolV1ReceivePackResponseChunk) EncodeToPktLine() []byte

EncodeToPktLine serializes the chunk.

type ProtocolV1UploadPackRequest

type ProtocolV1UploadPackRequest struct {
	// contains filtered or unexported fields
}

ProtocolV1UploadPackRequest provides an interface for reading a protocol v1 git-upload-pack request.

func NewProtocolV1UploadPackRequest

func NewProtocolV1UploadPackRequest(rd io.Reader) *ProtocolV1UploadPackRequest

NewProtocolV1UploadPackRequest returns a new ProtocolV1UploadPackRequest to read from rd.

func (*ProtocolV1UploadPackRequest) Chunk

Chunk returns the most recent chunk generated by a call to Scan.

func (*ProtocolV1UploadPackRequest) Err

Err returns the first non-EOF error that was encountered by the ProtocolV1UploadPackRequest.

func (*ProtocolV1UploadPackRequest) Scan

Scan advances the scanner to the next packet. It returns false when the scan stops, either by reaching the end of the input or an error. After scan returns false, the Err method will return any error that occurred during scanning, except that if it was io.EOF, Err will return nil.

type ProtocolV1UploadPackRequestChunk

type ProtocolV1UploadPackRequestChunk struct {
	Capabilities    []string
	WantObjectID    string
	ShallowObjectID string
	DeepenDepth     int
	// Not documented, but seconds from UNIX epoch.
	DeepenSince       uint64
	DeepenNotRef      string
	FilterSpec        string
	HaveObjectID      string
	EndOneRound       bool
	NoMoreNegotiation bool
}

ProtocolV1UploadPackRequestChunk is a chunk of a protocol v1 git-upload-pack request.

func (*ProtocolV1UploadPackRequestChunk) EncodeToPktLine

func (c *ProtocolV1UploadPackRequestChunk) EncodeToPktLine() []byte

EncodeToPktLine serializes the chunk.

type ProtocolV1UploadPackResponse

type ProtocolV1UploadPackResponse struct {
	// contains filtered or unexported fields
}

ProtocolV1UploadPackResponse provides an interface for reading a protocol v1 git-upload-pack response.

func NewProtocolV1UploadPackResponse

func NewProtocolV1UploadPackResponse(rd io.Reader) *ProtocolV1UploadPackResponse

NewProtocolV1UploadPackResponse returns a new ProtocolV1UploadPackResponse to read from rd.

func (*ProtocolV1UploadPackResponse) Chunk

Chunk returns the most recent chunk generated by a call to Scan.

func (*ProtocolV1UploadPackResponse) Err

Err returns the first non-EOF error that was encountered by the ProtocolV1UploadPackResponse.

func (*ProtocolV1UploadPackResponse) Scan

Scan advances the scanner to the next packet. It returns false when the scan stops, either by reaching the end of the input or an error. After scan returns false, the Err method will return any error that occurred during scanning, except that if it was io.EOF, Err will return nil.

type ProtocolV1UploadPackResponseChunk

type ProtocolV1UploadPackResponseChunk struct {
	ShallowObjectID   string
	UnshallowObjectID string
	EndOfShallows     bool
	AckObjectID       string
	AckDetail         string
	Nak               bool
	PackStream        []byte
	EndOfRequest      bool
}

ProtocolV1UploadPackResponseChunk is a chunk of a protocol v1 git-upload-pack response.

func (*ProtocolV1UploadPackResponseChunk) EncodeToPktLine

func (c *ProtocolV1UploadPackResponseChunk) EncodeToPktLine() []byte

EncodeToPktLine serializes the chunk.

type ProtocolV2Request

type ProtocolV2Request struct {
	// contains filtered or unexported fields
}

ProtocolV2Request provides an interface for reading a protocol v2 request.

func NewProtocolV2Request

func NewProtocolV2Request(rd io.Reader) *ProtocolV2Request

NewProtocolV2Request returns a new ProtocolV2Request to read from rd.

func (*ProtocolV2Request) Chunk

Chunk returns the most recent request chunk generated by a call to Scan.

The underlying array of Argument may point to data that will be overwritten by a subsequent call to Scan. It does no allocation.

func (*ProtocolV2Request) Err

func (r *ProtocolV2Request) Err() error

Err returns the first non-EOF error that was encountered by the ProtocolV2Request.

func (*ProtocolV2Request) Scan

func (r *ProtocolV2Request) Scan() bool

Scan advances the scanner to the next packet. It returns false when the scan stops, either by reaching the end of the input or an error. After scan returns false, the Err method will return any error that occurred during scanning, except that if it was io.EOF, Err will return nil.

type ProtocolV2RequestChunk

type ProtocolV2RequestChunk struct {
	Command       string
	Capability    string
	EndCapability bool
	Argument      []byte
	EndArgument   bool
	EndRequest    bool
}

ProtocolV2RequestChunk is a chunk of a protocol v2 request.

func (*ProtocolV2RequestChunk) EncodeToPktLine

func (c *ProtocolV2RequestChunk) EncodeToPktLine() []byte

EncodeToPktLine serializes the chunk.

type ProtocolV2Response

type ProtocolV2Response struct {
	// contains filtered or unexported fields
}

ProtocolV2Response provides an interface for reading a protocol v2 response.

func NewProtocolV2Response

func NewProtocolV2Response(rd io.Reader) *ProtocolV2Response

NewProtocolV2Response returns a new ProtocolV2Response to read from rd.

func (*ProtocolV2Response) Chunk

Chunk returns the most recent request chunk generated by a call to Scan.

The underlying array of Response may point to data that will be overwritten by a subsequent call to Scan. It does no allocation.

func (*ProtocolV2Response) Err

func (r *ProtocolV2Response) Err() error

Err returns the first non-EOF error that was encountered by the ProtocolV2Response.

func (*ProtocolV2Response) Scan

func (r *ProtocolV2Response) Scan() bool

Scan advances the scanner to the next packet. It returns false when the scan stops, either by reaching the end of the input or an error. After scan returns false, the Err method will return any error that occurred during scanning, except that if it was io.EOF, Err will return nil.

type ProtocolV2ResponseChunk

type ProtocolV2ResponseChunk struct {
	Response    []byte
	Delimiter   bool
	EndResponse bool
}

ProtocolV2ResponseChunk is a chunk of a protocol v2 response.

func (*ProtocolV2ResponseChunk) EncodeToPktLine

func (c *ProtocolV2ResponseChunk) EncodeToPktLine() []byte

EncodeToPktLine serializes the chunk.

type SideBandErrorPacket

type SideBandErrorPacket []byte

SideBandErrorPacket is a sideband packet for the error stream (0x03).

func (SideBandErrorPacket) Bytes

func (p SideBandErrorPacket) Bytes() []byte

Bytes returns the payload.

func (SideBandErrorPacket) EncodeToPktLine

func (p SideBandErrorPacket) EncodeToPktLine() []byte

EncodeToPktLine serializes the packet.

type SideBandMainPacket

type SideBandMainPacket []byte

SideBandMainPacket is a sideband packet for the main stream (0x01).

func (SideBandMainPacket) Bytes

func (p SideBandMainPacket) Bytes() []byte

Bytes returns the payload.

func (SideBandMainPacket) EncodeToPktLine

func (p SideBandMainPacket) EncodeToPktLine() []byte

EncodeToPktLine serializes the packet.

type SideBandReportPacket

type SideBandReportPacket []byte

SideBandReportPacket is a sideband packet for the report stream (0x02).

func (SideBandReportPacket) Bytes

func (p SideBandReportPacket) Bytes() []byte

Bytes returns the payload.

func (SideBandReportPacket) EncodeToPktLine

func (p SideBandReportPacket) EncodeToPktLine() []byte

EncodeToPktLine serializes the packet.

type SyntaxError

type SyntaxError string

SyntaxError is an error returned when the parser cannot parse the input.

func (SyntaxError) Error

func (s SyntaxError) Error() string

type WriteFlushCloser

type WriteFlushCloser interface {
	io.WriteCloser
	Flush() error
}

func NewChunkedWriter

func NewChunkedWriter(sz int) (<-chan []byte, WriteFlushCloser)

Directories

Path Synopsis
testproxy
testproxy is a Git protocol HTTP transport proxy.
testproxy is a Git protocol HTTP transport proxy.
testserver
testserver runs cgit servers.
testserver runs cgit servers.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL