forked from sijms/go-ora
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pre-release version 2 of the client major changes:
1- update client version to: 2- update ttc version to: 9 3- use 4 byte packet length instead of 2 bytes 4- use advanced negotiation 5- define NCHARSET in the data type negotiation and 6- use big clear chunks 7- use more verifier type in authentication object 8- receive session properties after authentication without calling getNLSData()
- Loading branch information
Showing
27 changed files
with
2,450 additions
and
461 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package advanced_nego | ||
|
||
import ( | ||
"errors" | ||
"github.com/sijms/go-ora/network" | ||
) | ||
|
||
type AdvNego struct { | ||
serviceList []AdvNegoService | ||
} | ||
|
||
func NewAdvNego(connOption *network.ConnectionOption) (*AdvNego, error) { | ||
output := &AdvNego{ | ||
serviceList: make([]AdvNegoService, 5), | ||
} | ||
var err error | ||
output.serviceList[1], err = NewAuthService(connOption) | ||
if err != nil { | ||
return nil, err | ||
} | ||
output.serviceList[2], err = NewEncryptService(connOption) | ||
if err != nil { | ||
return nil, err | ||
} | ||
output.serviceList[3], err = NewDataIntegrityService(connOption) | ||
if err != nil { | ||
return nil, err | ||
} | ||
output.serviceList[4], err = NewSupervisorService() | ||
if err != nil { | ||
return nil, err | ||
} | ||
return output, nil | ||
} | ||
func (nego *AdvNego) readHeader(session *network.Session) ([]int, error) { | ||
num, err := session.GetInt(4, false, true) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if num != 0xDEADBEEF { | ||
return nil, errors.New("advanced negotiation error: during receive header") | ||
} | ||
output := make([]int, 4) | ||
output[0], err = session.GetInt(2, false, true) | ||
if err != nil { | ||
return nil, err | ||
} | ||
output[1], err = session.GetInt(4, false, true) | ||
if err != nil { | ||
return nil, err | ||
} | ||
output[2], err = session.GetInt(2, false, true) | ||
if err != nil { | ||
return nil, err | ||
} | ||
output[3], err = session.GetInt(1, false, true) | ||
return output, err | ||
} | ||
func (nego *AdvNego) readServiceHeader(session *network.Session) ([]int, error) { | ||
output := make([]int, 3) | ||
var err error | ||
output[0], err = session.GetInt(2, false, true) | ||
if err != nil { | ||
return nil, err | ||
} | ||
output[1], err = session.GetInt(2, false, true) | ||
if err != nil { | ||
return nil, err | ||
} | ||
output[2], err = session.GetInt(4, false, true) | ||
return output, err | ||
} | ||
func (nego *AdvNego) Read(session *network.Session) error { | ||
header, err := nego.readHeader(session) | ||
if err != nil { | ||
return err | ||
} | ||
for i := 0; i < header[2]; i++ { | ||
serviceHeader, err := nego.readServiceHeader(session) | ||
if err != nil { | ||
return err | ||
} | ||
if serviceHeader[2] != 0 { | ||
return errors.New("advanced negotiation error: during receive service header") | ||
} | ||
err = nego.serviceList[serviceHeader[0]].readServiceData(session, serviceHeader[1]) | ||
if err != nil { | ||
return err | ||
} | ||
err = nego.serviceList[serviceHeader[0]].validateResponse() | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
for i := 1; i < 5; i++ { | ||
err = nego.serviceList[i].activateAlgorithm() | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
if authServ, ok := nego.serviceList[1].(*authService); ok { | ||
if authServ.active { | ||
errors.New("advanced negotiation: advanced authentication still not supported") | ||
if authServ.serviceName == "KERBEROS5" { | ||
|
||
} else if authServ.serviceName == "NTS" { | ||
|
||
} | ||
} | ||
} | ||
return nil | ||
} | ||
func (nego *AdvNego) Write(session *network.Session) error { | ||
session.ResetBuffer() | ||
size := 0 | ||
for i := 1; i < 5; i++ { | ||
size = size + 8 + nego.serviceList[i].getServiceDataLength() | ||
} | ||
size += 13 | ||
session.PutInt(0xDEADBEEF, 4, true, false) | ||
session.PutInt(size, 2, true, false) | ||
session.PutInt(nego.serviceList[1].getVersion(), 4, true, false) | ||
session.PutInt(4, 2, true, false) | ||
session.PutBytes(0) | ||
err := nego.serviceList[4].writeServiceData(session) | ||
if err != nil { | ||
return err | ||
} | ||
err = nego.serviceList[1].writeServiceData(session) | ||
if err != nil { | ||
return err | ||
} | ||
err = nego.serviceList[2].writeServiceData(session) | ||
if err != nil { | ||
return err | ||
} | ||
err = nego.serviceList[3].writeServiceData(session) | ||
if err != nil { | ||
return err | ||
} | ||
return session.Write() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
package advanced_nego | ||
|
||
import ( | ||
"errors" | ||
"github.com/sijms/go-ora/network" | ||
"runtime" | ||
) | ||
|
||
type authService struct { | ||
defaultService | ||
status int | ||
serviceName string | ||
active bool | ||
} | ||
|
||
func NewAuthService(connOption *network.ConnectionOption) (*authService, error) { | ||
output := &authService{ | ||
defaultService: defaultService{ | ||
serviceType: 1, | ||
level: -1, | ||
version: 0xB200200, | ||
}, | ||
status: 0xFCFF, | ||
} | ||
//var avaAuth []string | ||
if runtime.GOOS == "windows" { | ||
output.availableServiceNames = []string{"", "NTS", "KERBEROS5", "TCPS"} | ||
output.availableServiceIDs = []int{0, 1, 1, 2} | ||
} else { | ||
output.availableServiceNames = []string{"TCPS"} | ||
output.availableServiceIDs = []int{2} | ||
} | ||
str := "" | ||
if connOption != nil { | ||
snConfig := connOption.SNOConfig | ||
if snConfig != nil { | ||
var exists bool | ||
str, exists = snConfig["sqlnet.authentication_services"] | ||
if !exists { | ||
str = "" | ||
} | ||
} | ||
} | ||
//level := conops.Encryption != null ? conops.Encryption : snoConfig[]; | ||
err := output.buildServiceList(str, false, false) | ||
//output.selectedServ, err = output.validate(strings.Split(str,","), true) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return output, nil | ||
/* user list is found in the dictionary | ||
sessCtx.m_conops.SNOConfig["sqlnet.authentication_services"] | ||
*/ | ||
/* you need to confirm that every item in user list found in avaAuth list | ||
then for each item in userList you need to get index of it in the avaAuth | ||
return output*/ | ||
} | ||
|
||
func (serv *authService) writeServiceData(session *network.Session) error { | ||
serv.writeHeader(session, 3+(len(serv.selectedIndices)*2)) | ||
err := serv.writeVersion(session) | ||
if err != nil { | ||
return err | ||
} | ||
err = serv.writePacketHeader(session, 2, 3) | ||
if err != nil { | ||
return err | ||
} | ||
session.PutInt(0xE0E1, 2, true, false) | ||
err = serv.writePacketHeader(session, 2, 6) | ||
if err != nil { | ||
return err | ||
} | ||
session.PutInt(serv.status, 2, true, false) | ||
for i := 0; i < len(serv.selectedIndices); i++ { | ||
index := serv.selectedIndices[i] | ||
session.PutBytes(uint8(serv.availableServiceIDs[index])) | ||
session.PutBytes([]byte(serv.availableServiceNames[index])...) | ||
} | ||
return nil | ||
} | ||
|
||
func (serv *authService) readServiceData(session *network.Session, subPacketNum int) error { | ||
// read version | ||
var err error | ||
serv.version, err = serv.readVersion(session) | ||
if err != nil { | ||
return err | ||
} | ||
// read status | ||
_, err = serv.readPacketHeader(session, 6) | ||
if err != nil { | ||
return err | ||
} | ||
status, err := session.GetInt(2, false, true) | ||
if err != nil { | ||
return err | ||
} | ||
if status == 0xFAFF && subPacketNum > 2 { | ||
// get 1 byte with header | ||
_, err = serv.readPacketHeader(session, 2) | ||
if err != nil { | ||
return err | ||
} | ||
_, err = session.GetByte() | ||
if err != nil { | ||
return err | ||
} | ||
stringLen, err := serv.readPacketHeader(session, 0) | ||
if err != nil { | ||
return err | ||
} | ||
serviceNameBytes, err := session.GetBytes(stringLen) | ||
if err != nil { | ||
return err | ||
} | ||
serv.serviceName = string(serviceNameBytes) | ||
if subPacketNum > 4 { | ||
_, err = serv.readVersion(session) | ||
if err != nil { | ||
return err | ||
} | ||
_, err = serv.readPacketHeader(session, 4) | ||
if err != nil { | ||
return err | ||
} | ||
_, err = session.GetInt(4, false, true) | ||
if err != nil { | ||
return err | ||
} | ||
_, err = serv.readPacketHeader(session, 4) | ||
if err != nil { | ||
return err | ||
} | ||
_, err = session.GetInt(4, false, true) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
serv.active = true | ||
} else { | ||
if status != 0xFBFF { | ||
return errors.New("advanced negotiation error: reading authentication service") | ||
} | ||
serv.active = false | ||
} | ||
return nil | ||
} | ||
|
||
func (serv *authService) getServiceDataLength() int { | ||
size := 20 | ||
for i := 0; i < len(serv.selectedIndices); i++ { | ||
index := serv.selectedIndices[i] | ||
size = size + 5 + (4 + len(serv.availableServiceNames[index])) | ||
} | ||
return size | ||
} |
Oops, something went wrong.