2020-08-05 05:17:05 +00:00
|
|
|
package statute
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
)
|
|
|
|
|
2020-08-05 09:32:37 +00:00
|
|
|
// auth error defined
|
|
|
|
var (
|
|
|
|
ErrUserAuthFailed = fmt.Errorf("user authentication failed")
|
|
|
|
ErrNoSupportedAuth = fmt.Errorf("no supported authentication mechanism")
|
|
|
|
)
|
|
|
|
|
2020-08-05 05:17:05 +00:00
|
|
|
// UserPassRequest is the negotiation user's password request packet
|
|
|
|
// The SOCKS handshake user's password request is formed as follows:
|
|
|
|
// +--------------+------+----------+------+----------+
|
|
|
|
// | USERPASS_VER | ULEN | USER | PLEN | PASS |
|
|
|
|
// +--------------+------+----------+------+----------+
|
|
|
|
// | 1 | 1 | Variable | 1 | Variable |
|
|
|
|
// +--------------+------+----------+------+----------+
|
|
|
|
type UserPassRequest struct {
|
|
|
|
Ver byte
|
|
|
|
Ulen byte
|
|
|
|
Plen byte
|
2020-08-06 01:20:43 +00:00
|
|
|
User []byte // 1-255 bytes
|
2020-08-05 05:17:05 +00:00
|
|
|
Pass []byte // 1-255 bytes
|
|
|
|
}
|
|
|
|
|
2020-08-05 05:54:05 +00:00
|
|
|
// NewUserPassRequest new user's password request packet with ver,user, pass
|
|
|
|
func NewUserPassRequest(ver byte, user, pass []byte) UserPassRequest {
|
2020-08-05 05:17:05 +00:00
|
|
|
return UserPassRequest{
|
|
|
|
ver,
|
|
|
|
byte(len(user)),
|
|
|
|
byte(len(pass)),
|
2020-08-06 01:20:43 +00:00
|
|
|
user,
|
2020-08-05 05:17:05 +00:00
|
|
|
pass,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-05 05:54:05 +00:00
|
|
|
// ParseUserPassRequest parse user's password request.
|
2020-08-05 05:17:05 +00:00
|
|
|
func ParseUserPassRequest(r io.Reader) (nup UserPassRequest, err error) {
|
2020-08-06 01:20:43 +00:00
|
|
|
tmp := []byte{0, 0}
|
|
|
|
|
2020-08-05 05:17:05 +00:00
|
|
|
// Get the version and username length
|
2020-08-06 01:20:43 +00:00
|
|
|
if _, err = io.ReadAtLeast(r, tmp, 2); err != nil {
|
2020-08-05 05:17:05 +00:00
|
|
|
return
|
|
|
|
}
|
2020-08-06 01:20:43 +00:00
|
|
|
nup.Ver, nup.Ulen = tmp[0], tmp[1]
|
2020-08-05 05:54:05 +00:00
|
|
|
|
2020-08-06 01:20:43 +00:00
|
|
|
// Ensure the UserPass version
|
2020-08-05 05:54:05 +00:00
|
|
|
if nup.Ver != UserPassAuthVersion {
|
2020-08-06 01:20:43 +00:00
|
|
|
err = fmt.Errorf("unsupported auth version: %v", nup.Ver)
|
2020-08-05 05:17:05 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the user name
|
|
|
|
nup.User = make([]byte, nup.Ulen)
|
|
|
|
if _, err = io.ReadAtLeast(r, nup.User, int(nup.Ulen)); err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the password length
|
2020-08-06 01:20:43 +00:00
|
|
|
if _, err = r.Read(tmp[:1]); err != nil {
|
2020-08-05 05:17:05 +00:00
|
|
|
return
|
|
|
|
}
|
2020-08-06 01:20:43 +00:00
|
|
|
nup.Plen = tmp[0]
|
|
|
|
|
2020-08-05 05:17:05 +00:00
|
|
|
// Get the password
|
|
|
|
nup.Pass = make([]byte, nup.Plen)
|
|
|
|
_, err = io.ReadAtLeast(r, nup.Pass, int(nup.Plen))
|
2020-08-30 03:15:05 +00:00
|
|
|
return nup, err
|
2020-08-05 05:17:05 +00:00
|
|
|
}
|
|
|
|
|
2020-08-06 01:20:43 +00:00
|
|
|
// Bytes to bytes
|
2020-08-05 05:17:05 +00:00
|
|
|
func (sf UserPassRequest) Bytes() []byte {
|
|
|
|
b := make([]byte, 0, 3+sf.Ulen+sf.Plen)
|
|
|
|
b = append(b, sf.Ver, sf.Ulen)
|
|
|
|
b = append(b, sf.User...)
|
|
|
|
b = append(b, sf.Plen)
|
|
|
|
b = append(b, sf.Pass...)
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
|
|
|
// UserPassReply is the negotiation user's password reply packet
|
|
|
|
// The SOCKS handshake user's password response is formed as follows:
|
|
|
|
// +-----+--------+
|
|
|
|
// | VER | status |
|
|
|
|
// +-----+--------+
|
|
|
|
// | 1 | 1 |
|
|
|
|
// +-----+--------+
|
|
|
|
type UserPassReply struct {
|
|
|
|
Ver byte
|
|
|
|
Status byte
|
|
|
|
}
|
|
|
|
|
2020-08-05 05:54:05 +00:00
|
|
|
// ParseUserPassReply parse user's password reply packet.
|
2020-08-06 01:20:43 +00:00
|
|
|
func ParseUserPassReply(r io.Reader) (upr UserPassReply, err error) {
|
2020-08-05 07:27:22 +00:00
|
|
|
bb := []byte{0, 0}
|
2020-08-05 05:17:05 +00:00
|
|
|
if _, err = io.ReadFull(r, bb); err != nil {
|
|
|
|
return
|
|
|
|
}
|
2020-08-06 01:20:43 +00:00
|
|
|
upr.Ver, upr.Status = bb[0], bb[1]
|
2020-08-05 05:17:05 +00:00
|
|
|
return
|
|
|
|
}
|