109 lines
2.2 KiB
Go
109 lines
2.2 KiB
Go
package socks5
|
|
|
|
import (
|
|
"io"
|
|
)
|
|
|
|
// NegotiationRequest is the negotiation request packet
|
|
type NegotiationRequest struct {
|
|
NMethods int
|
|
Methods []AuthMethod
|
|
}
|
|
|
|
// NewNegotiationRequest returns new negotiation request packet
|
|
func NewNegotiationRequest(methods []AuthMethod) *NegotiationRequest {
|
|
return &NegotiationRequest{
|
|
NMethods: len(methods),
|
|
Methods: methods,
|
|
}
|
|
}
|
|
|
|
// NewNegotiationRequestFrom reads negotiation request packet from reader
|
|
func NewNegotiationRequestFrom(r io.Reader) (*NegotiationRequest, error) {
|
|
buf := make([]byte, 2)
|
|
if _, err := io.ReadFull(r, buf); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if buf[0] != Version {
|
|
return nil, ErrVersion
|
|
}
|
|
|
|
methodsLen := int(buf[1])
|
|
if methodsLen == 0 {
|
|
return nil, ErrBadRequest
|
|
}
|
|
|
|
methodsBytes := make([]byte, methodsLen)
|
|
if _, err := io.ReadFull(r, methodsBytes); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
methods := make([]AuthMethod, methodsLen)
|
|
for i := range methodsBytes {
|
|
methods[i] = AuthMethod(methodsBytes[i])
|
|
}
|
|
|
|
req := &NegotiationRequest{
|
|
NMethods: methodsLen,
|
|
Methods: methods,
|
|
}
|
|
|
|
return req, nil
|
|
}
|
|
|
|
// WriteTo writes negotiation request packet
|
|
func (s *NegotiationRequest) WriteTo(w io.Writer) (int64, error) {
|
|
buf := []byte{Version, byte(s.NMethods)}
|
|
for i := range s.Methods {
|
|
buf = append(buf, byte(s.Methods[i]))
|
|
}
|
|
|
|
n, err := w.Write(buf)
|
|
if err != nil {
|
|
return int64(n), err
|
|
}
|
|
|
|
return int64(n), nil
|
|
}
|
|
|
|
// NegotiationReply is the negotiation reply packet
|
|
type NegotiationReply struct {
|
|
Method AuthMethod
|
|
}
|
|
|
|
// NewNegotiationReply returns new negotiation reply packet
|
|
func NewNegotiationReply(method AuthMethod) *NegotiationReply {
|
|
return &NegotiationReply{
|
|
Method: method,
|
|
}
|
|
}
|
|
|
|
// NewNegotiationReplyFrom reads negotiation reply packet from reader
|
|
func NewNegotiationReplyFrom(r io.Reader) (*NegotiationReply, error) {
|
|
buf := make([]byte, 2)
|
|
if _, err := io.ReadFull(r, buf); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if buf[0] != Version {
|
|
return nil, ErrVersion
|
|
}
|
|
|
|
rep := &NegotiationReply{
|
|
Method: AuthMethod(buf[1]),
|
|
}
|
|
|
|
return rep, nil
|
|
}
|
|
|
|
// WriteTo writes negotiation reply packet
|
|
func (s *NegotiationReply) WriteTo(w io.Writer) (int64, error) {
|
|
n, err := w.Write([]byte{Version, byte(s.Method)})
|
|
if err != nil {
|
|
return int64(n), err
|
|
}
|
|
|
|
return int64(n), nil
|
|
}
|