forked from forgejo/forgejo
[Vendor] mssqldb: 2019-11-28 -> 2020-04-28 (#11364)
update go-mssqldb 2019-11-28 (1d7a30a10f73) -> 2020-04-28 (06a60b6afbbc)
This commit is contained in:
parent
da5e3fa299
commit
6e23a1b843
27 changed files with 987 additions and 1378 deletions
146
vendor/github.com/denisenkom/go-mssqldb/tds.go
generated
vendored
146
vendor/github.com/denisenkom/go-mssqldb/tds.go
generated
vendored
|
@ -100,13 +100,15 @@ const (
|
|||
// prelogin fields
|
||||
// http://msdn.microsoft.com/en-us/library/dd357559.aspx
|
||||
const (
|
||||
preloginVERSION = 0
|
||||
preloginENCRYPTION = 1
|
||||
preloginINSTOPT = 2
|
||||
preloginTHREADID = 3
|
||||
preloginMARS = 4
|
||||
preloginTRACEID = 5
|
||||
preloginTERMINATOR = 0xff
|
||||
preloginVERSION = 0
|
||||
preloginENCRYPTION = 1
|
||||
preloginINSTOPT = 2
|
||||
preloginTHREADID = 3
|
||||
preloginMARS = 4
|
||||
preloginTRACEID = 5
|
||||
preloginFEDAUTHREQUIRED = 6
|
||||
preloginNONCEOPT = 7
|
||||
preloginTERMINATOR = 0xff
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -245,6 +247,12 @@ const (
|
|||
fReadOnlyIntent = 32
|
||||
)
|
||||
|
||||
// OptionFlags3
|
||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/773a62b6-ee89-4c02-9e5e-344882630aac
|
||||
const (
|
||||
fExtension = 0x10
|
||||
)
|
||||
|
||||
type login struct {
|
||||
TDSVersion uint32
|
||||
PacketSize uint32
|
||||
|
@ -269,6 +277,89 @@ type login struct {
|
|||
SSPI []byte
|
||||
AtchDBFile string
|
||||
ChangePassword string
|
||||
FeatureExt featureExts
|
||||
}
|
||||
|
||||
type featureExts struct {
|
||||
features map[byte]featureExt
|
||||
}
|
||||
|
||||
type featureExt interface {
|
||||
featureID() byte
|
||||
toBytes() []byte
|
||||
}
|
||||
|
||||
func (e *featureExts) Add(f featureExt) error {
|
||||
if f == nil {
|
||||
return nil
|
||||
}
|
||||
id := f.featureID()
|
||||
if _, exists := e.features[id]; exists {
|
||||
f := "Login error: Feature with ID '%v' is already present in FeatureExt block."
|
||||
return fmt.Errorf(f, id)
|
||||
}
|
||||
if e.features == nil {
|
||||
e.features = make(map[byte]featureExt)
|
||||
}
|
||||
e.features[id] = f
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e featureExts) toBytes() []byte {
|
||||
if len(e.features) == 0 {
|
||||
return nil
|
||||
}
|
||||
var d []byte
|
||||
for featureID, f := range e.features {
|
||||
featureData := f.toBytes()
|
||||
|
||||
hdr := make([]byte, 5)
|
||||
hdr[0] = featureID // FedAuth feature extension BYTE
|
||||
binary.LittleEndian.PutUint32(hdr[1:], uint32(len(featureData))) // FeatureDataLen DWORD
|
||||
d = append(d, hdr...)
|
||||
|
||||
d = append(d, featureData...) // FeatureData *BYTE
|
||||
}
|
||||
if d != nil {
|
||||
d = append(d, 0xff) // Terminator
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
type featureExtFedAuthSTS struct {
|
||||
FedAuthEcho bool
|
||||
FedAuthToken string
|
||||
Nonce []byte
|
||||
}
|
||||
|
||||
func (e *featureExtFedAuthSTS) featureID() byte {
|
||||
return 0x02
|
||||
}
|
||||
|
||||
func (e *featureExtFedAuthSTS) toBytes() []byte {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
options := byte(0x01) << 1 // 0x01 => STS bFedAuthLibrary 7BIT
|
||||
if e.FedAuthEcho {
|
||||
options |= 1 // fFedAuthEcho
|
||||
}
|
||||
|
||||
d := make([]byte, 5)
|
||||
d[0] = options
|
||||
|
||||
// looks like string in
|
||||
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/f88b63bb-b479-49e1-a87b-deda521da508
|
||||
tokenBytes := str2ucs2(e.FedAuthToken)
|
||||
binary.LittleEndian.PutUint32(d[1:], uint32(len(tokenBytes))) // Should be a signed int32, but since the length is relatively small, this should work
|
||||
d = append(d, tokenBytes...)
|
||||
|
||||
if len(e.Nonce) == 32 {
|
||||
d = append(d, e.Nonce...)
|
||||
}
|
||||
|
||||
return d
|
||||
}
|
||||
|
||||
type loginHeader struct {
|
||||
|
@ -295,7 +386,7 @@ type loginHeader struct {
|
|||
ServerNameOffset uint16
|
||||
ServerNameLength uint16
|
||||
ExtensionOffset uint16
|
||||
ExtensionLenght uint16
|
||||
ExtensionLength uint16
|
||||
CtlIntNameOffset uint16
|
||||
CtlIntNameLength uint16
|
||||
LanguageOffset uint16
|
||||
|
@ -357,6 +448,8 @@ func sendLogin(w *tdsBuffer, login login) error {
|
|||
database := str2ucs2(login.Database)
|
||||
atchdbfile := str2ucs2(login.AtchDBFile)
|
||||
changepassword := str2ucs2(login.ChangePassword)
|
||||
featureExt := login.FeatureExt.toBytes()
|
||||
|
||||
hdr := loginHeader{
|
||||
TDSVersion: login.TDSVersion,
|
||||
PacketSize: login.PacketSize,
|
||||
|
@ -405,7 +498,18 @@ func sendLogin(w *tdsBuffer, login login) error {
|
|||
offset += uint16(len(atchdbfile))
|
||||
hdr.ChangePasswordOffset = offset
|
||||
offset += uint16(len(changepassword))
|
||||
hdr.Length = uint32(offset)
|
||||
|
||||
featureExtOffset := uint32(0)
|
||||
featureExtLen := len(featureExt)
|
||||
if featureExtLen > 0 {
|
||||
hdr.OptionFlags3 |= fExtension
|
||||
hdr.ExtensionOffset = offset
|
||||
hdr.ExtensionLength = 4
|
||||
offset += hdr.ExtensionLength // DWORD
|
||||
featureExtOffset = uint32(offset)
|
||||
}
|
||||
hdr.Length = uint32(offset) + uint32(featureExtLen)
|
||||
|
||||
var err error
|
||||
err = binary.Write(w, binary.LittleEndian, &hdr)
|
||||
if err != nil {
|
||||
|
@ -455,6 +559,16 @@ func sendLogin(w *tdsBuffer, login login) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if featureExtOffset > 0 {
|
||||
err = binary.Write(w, binary.LittleEndian, featureExtOffset)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = w.Write(featureExt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return w.FinishPacket()
|
||||
}
|
||||
|
||||
|
@ -844,15 +958,23 @@ initiate_connection:
|
|||
AppName: p.appname,
|
||||
TypeFlags: p.typeFlags,
|
||||
}
|
||||
auth, auth_ok := getAuth(p.user, p.password, p.serverSPN, p.workstation)
|
||||
if auth_ok {
|
||||
auth, authOk := getAuth(p.user, p.password, p.serverSPN, p.workstation)
|
||||
switch {
|
||||
case p.fedAuthAccessToken != "": // accesstoken ignores user/password
|
||||
featurext := &featureExtFedAuthSTS{
|
||||
FedAuthEcho: len(fields[preloginFEDAUTHREQUIRED]) > 0 && fields[preloginFEDAUTHREQUIRED][0] == 1,
|
||||
FedAuthToken: p.fedAuthAccessToken,
|
||||
Nonce: fields[preloginNONCEOPT],
|
||||
}
|
||||
login.FeatureExt.Add(featurext)
|
||||
case authOk:
|
||||
login.SSPI, err = auth.InitialBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
login.OptionFlags2 |= fIntSecurity
|
||||
defer auth.Free()
|
||||
} else {
|
||||
default:
|
||||
login.UserName = p.user
|
||||
login.Password = p.password
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue