Added connection timestamps to firewall prompting.

Disabled old synchronous RequestPrompt Dbus method in fw-prompt.
fw-prompt GUI now (as originally) remains above other windows when there are pending decisions.
Fixed improper traversal of pending connections in fw-prompt GUI.
Consolidated redundant code blocks in fw-prompt GUI.
shw_dev
Stephen Watt 7 years ago
parent 0bda150abc
commit ff8be65566

@ -1,5 +1,5 @@
fw-daemon:
pc.socks() an getOptString() return overlapping information
pc.socks() and getOptString() return overlapping information
remove all stale references to SANDBOX: rules/policyForPathAndSandbox()
@ -7,13 +7,6 @@ fw-daemon:
fw-prompt:
scope returned by new rules is bad (always set to process)
prompter should have a timestamp field
Iteration through fw-prompt choices can't brute force by index #
This function needs to be updated because it no longer works:
func toggleHover() { mainWin.SetKeepAbove(len(decisionWaiters) > 0) }
Each duplicate prompt needs to be expandable into individual items

@ -52,10 +52,10 @@ func newDbusServer() (*dbusServer, error) {
return ds, nil
}
func (ds *dbusServer) RequestPrompt(guid, application, icon, path, address string, port int32, ip, origin, proto string, uid, gid int32, username, groupname string, pid int32, sandbox string,
is_socks bool, optstring string, expanded, expert bool, action int32) (int32, string, *dbus.Error) {
/*func (ds *dbusServer) RequestPrompt(guid, application, icon, path, address string, port int32, ip, origin, proto string, uid, gid int32, username, groupname string, pid int32, sandbox string,
is_socks bool, timestamp string, optstring string, expanded, expert bool, action int32) (int32, string, *dbus.Error) {
log.Printf("request prompt: app = %s, icon = %s, path = %s, address = %s / ip = %s, is_socks = %v, action = %v\n", application, icon, path, address, ip, is_socks, action)
decision := addRequest(nil, guid, path, icon, proto, int(pid), ip, address, int(port), int(uid), int(gid), origin, is_socks, optstring, sandbox, int(action))
decision := addRequest(nil, guid, path, icon, proto, int(pid), ip, address, int(port), int(uid), int(gid), origin, timestamp, is_socks, optstring, sandbox, int(action))
log.Print("Waiting on decision...")
decision.Cond.L.Lock()
for !decision.Ready {
@ -64,12 +64,12 @@ func (ds *dbusServer) RequestPrompt(guid, application, icon, path, address strin
log.Print("Decision returned: ", decision.Rule)
decision.Cond.L.Unlock()
return int32(decision.Scope), decision.Rule, nil
}
}*/
func (ds *dbusServer) RequestPromptAsync(guid, application, icon, path, address string, port int32, ip, origin, proto string, uid, gid int32, username, groupname string, pid int32, sandbox string,
is_socks bool, optstring string, expanded, expert bool, action int32) (bool, *dbus.Error) {
is_socks bool, timestamp string, optstring string, expanded, expert bool, action int32) (bool, *dbus.Error) {
log.Printf("ASYNC request prompt: guid = %s, app = %s, icon = %s, path = %s, address = %s / ip = %s, is_socks = %v, action = %v\n", guid, application, icon, path, address, ip, is_socks, action)
addRequestAsync(nil, guid, path, icon, proto, int(pid), ip, address, int(port), int(uid), int(gid), origin, is_socks, optstring, sandbox, int(action))
addRequestAsync(nil, guid, path, icon, proto, int(pid), ip, address, int(port), int(uid), int(gid), origin, timestamp, is_socks, optstring, sandbox, int(action))
return true, nil
}

@ -34,23 +34,24 @@ type decisionWaiter struct {
}
type ruleColumns struct {
nrefs int
Path string
GUID string
Icon string
Proto string
Pid int
Target string
Hostname string
Port int
UID int
GID int
Uname string
Gname string
Origin string
IsSocks bool
ForceTLS bool
Scope int
nrefs int
Path string
GUID string
Icon string
Proto string
Pid int
Target string
Hostname string
Port int
UID int
GID int
Uname string
Gname string
Origin string
Timestamp string
IsSocks bool
ForceTLS bool
Scope int
}
var dbuso *dbusObject
@ -70,6 +71,7 @@ var btnApprove, btnDeny, btnIgnore *gtk.Button
var chkTLS, chkUser, chkGroup *gtk.CheckButton
func dumpDecisions() {
return
fmt.Println("XXX Total of decisions pending: ", len(decisionWaiters))
for i := 0; i < len(decisionWaiters); i++ {
fmt.Printf("XXX %d ready = %v, rule = %v\n", i+1, decisionWaiters[i].Ready, decisionWaiters[i].Rule)
@ -77,6 +79,7 @@ func dumpDecisions() {
}
func addDecision() *decisionWaiter {
return nil
decision := decisionWaiter{Lock: &sync.Mutex{}, Ready: false, Scope: int(sgfw.APPLY_ONCE), Rule: ""}
decision.Cond = sync.NewCond(decision.Lock)
decisionWaiters = append(decisionWaiters, &decision)
@ -315,7 +318,7 @@ func createColumn(title string, id int) *gtk.TreeViewColumn {
func createListStore(general bool) *gtk.ListStore {
colData := []glib.Type{glib.TYPE_INT, glib.TYPE_STRING, glib.TYPE_STRING, glib.TYPE_STRING, glib.TYPE_STRING, glib.TYPE_INT, glib.TYPE_STRING,
glib.TYPE_STRING, glib.TYPE_INT, glib.TYPE_INT, glib.TYPE_INT, glib.TYPE_STRING, glib.TYPE_INT, glib.TYPE_STRING, glib.TYPE_INT}
glib.TYPE_STRING, glib.TYPE_INT, glib.TYPE_INT, glib.TYPE_INT, glib.TYPE_STRING, glib.TYPE_STRING, glib.TYPE_INT, glib.TYPE_STRING, glib.TYPE_INT}
listStore, err := gtk.ListStoreNew(colData...)
if err != nil {
@ -331,7 +334,7 @@ func removeRequest(listStore *gtk.ListStore, guid string) {
defer globalPromptLock.Unlock()
/* XXX: This is horrible. Figure out how to do this properly. */
for ridx := 0; ridx < 2000; ridx++ {
for ridx := 0; ridx < globalLS.IterNChildren(nil); ridx++ {
rule, _, err := getRuleByIdx(ridx)
if err != nil {
@ -357,7 +360,7 @@ func addRequestInc(listStore *gtk.ListStore, guid, path, icon, proto string, pid
globalPromptLock.Lock()
defer globalPromptLock.Unlock()
for ridx := 0; ridx < 2000; ridx++ {
for ridx := 0; ridx < globalLS.IterNChildren(nil); ridx++ {
/* XXX: This is horrible. Figure out how to do this properly. */
rule, iter, err := getRuleByIdx(ridx)
@ -385,98 +388,14 @@ func addRequestInc(listStore *gtk.ListStore, guid, path, icon, proto string, pid
}
func addRequestAsync(listStore *gtk.ListStore, guid, path, icon, proto string, pid int, ipaddr, hostname string, port, uid, gid int,
origin string, is_socks bool, optstring string, sandbox string, action int) bool {
if listStore == nil {
listStore = globalLS
waitTimes := []int{1, 2, 5, 10}
if listStore == nil {
log.Println("SGFW prompter was not ready to receive firewall request... waiting")
for _, wtime := range waitTimes {
time.Sleep(time.Duration(wtime) * time.Second)
listStore = globalLS
if listStore != nil {
break
}
log.Println("SGFW prompter is still waiting...")
}
}
}
if listStore == nil {
log.Fatal("SGFW prompter GUI failed to load for unknown reasons")
}
if addRequestInc(listStore, guid, path, icon, proto, pid, ipaddr, hostname, port, uid, gid, origin, is_socks, optstring, sandbox, action) {
fmt.Println("REQUEST WAS DUPLICATE")
return false
} else {
fmt.Println("NOT DUPLICATE")
}
globalPromptLock.Lock()
iter := listStore.Append()
if is_socks {
if (optstring != "") && (strings.Index(optstring, "SOCKS") == -1) {
optstring = "SOCKS5 / " + optstring
} else if optstring == "" {
optstring = "SOCKS5"
}
}
colVals := make([]interface{}, 15)
colVals[0] = 1
colVals[1] = guid
colVals[2] = path
colVals[3] = icon
colVals[4] = proto
colVals[5] = pid
if ipaddr == "" {
colVals[6] = "---"
} else {
colVals[6] = ipaddr
}
colVals[7] = hostname
colVals[8] = port
colVals[9] = uid
colVals[10] = gid
colVals[11] = origin
colVals[12] = 0
if is_socks {
colVals[12] = 1
}
colVals[13] = optstring
colVals[14] = action
colNums := make([]int, len(colVals))
for n := 0; n < len(colVals); n++ {
colNums[n] = n
}
err := listStore.Set(iter, colNums, colVals)
globalPromptLock.Unlock()
if err != nil {
log.Fatal("Unable to add row:", err)
}
toggleHover()
origin, timestamp string, is_socks bool, optstring string, sandbox string, action int) bool {
addRequest(listStore, guid, path, icon, proto, pid, ipaddr, hostname, port, uid, gid, origin, timestamp, is_socks,
optstring, sandbox, action)
return true
}
func addRequest(listStore *gtk.ListStore, guid, path, icon, proto string, pid int, ipaddr, hostname string, port, uid, gid int,
origin string, is_socks bool, optstring string, sandbox string, action int) *decisionWaiter {
origin, timestamp string, is_socks bool, optstring string, sandbox string, action int) *decisionWaiter {
if listStore == nil {
listStore = globalLS
waitTimes := []int{1, 2, 5, 10}
@ -506,7 +425,9 @@ func addRequest(listStore *gtk.ListStore, guid, path, icon, proto string, pid in
if addRequestInc(listStore, guid, path, icon, proto, pid, ipaddr, hostname, port, uid, gid, origin, is_socks, optstring, sandbox, action) {
fmt.Println("REQUEST WAS DUPLICATE")
decision := addDecision()
globalPromptLock.Lock()
toggleHover()
globalPromptLock.Unlock()
return decision
} else {
fmt.Println("NOT DUPLICATE")
@ -523,7 +444,7 @@ func addRequest(listStore *gtk.ListStore, guid, path, icon, proto string, pid in
}
}
colVals := make([]interface{}, 15)
colVals := make([]interface{}, 16)
colVals[0] = 1
colVals[1] = guid
colVals[2] = path
@ -542,14 +463,15 @@ func addRequest(listStore *gtk.ListStore, guid, path, icon, proto string, pid in
colVals[9] = uid
colVals[10] = gid
colVals[11] = origin
colVals[12] = 0
colVals[12] = timestamp
colVals[13] = 0
if is_socks {
colVals[12] = 1
colVals[13] = 1
}
colVals[13] = optstring
colVals[14] = action
colVals[14] = optstring
colVals[15] = action
colNums := make([]int, len(colVals))
@ -558,7 +480,6 @@ func addRequest(listStore *gtk.ListStore, guid, path, icon, proto string, pid in
}
err := listStore.Set(iter, colNums, colVals)
globalPromptLock.Unlock()
if err != nil {
log.Fatal("Unable to add row:", err)
@ -567,6 +488,7 @@ func addRequest(listStore *gtk.ListStore, guid, path, icon, proto string, pid in
decision := addDecision()
dumpDecisions()
toggleHover()
globalPromptLock.Unlock()
return decision
}
@ -682,14 +604,17 @@ func makeDecision(idx int, rule string, scope int) error {
return nil
}
/* Do we need to hold the lock while this is called? Stay safe... */
func toggleHover() {
mainWin.SetKeepAbove(len(decisionWaiters) > 0)
nitems := globalLS.IterNChildren(nil)
mainWin.SetKeepAbove(nitems > 0)
}
func toggleValidRuleState() {
ok := true
// Unfortunately, this can cause deadlock since it's a part ofi the item removal cascade
// Unfortunately, this can cause deadlock since it's a part of the item removal cascade
// globalPromptLock.Lock()
// defer globalPromptLock.Unlock()
@ -912,8 +837,13 @@ func getRuleByIdx(idx int) (ruleColumns, *gtk.TreeIter, error) {
return rule, nil, err
}
rule.Timestamp, err = lsGetStr(globalLS, iter, 12)
if err != nil {
return rule, nil, err
}
rule.IsSocks = false
is_socks, err := lsGetInt(globalLS, iter, 12)
is_socks, err := lsGetInt(globalLS, iter, 13)
if err != nil {
return rule, nil, err
}
@ -922,7 +852,7 @@ func getRuleByIdx(idx int) (ruleColumns, *gtk.TreeIter, error) {
rule.IsSocks = true
}
rule.Scope, err = lsGetInt(globalLS, iter, 14)
rule.Scope, err = lsGetInt(globalLS, iter, 15)
if err != nil {
return rule, nil, err
}
@ -965,7 +895,7 @@ func addPendingPrompts(rules []string) {
for _, rule := range rules {
fields := strings.Split(rule, "|")
if len(fields) != 18 {
if len(fields) != 19 {
log.Printf("Got saved prompt message with strange data: \"%s\"", rule)
continue
}
@ -1011,15 +941,16 @@ func addPendingPrompts(rules []string) {
continue
}
optstring := fields[16]
timestamp := fields[16]
optstring := fields[17]
action, err := strconv.Atoi(fields[17])
action, err := strconv.Atoi(fields[18])
if err != nil {
log.Println("Error converting action in pending prompt message to integer:", err)
continue
}
addRequestAsync(nil, guid, path, icon, proto, int(pid), ip, address, int(port), int(uid), int(gid), origin, is_socks, optstring, sandbox, action)
addRequestAsync(nil, guid, path, icon, proto, int(pid), ip, address, int(port), int(uid), int(gid), origin, timestamp, is_socks, optstring, sandbox, action)
}
}
@ -1255,14 +1186,15 @@ func main() {
tv.AppendColumn(createColumn("UID", 9))
tv.AppendColumn(createColumn("GID", 10))
tv.AppendColumn(createColumn("Origin", 11))
tv.AppendColumn(createColumn("Timestamp", 12))
scol := createColumn("Is SOCKS", 12)
scol := createColumn("Is SOCKS", 13)
scol.SetVisible(false)
tv.AppendColumn(scol)
tv.AppendColumn(createColumn("Details", 13))
tv.AppendColumn(createColumn("Details", 14))
acol := createColumn("Scope", 14)
acol := createColumn("Scope", 15)
acol.SetVisible(false)
tv.AppendColumn(acol)

@ -241,6 +241,7 @@ func (ds *dbusServer) GetPendingRequests(policy string) ([]string, *dbus.Error)
pstr += strconv.FormatInt(int64(pc.procInfo().Pid), 10) + "|"
pstr += pc.sandbox() + "|"
pstr += strconv.FormatBool(pc.socks()) + "|"
pstr += pc.getTimestamp() + "|"
pstr += pc.getOptString() + "|"
pstr += strconv.FormatUint(uint64(FirewallConfig.DefaultActionID), 10)
pending_data = append(pending_data, pstr)

@ -13,6 +13,7 @@ import (
"net"
"os"
"syscall"
"time"
"unsafe"
)
@ -53,6 +54,7 @@ type pendingConnection interface {
setPrompter(*prompter)
getPrompter() *prompter
getGUID() string
getTimestamp() string
print() string
}
@ -65,6 +67,7 @@ type pendingPkt struct {
prompting bool
prompter *prompter
guid string
timestamp time.Time
}
/* Not a *REAL* GUID */
@ -97,6 +100,10 @@ func (pp *pendingPkt) sandbox() string {
return pp.pinfo.Sandbox
}
func (pc *pendingPkt) getTimestamp() string {
return pc.timestamp.Format("15:04:05.00")
}
func (pp *pendingPkt) socks() bool {
return false
}
@ -281,13 +288,9 @@ func (fw *Firewall) policyForPath(path string) *Policy {
return fw.policyMap[path]
}
func (p *Policy) processPacket(pkt *nfqueue.NFQPacket, pinfo *procsnitch.Info, optstr string) {
func (p *Policy) processPacket(pkt *nfqueue.NFQPacket, timestamp time.Time, pinfo *procsnitch.Info, optstr string) {
fmt.Println("policy processPacket()")
/* hbytes, err := pkt.GetHWAddr()
if err != nil {
log.Notice("Failed to get HW address underlying packet: ", err)
} else { log.Notice("got hwaddr: ", hbytes) } */
p.lock.Lock()
defer p.lock.Unlock()
dstb := pkt.Packet.NetworkLayer().NetworkFlow().Dst().Raw()
@ -320,7 +323,7 @@ func (p *Policy) processPacket(pkt *nfqueue.NFQPacket, pinfo *procsnitch.Info, o
case FILTER_ALLOW:
pkt.Accept()
case FILTER_PROMPT:
p.processPromptResult(&pendingPkt{pol: p, name: name, pkt: pkt, pinfo: pinfo, optstring: optstr, prompter: nil, prompting: false})
p.processPromptResult(&pendingPkt{pol: p, name: name, pkt: pkt, pinfo: pinfo, optstring: optstr, prompter: nil, timestamp: timestamp, prompting: false})
default:
log.Warningf("Unexpected filter result: %d", result)
}
@ -499,7 +502,7 @@ func printPacket(pkt *nfqueue.NFQPacket, hostname string, pinfo *procsnitch.Info
return fmt.Sprintf("%s %s %s:%d -> %s:%d", pinfo.ExePath, proto, SrcIp, SrcPort, name, DstPort)
}
func (fw *Firewall) filterPacket(pkt *nfqueue.NFQPacket) {
func (fw *Firewall) filterPacket(pkt *nfqueue.NFQPacket, timestamp time.Time) {
fmt.Println("firewall: filterPacket()")
isudp := pkt.Packet.Layer(layers.LayerTypeUDP) != nil
@ -578,7 +581,7 @@ func (fw *Firewall) filterPacket(pkt *nfqueue.NFQPacket) {
*/
policy := fw.PolicyForPathAndSandbox(ppath, pinfo.Sandbox)
//log.Notice("XXX: flunked basicallowpacket; policy = ", policy)
policy.processPacket(pkt, pinfo, optstring)
policy.processPacket(pkt, timestamp, pinfo, optstring)
}
func readFileDirect(filename string) ([]byte, error) {

@ -248,6 +248,7 @@ func (p *prompter) processConnection(pc pendingConnection) {
int32(pc.procInfo().Pid),
pc.sandbox(),
pc.socks(),
pc.getTimestamp(),
pc.getOptString(),
FirewallConfig.PromptExpanded,
FirewallConfig.PromptExpert,

@ -1,16 +1,16 @@
package sgfw
import (
"bufio"
"encoding/json"
"fmt"
"os"
"os/signal"
"regexp"
"strings"
"sync"
"syscall"
// "time"
"bufio"
"encoding/json"
"fmt"
"strings"
"time"
"github.com/op/go-logging"
nfqueue "github.com/subgraph/go-nfnetlink/nfqueue"
@ -110,6 +110,8 @@ func (fw *Firewall) runFilter() {
go func() {
for p := range ps {
timestamp := time.Now()
if fw.isEnabled() {
ipLayer := p.Packet.Layer(layers.LayerTypeIPv4)
if ipLayer == nil {
@ -127,7 +129,7 @@ func (fw *Firewall) runFilter() {
}
fw.filterPacket(p)
fw.filterPacket(p, timestamp)
} else {
p.Accept()
}

@ -59,6 +59,7 @@ type pendingSocksConnection struct {
prompter *prompter
guid string
optstr string
timestamp time.Time
}
func (sc *pendingSocksConnection) sandbox() string {
@ -116,17 +117,31 @@ func (sc *pendingSocksConnection) deliverVerdict(v int) {
}
}
func (sc *pendingSocksConnection) accept() { sc.deliverVerdict(socksVerdictAccept) }
func (sc *pendingSocksConnection) accept() {
sc.deliverVerdict(socksVerdictAccept)
}
// need to generalize special accept
func (sc *pendingSocksConnection) acceptTLSOnly() { sc.deliverVerdict(socksVerdictAcceptTLSOnly) }
func (sc *pendingSocksConnection) acceptTLSOnly() {
sc.deliverVerdict(socksVerdictAcceptTLSOnly)
}
func (sc *pendingSocksConnection) drop() { sc.deliverVerdict(socksVerdictDrop) }
func (sc *pendingSocksConnection) drop() {
sc.deliverVerdict(socksVerdictDrop)
}
func (sc *pendingSocksConnection) setPrompter(val *prompter) {
sc.prompter = val
}
func (sc *pendingSocksConnection) setPrompter(val *prompter) { sc.prompter = val }
func (sc *pendingSocksConnection) getPrompter() *prompter {
return sc.prompter
}
func (sc *pendingSocksConnection) getPrompter() *prompter { return sc.prompter }
func (sc *pendingSocksConnection) getTimestamp() string {
return sc.timestamp.Format("15:04:05.00")
}
func (sc *pendingSocksConnection) getGUID() string {
if sc.guid == "" {
@ -136,11 +151,17 @@ func (sc *pendingSocksConnection) getGUID() string {
return sc.guid
}
func (sc *pendingSocksConnection) getPrompting() bool { return sc.prompting }
func (sc *pendingSocksConnection) getPrompting() bool {
return sc.prompting
}
func (sc *pendingSocksConnection) setPrompting(val bool) { sc.prompting = val }
func (sc *pendingSocksConnection) setPrompting(val bool) {
sc.prompting = val
}
func (sc *pendingSocksConnection) print() string { return "socks connection" }
func (sc *pendingSocksConnection) print() string {
return "socks connection"
}
func NewSocksChain(cfg *socksChainConfig, wg *sync.WaitGroup, fw *Firewall) *socksChain {
chain := socksChain{
@ -163,10 +184,11 @@ func (s *socksChain) start() {
}
s.wg.Add(1)
go s.socksAcceptLoop()
ts := time.Now()
go s.socksAcceptLoop(ts)
}
func (s *socksChain) socksAcceptLoop() error {
func (s *socksChain) socksAcceptLoop(timestamp time.Time) error {
defer s.wg.Done()
defer s.listener.Close()
@ -180,11 +202,11 @@ func (s *socksChain) socksAcceptLoop() error {
continue
}
session := &socksChainSession{cfg: s.cfg, clientConn: conn, procInfo: s.procInfo, server: s}
go session.sessionWorker()
go session.sessionWorker(timestamp)
}
}
func (c *socksChainSession) sessionWorker() {
func (c *socksChainSession) sessionWorker(timestamp time.Time) {
defer c.clientConn.Close()
clientAddr := c.clientConn.RemoteAddr()
@ -214,7 +236,7 @@ func (c *socksChainSession) sessionWorker() {
c.req.ReplyAddr(ReplySucceeded, c.bndAddr)
}
case CommandConnect:
verdict, tls := c.filterConnect()
verdict, tls := c.filterConnect(timestamp)
if !verdict {
c.req.Reply(ReplyConnectionRefused)
@ -295,7 +317,7 @@ func findProxyEndpoint(pdata []string, conn net.Conn) (*procsnitch.Info, string)
return nil, ""
}
func (c *socksChainSession) filterConnect() (bool, bool) {
func (c *socksChainSession) filterConnect(timestamp time.Time) (bool, bool) {
// return filter verdict, tlsguard
allProxies, err := ListProxies()
@ -383,6 +405,7 @@ func (c *socksChainSession) filterConnect() (bool, bool) {
prompting: false,
prompter: nil,
optstr: optstr,
timestamp: timestamp,
}
policy.processPromptResult(pending)
v := <-pending.verdict

@ -2,6 +2,7 @@ package sgfw
import (
"crypto/x509"
"encoding/binary"
"errors"
"fmt"
"io"
@ -62,6 +63,20 @@ type connReader struct {
err error
}
var cipherSuiteMap map[uint16]string = map[uint16]string{
0x0000: "TLS_NULL_WITH_NULL_NULL",
0x0030: "TLS_DH_DSS_WITH_AES_128_CBC_SHA",
}
func getCipherSuiteName(value uint) string {
val, ok := cipherSuiteMap[uint16(value)]
if !ok {
return "UNKNOWN"
}
return val
}
func connectionReader(conn net.Conn, is_client bool, c chan connReader, done chan bool) {
var ret_error error = nil
buffered := []byte{}
@ -226,8 +241,8 @@ select_loop:
other.Write(cr.data)
continue
} else if cr.client {
other.Write(cr.data)
continue
// other.Write(cr.data)
// continue
} else if cr.rtype != SSL3_RT_HANDSHAKE {
return errors.New(fmt.Sprintf("Expected TLS server handshake byte was not received [%#x vs 0x16]", cr.rtype))
}
@ -236,8 +251,8 @@ select_loop:
return errors.New(fmt.Sprintf("TLSGuard dropping connection with unknown content type: %#x", cr.rtype))
}
serverMsg := cr.data[5:]
s := uint(serverMsg[0])
handshakeMsg := cr.data[5:]
s := uint(handshakeMsg[0])
fmt.Printf("s = %#x\n", s)
if cr.client && s != uint(client_expected) {
@ -246,6 +261,31 @@ select_loop:
return errors.New(fmt.Sprintf("Server sent handshake type %#x but expected %#x", s, server_expected))
}
if cr.client {
if s == SSL3_MT_CLIENT_HELLO {
fmt.Println("CLIENT HELLO")
hello_offset := 4
// 2 byte protocol version
fmt.Println("CLIENT HELLO VERSION = ", handshakeMsg[hello_offset:hello_offset+2])
hello_offset += 2
// 4 byte Random/GMT time
fmt.Println("CLIENT HELLO GMT = ", handshakeMsg[hello_offset:hello_offset+4])
hello_offset += 4
// 28 bytes Random/random_bytes
hello_offset += 28
// 1 byte (32-bit session ID)
fmt.Println("CLIENT HELLO SESSION ID = ", handshakeMsg[hello_offset:hello_offset+1])
hello_offset++
// 2 byte cipher suite array
cs := binary.BigEndian.Uint16(handshakeMsg[hello_offset : hello_offset+2])
fmt.Printf("cs = %v / %#v\n", cs, cs)
fmt.Printf("CLIENT HELLO CIPHERSUITE: %v (%s)\n", handshakeMsg[hello_offset:hello_offset+2], getCipherSuiteName(uint(cs)))
}
other.Write(cr.data)
continue
}
if !cr.client && s == SSL3_MT_HELLO_REQUEST {
fmt.Println("Server sent hello request")
continue
@ -256,16 +296,16 @@ select_loop:
}
// Message len, 3 bytes
serverMessageLen := serverMsg[1:4]
serverMessageLenInt := int(int(serverMessageLen[0])<<16 | int(serverMessageLen[1])<<8 | int(serverMessageLen[2]))
handshakeMessageLen := handshakeMsg[1:4]
handshakeMessageLenInt := int(int(handshakeMessageLen[0])<<16 | int(handshakeMessageLen[1])<<8 | int(handshakeMessageLen[2]))
if s == SSL3_MT_CERTIFICATE {
fmt.Println("HMM")
// fmt.Printf("chunk len = %v, serverMsgLen = %v, slint = %v\n", len(chunk), len(serverMsg), serverMessageLenInt)
if len(serverMsg) < serverMessageLenInt {
return errors.New(fmt.Sprintf("len(serverMsg) %v < serverMessageLenInt %v!\n", len(serverMsg), serverMessageLenInt))
// fmt.Printf("chunk len = %v, handshakeMsgLen = %v, slint = %v\n", len(chunk), len(handshakeMsg), handshakeMessageLenInt)
if len(handshakeMsg) < handshakeMessageLenInt {
return errors.New(fmt.Sprintf("len(handshakeMsg) %v < handshakeMessageLenInt %v!\n", len(handshakeMsg), handshakeMessageLenInt))
}
serverHelloBody := serverMsg[4 : 4+serverMessageLenInt]
serverHelloBody := handshakeMsg[4 : 4+handshakeMessageLenInt]
certChainLen := int(int(serverHelloBody[0])<<16 | int(serverHelloBody[1])<<8 | int(serverHelloBody[2]))
remaining := certChainLen
pos := serverHelloBody[3:certChainLen]

Loading…
Cancel
Save