-
Notifications
You must be signed in to change notification settings - Fork 1
/
integrated_auth.go
155 lines (131 loc) · 2.65 KB
/
integrated_auth.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package main
import (
"fmt"
"io"
"net"
"time"
)
type tdsSession struct {
buf *tdsBuffer
loginAck loginAckStruct
database string
partner string
tranid uint64
routedServer string
routedPort uint16
}
type Auth interface {
InitialBytes() ([]byte, error)
NextBytes([]byte) ([]byte, error)
Free()
}
func main(){
// connect()
}
//token.go
type loginAckStruct struct {
Interface uint8
TDSVersion uint32
ProgName string
ProgVer uint32
}
//end token.go
//buf.go
func newTdsBuffer(bufsize int, transport io.ReadWriteCloser) *tdsBuffer {
buf := make([]byte, bufsize)
w := new(tdsBuffer)
w.buf = buf
w.pos = 8
w.transport = transport
w.size = 0
return w
}
type tdsBuffer struct {
buf []byte
pos uint16
transport io.ReadWriteCloser
size uint16
final bool
packet_type uint8
afterFirst func()
}
//end buf.go
func dialConnection() (conn net.Conn, err error){
d := &net.Dialer{Timeout: 10000, KeepAlive: time.Hour}
addr := "http://localhost:8080/tfs"
conn, err = d.Dial("tcp", addr)
if err != nil {
f := "Unable to open tcp connection with host '%v': %v"
return nil, fmt.Errorf(f, addr, err.Error())
}
return conn, err
}
func connect() (res *tdsSession, err error) {
initiate_connection:
conn, err := dialConnection()
if err != nil {
return nil, err
}
toconn := NewTimeoutConn(conn, time.Hour)
outbuf := newTdsBuffer(4096, toconn)
sess := tdsSession{
buf: outbuf,
}
auth, auth_ok := getAuth("", "", "", "")
if auth_ok {
auth_sspi, err := auth.InitialBytes()
if err != nil {
return nil, err
}
defer auth.Free()
} else {
fmt.Println("auth_ok=false")
}
err = sendLogin(outbuf, login)
if err != nil {
return nil, err
}
// processing login response
var sspi_msg []byte
continue_login:
tokchan := make(chan tokenStruct, 5)
go processResponse(&sess, tokchan)
success := false
for tok := range tokchan {
switch token := tok.(type) {
case sspiMsg:
sspi_msg, err = auth.NextBytes(token)
if err != nil {
return nil, err
}
case loginAckStruct:
success = true
sess.loginAck = token
case error:
return nil, fmt.Errorf("Login error: %s", token.Error())
}
}
if sspi_msg != nil {
outbuf.BeginPacket(packSSPIMessage)
_, err = outbuf.Write(sspi_msg)
if err != nil {
return nil, err
}
err = outbuf.FinishPacket()
if err != nil {
return nil, err
}
sspi_msg = nil
goto continue_login
}
if !success {
return nil, fmt.Errorf("Login failed")
}
if sess.routedServer != "" {
toconn.Close()
p.host = sess.routedServer
p.port = uint64(sess.routedPort)
goto initiate_connection
}
return &sess, nil
}