go-hep.org/x/hep@v0.38.1/xrootd/xrdproto/protocol/protocol.go (about)

     1  // Copyright ©2018 The go-hep Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package protocol contains the structures describing request and response
     6  // for protocol request (see XRootD specification).
     7  //
     8  // A response consists of 3 parts:
     9  //
    10  // 1) A general response that is always returned and specifies protocol version and flags describing server type.
    11  //
    12  // 2) A response part that is added to the general response
    13  // if `ReturnSecurityRequirements` is provided and server supports it.
    14  // It contains the security version, the security options, the security level,
    15  // and the number of following security overrides, if any.
    16  //
    17  // 3) A list of SecurityOverride - alterations needed to the specified predefined security level.
    18  package protocol // import "go-hep.org/x/hep/xrootd/xrdproto/protocol"
    19  
    20  import (
    21  	"go-hep.org/x/hep/xrootd/internal/xrdenc"
    22  	"go-hep.org/x/hep/xrootd/xrdproto"
    23  )
    24  
    25  // RequestID is the id of the request, it is sent as part of message.
    26  // See xrootd protocol specification for details: http://xrootd.org/doc/dev45/XRdv310.pdf, 2.3 Client Request Format.
    27  const RequestID uint16 = 3006
    28  
    29  // Flags are the Flags that define xrootd server type. See xrootd protocol specification for further info.
    30  type Flags int32
    31  
    32  const (
    33  	IsServer     Flags = 0x00000001 // IsServer indicates whether this server has server role.
    34  	IsManager    Flags = 0x00000002 // IsManager indicates whether this server has manager role.
    35  	IsMeta       Flags = 0x00000100 // IsMeta indicates whether this server has meta attribute.
    36  	IsProxy      Flags = 0x00000200 // IsProxy indicates whether this server has proxy attribute.
    37  	IsSupervisor Flags = 0x00000400 // IsSupervisor indicates whether this server has supervisor attribute.
    38  )
    39  
    40  // SecurityOptions are the security-related options.
    41  // See specification for details: http://xrootd.org/doc/dev45/XRdv310.pdf, p. 72.
    42  type SecurityOptions byte
    43  
    44  const (
    45  	// ForceSecurity specifies that signing is required even if the authentication
    46  	// protocol does not support generic encryption.
    47  	ForceSecurity SecurityOptions = 0x02
    48  )
    49  
    50  // RequestOptions specifies what should be returned as part of response.
    51  type RequestOptions byte
    52  
    53  const (
    54  	// RequestOptionsNone specifies that only general response should be returned.
    55  	RequestOptionsNone RequestOptions = 0
    56  	// ReturnSecurityRequirements specifies that security requirements should be returned
    57  	// if that's supported by the server.
    58  	ReturnSecurityRequirements RequestOptions = 1
    59  )
    60  
    61  // Request holds protocol request parameters.
    62  type Request struct {
    63  	ClientProtocolVersion int32
    64  	Options               RequestOptions
    65  	_                     [11]byte
    66  	_                     int32
    67  }
    68  
    69  // NewRequest forms a Request according to provided parameters.
    70  func NewRequest(protocolVersion int32, withSecurityRequirements bool) *Request {
    71  	var options = RequestOptionsNone
    72  	if withSecurityRequirements {
    73  		options |= ReturnSecurityRequirements
    74  	}
    75  	return &Request{ClientProtocolVersion: protocolVersion, Options: options}
    76  }
    77  
    78  // ReqID implements xrdproto.Request.ReqID.
    79  func (req *Request) ReqID() uint16 { return RequestID }
    80  
    81  // MarshalXrd implements xrdproto.Marshaler.
    82  func (o Request) MarshalXrd(wBuffer *xrdenc.WBuffer) error {
    83  	wBuffer.WriteI32(o.ClientProtocolVersion)
    84  	wBuffer.WriteU8(byte(o.Options))
    85  	wBuffer.Next(15)
    86  	return nil
    87  }
    88  
    89  // UnmarshalXrd implements xrdproto.Unmarshaler.
    90  func (o *Request) UnmarshalXrd(rBuffer *xrdenc.RBuffer) error {
    91  	o.ClientProtocolVersion = rBuffer.ReadI32()
    92  	o.Options = RequestOptions(rBuffer.ReadU8())
    93  	rBuffer.Skip(15)
    94  	return nil
    95  }
    96  
    97  // Response is a response for the `Protocol` request. See details in the xrootd protocol specification.
    98  type Response struct {
    99  	BinaryProtocolVersion int32
   100  	Flags                 Flags
   101  	HasSecurityInfo       bool
   102  	_                     byte
   103  	_                     byte
   104  	SecurityVersion       byte
   105  	SecurityOptions       SecurityOptions
   106  	SecurityLevel         xrdproto.SecurityLevel
   107  	SecurityOverrides     []xrdproto.SecurityOverride
   108  }
   109  
   110  // IsManager indicates whether this server has manager role.
   111  func (resp *Response) IsManager() bool {
   112  	return resp.Flags&IsManager != 0
   113  }
   114  
   115  // IsServer indicates whether this server has server role.
   116  func (resp *Response) IsServer() bool {
   117  	return resp.Flags&IsServer != 0
   118  }
   119  
   120  // IsMeta indicates whether this server has meta attribute.
   121  func (resp *Response) IsMeta() bool {
   122  	return resp.Flags&IsMeta != 0
   123  }
   124  
   125  // IsProxy indicates whether this server has proxy attribute.
   126  func (resp *Response) IsProxy() bool {
   127  	return resp.Flags&IsProxy != 0
   128  }
   129  
   130  // IsSupervisor indicates whether this server has supervisor attribute.
   131  func (resp *Response) IsSupervisor() bool {
   132  	return resp.Flags&IsSupervisor != 0
   133  }
   134  
   135  // ForceSecurity indicates whether signing is required even if the authentication
   136  // protocol does not support generic encryption.
   137  func (resp *Response) ForceSecurity() bool {
   138  	return resp.SecurityOptions&ForceSecurity != 0
   139  }
   140  
   141  // MarshalXrd implements xrdproto.Marshaler.
   142  func (o Response) MarshalXrd(wBuffer *xrdenc.WBuffer) error {
   143  	wBuffer.WriteI32(o.BinaryProtocolVersion)
   144  	wBuffer.WriteI32(int32(o.Flags))
   145  	if !o.HasSecurityInfo {
   146  		return nil
   147  	}
   148  	wBuffer.WriteU8('S')
   149  	wBuffer.Next(1)
   150  	wBuffer.WriteU8(o.SecurityVersion)
   151  	wBuffer.WriteU8(byte(o.SecurityOptions))
   152  	wBuffer.WriteU8(byte(o.SecurityLevel))
   153  	wBuffer.WriteU8(uint8(len(o.SecurityOverrides)))
   154  	for _, x := range o.SecurityOverrides {
   155  		err := x.MarshalXrd(wBuffer)
   156  		if err != nil {
   157  			return err
   158  		}
   159  	}
   160  	return nil
   161  }
   162  
   163  // UnmarshalXrd implements xrdproto.Unmarshaler.
   164  func (o *Response) UnmarshalXrd(rBuffer *xrdenc.RBuffer) error {
   165  	o.BinaryProtocolVersion = rBuffer.ReadI32()
   166  	o.Flags = Flags(rBuffer.ReadI32())
   167  	if rBuffer.Len() == 0 {
   168  		return nil
   169  	}
   170  	o.HasSecurityInfo = true
   171  	rBuffer.Skip(1)
   172  	rBuffer.Skip(1)
   173  	o.SecurityVersion = rBuffer.ReadU8()
   174  	o.SecurityOptions = SecurityOptions(rBuffer.ReadU8())
   175  	o.SecurityLevel = xrdproto.SecurityLevel(rBuffer.ReadU8())
   176  	o.SecurityOverrides = make([]xrdproto.SecurityOverride, rBuffer.ReadU8())
   177  	for i := range o.SecurityOverrides {
   178  		err := o.SecurityOverrides[i].UnmarshalXrd(rBuffer)
   179  		if err != nil {
   180  			return err
   181  		}
   182  	}
   183  	return nil
   184  }
   185  
   186  // RespID implements xrdproto.Response.RespID.
   187  func (resp *Response) RespID() uint16 { return RequestID }
   188  
   189  // ShouldSign implements xrdproto.Request.ShouldSign.
   190  func (req *Request) ShouldSign() bool { return false }