Browse Source

Merge pull request #1436 from hvenev-vmware/fix-ipsec

Fix ipsec
Manuel Buil 3 năm trước cách đây
mục cha
commit
0da79c271c

+ 9 - 8
backend/ipsec/handle_charon.go

@@ -156,14 +156,15 @@ func (charon *CharonIKEDaemon) LoadConnection(localLease, remoteLease *subnet.Le
 
 	childConfMap := make(map[string]goStrongswanVici.ChildSAConf)
 	childSAConf := goStrongswanVici.ChildSAConf{
-		Local_ts:     []string{localLease.Subnet.String()},
-		Remote_ts:    []string{remoteLease.Subnet.String()},
-		ESPProposals: []string{charon.espProposal},
-		StartAction:  "start",
-		CloseAction:  "trap",
-		Mode:         "tunnel",
-		ReqID:        reqID,
-		//		RekeyTime:     rekeyTime,
+		Local_ts:      []string{localLease.Subnet.String()},
+		Remote_ts:     []string{remoteLease.Subnet.String()},
+		ESPProposals:  []string{charon.espProposal},
+		StartAction:   "start",
+		CloseAction:   "trap",
+		DpdAction:     "restart",
+		Mode:          "tunnel",
+		ReqID:         reqID,
+		RekeyTime:     "1h",
 		InstallPolicy: "no",
 	}
 

+ 1 - 1
go.mod

@@ -5,7 +5,7 @@ go 1.16
 require (
 	github.com/Microsoft/hcsshim v0.8.6
 	github.com/aws/aws-sdk-go v1.12.54
-	github.com/bronze1man/goStrongswanVici v0.0.0-20171013065002-4d72634a2f11
+	github.com/bronze1man/goStrongswanVici v0.0.0-20201105010758-936f38b697fd
 	github.com/containernetworking/plugins v0.8.6
 	github.com/coreos/etcd v3.1.11+incompatible
 	github.com/coreos/go-iptables v0.4.5

+ 3 - 2
go.sum

@@ -35,8 +35,8 @@ github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdko
 github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
 github.com/aws/aws-sdk-go v1.12.54 h1:k9PjZW5+9Y4IomO0w1Qsz93+RD6S2cTp5fD+hib6tcE=
 github.com/aws/aws-sdk-go v1.12.54/go.mod h1:ZRmQr0FajVIyZ4ZzBYKG5P3ZqPz9IHG41ZoMu1ADI3k=
-github.com/bronze1man/goStrongswanVici v0.0.0-20171013065002-4d72634a2f11 h1:BPqRtINHoFADOk8U+4CTZrbo3Oo2Ee2qpkpVXcdqhFk=
-github.com/bronze1man/goStrongswanVici v0.0.0-20171013065002-4d72634a2f11/go.mod h1:c+n7HXa5FxzR8GDsmu773UtbtrmKvMVerLVQeEbnzAE=
+github.com/bronze1man/goStrongswanVici v0.0.0-20201105010758-936f38b697fd h1:qn6a8rGrW+7p4ghypmYHZUKewXURuUDYxKqZxEoFjPc=
+github.com/bronze1man/goStrongswanVici v0.0.0-20201105010758-936f38b697fd/go.mod h1:fWUtBEPt2yjrr3WFhOqvajM8JSEU8bEeBcoeSCsKRpc=
 github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
@@ -203,6 +203,7 @@ github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzu
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=

+ 1 - 0
vendor/github.com/bronze1man/goStrongswanVici/.gitignore

@@ -0,0 +1 @@
+*.swp

+ 12 - 2
vendor/github.com/bronze1man/goStrongswanVici/.travis.yml

@@ -1,6 +1,16 @@
 language: go
+
+services:
+  - docker
+
 go:
- - release
+  - "1.11.x"
+
+before_script:
+  - docker-compose up -d strongswan
 
 script:
- - go test -v
+  - docker-compose run app go test -v ./...
+
+after_script:
+  - docker-compose down -v

+ 7 - 0
vendor/github.com/bronze1man/goStrongswanVici/Dockerfile

@@ -0,0 +1,7 @@
+# Docker image for building the Go app
+FROM golang:latest
+
+WORKDIR /app
+ADD . /app
+
+RUN GO111MODULE=on go mod download

+ 17 - 1
vendor/github.com/bronze1man/goStrongswanVici/README.md

@@ -31,6 +31,22 @@ a golang implement of strongswan vici plugin client.
 
 If you need some commands, but it is not here .you can implement yourself, and send a pull request to this project.
 
+### Testing
+
+To test the library's functionality, `docker-compose` is used to spin up strongswan in a separate Docker container.
+
+```bash
+$ docker-compose up -V
+Creating network "gostrongswanvici_default" with the default drive
+Creating volume "gostrongswanvici_charondata" with default driver
+Creating gostrongswanvici_strongswan_1 ... done
+Creating gostrongswanvici_go-test_1    ... done
+Attaching to gostrongswanvici_strongswan_1, gostrongswanvici_go-test_1
+...
+go-test_1     | ok      github.com/RenaultAI/goStrongswanVici   0.017s
+gostrongswanvici_go-test_1 exited with code 0
+```
+
 ### example
 ```go
 package main
@@ -134,7 +150,7 @@ func main(){
 			}
 	err = client.UnloadConn(unloadConnReq)
 	if err != nil {
-		panic(error)
+		panic(err)
 	}
 
 	// kill all conns in strongswan

+ 58 - 6
vendor/github.com/bronze1man/goStrongswanVici/clientConn.go

@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"io"
 	"net"
+	"sync"
 	"time"
 )
 
@@ -22,11 +23,16 @@ type ClientConn struct {
 	// ReadTimeout specifies a time limit for requests made
 	// by this client.
 	ReadTimeout time.Duration
+
+	lock sync.RWMutex
 }
 
 func (c *ClientConn) Close() error {
+	c.lock.Lock()
+	defer c.lock.Unlock()
 	close(c.responseChan)
 	c.lastError = io.ErrClosedPipe
+
 	return c.conn.Close()
 }
 
@@ -38,6 +44,7 @@ func NewClientConn(conn net.Conn) (client *ClientConn) {
 		ReadTimeout:   DefaultReadTimeout,
 	}
 	go client.readThread()
+
 	return client
 }
 
@@ -47,6 +54,7 @@ func NewClientConnFromDefaultSocket() (client *ClientConn, err error) {
 	if err != nil {
 		return
 	}
+
 	return NewClientConn(conn), nil
 }
 
@@ -58,16 +66,23 @@ func (c *ClientConn) Request(apiname string, request map[string]interface{}) (re
 	})
 	if err != nil {
 		fmt.Printf("error writing segment \n")
+
 		return
 	}
 
 	outMsg := c.readResponse()
-	if c.lastError != nil {
-		return nil, c.lastError
+	c.lock.RLock()
+	err = c.lastError
+	if err != nil {
+		c.lock.RUnlock()
+		return nil, err
 	}
+	c.lock.RUnlock()
+
 	if outMsg.typ != stCMD_RESPONSE {
 		return nil, fmt.Errorf("[%s] response error %d", apiname, outMsg.typ)
 	}
+
 	return outMsg.msg, nil
 }
 
@@ -77,16 +92,22 @@ func (c *ClientConn) readResponse() segment {
 		return outMsg
 	case <-time.After(c.ReadTimeout):
 		if c.lastError == nil {
+			c.lock.Lock()
 			c.lastError = fmt.Errorf("Timeout waiting for message response")
+			c.lock.Unlock()
 		}
+
 		return segment{}
 	}
 }
 
 func (c *ClientConn) RegisterEvent(name string, handler func(response map[string]interface{})) (err error) {
+	c.lock.Lock()
 	if c.eventHandlers[name] != nil {
+		c.lock.Unlock()
 		return fmt.Errorf("[event %s] register a event twice.", name)
 	}
+
 	c.eventHandlers[name] = handler
 	err = writeSegment(c.conn, segment{
 		typ:  stEVENT_REGISTER,
@@ -94,19 +115,31 @@ func (c *ClientConn) RegisterEvent(name string, handler func(response map[string
 	})
 	if err != nil {
 		delete(c.eventHandlers, name)
+		c.lock.Unlock()
+
 		return
 	}
+	c.lock.Unlock()
 	outMsg := c.readResponse()
-	//fmt.Printf("registerEvent %#v\n", outMsg)
-	if c.lastError != nil {
+	// fmt.Printf("registerEvent %#v\n", outMsg)
+	c.lock.Lock()
+	lastError := c.lastError
+
+	if lastError != nil {
 		delete(c.eventHandlers, name)
-		return c.lastError
+		c.lock.Unlock()
+
+		return err
 	}
 
 	if outMsg.typ != stEVENT_CONFIRM {
 		delete(c.eventHandlers, name)
+		c.lock.Unlock()
+
 		return fmt.Errorf("[event %s] response error %d", name, outMsg.typ)
 	}
+	c.lock.Unlock()
+
 	return nil
 }
 
@@ -118,16 +151,25 @@ func (c *ClientConn) UnregisterEvent(name string) (err error) {
 	if err != nil {
 		return
 	}
+
 	outMsg := c.readResponse()
-	//fmt.Printf("UnregisterEvent %#v\n", outMsg)
+	// fmt.Printf("UnregisterEvent %#v\n", outMsg)
+	c.lock.Lock()
 	if c.lastError != nil {
+		c.lock.Unlock()
+
 		return c.lastError
 	}
+	c.lock.Unlock()
 
 	if outMsg.typ != stEVENT_CONFIRM {
 		return fmt.Errorf("[event %s] response error %d", name, outMsg.typ)
 	}
+
+	c.lock.Lock()
 	delete(c.eventHandlers, name)
+	c.lock.Unlock()
+
 	return nil
 }
 
@@ -135,19 +177,29 @@ func (c *ClientConn) readThread() {
 	for {
 		outMsg, err := readSegment(c.conn)
 		if err != nil {
+			c.lock.Lock()
 			c.lastError = err
+			c.lock.Unlock()
+
 			return
 		}
+
 		switch outMsg.typ {
 		case stCMD_RESPONSE, stEVENT_CONFIRM:
 			c.responseChan <- outMsg
 		case stEVENT:
+			c.lock.Lock()
 			handler := c.eventHandlers[outMsg.name]
+			c.lock.Unlock()
+
 			if handler != nil {
 				handler(outMsg.msg)
 			}
 		default:
+			c.lock.Lock()
 			c.lastError = fmt.Errorf("[Client.readThread] unknow msg type %d", outMsg.typ)
+			c.lock.Unlock()
+
 			return
 		}
 	}

+ 22 - 0
vendor/github.com/bronze1man/goStrongswanVici/docker-compose.yaml

@@ -0,0 +1,22 @@
+version: '3.3'
+services:
+  strongswan:
+    image: philplckthun/strongswan
+    ports:
+      - "500:500/udp"
+      - "4500:4500/udp"
+      - "1701:1701/udp"
+    privileged: true
+    volumes:
+      - "charondata:/var/run"
+
+  app:
+    build: .
+    volumes:
+      - ".:/app"
+      - "charondata:/var/run"
+    depends_on:
+      - strongswan
+
+volumes:
+  charondata:

+ 7 - 0
vendor/github.com/bronze1man/goStrongswanVici/go.mod

@@ -0,0 +1,7 @@
+module github.com/bronze1man/goStrongswanVici
+
+require (
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/stretchr/testify v1.2.2
+)

+ 6 - 0
vendor/github.com/bronze1man/goStrongswanVici/go.sum

@@ -0,0 +1,6 @@
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=

+ 25 - 0
vendor/github.com/bronze1man/goStrongswanVici/initiate.go

@@ -0,0 +1,25 @@
+package goStrongswanVici
+
+import (
+	"fmt"
+)
+
+// Initiate is used to initiate an SA. This is the
+// equivalent of `swanctl --initiate -c childname`
+func (c *ClientConn) Initiate(child string, ike string) (err error) {
+	inMap := map[string]interface{}{}
+	if child != "" {
+		inMap["child"] = child
+	}
+	if ike != "" {
+		inMap["ike"] = ike
+	}
+	msg, err := c.Request("initiate", inMap)
+	if err != nil {
+		return err
+	}
+	if msg["success"] != "yes" {
+		return fmt.Errorf("unsuccessful Initiate: %v", msg["errmsg"])
+	}
+	return nil
+}

+ 2 - 0
vendor/github.com/bronze1man/goStrongswanVici/listSas.go

@@ -11,8 +11,10 @@ type IkeSa struct {
 	Version         string               `json:"version"`
 	State           string               `json:"state"` //had saw: ESTABLISHED
 	Local_host      string               `json:"local-host"`
+	Local_port      string               `json:"local-port"`
 	Local_id        string               `json:"local-id"`
 	Remote_host     string               `json:"remote-host"`
+	Remote_port     string               `json:"remote-port"`
 	Remote_id       string               `json:"remote-id"`
 	Remote_xauth_id string               `json:"remote-xauth-id"` //client username
 	Initiator       string               `json:"initiator"`

+ 1 - 1
vendor/github.com/bronze1man/goStrongswanVici/loadCert.go

@@ -30,7 +30,7 @@ func (c *ClientConn) LoadCertificate(s string, typ string, flag string) (err err
 	}
 
 	if msg["success"] != "yes" {
-		return fmt.Errorf("unsuccessful loadCert: %v", msg["success"])
+		return fmt.Errorf("unsuccessful loadCert: %v", msg["errmsg"])
 	}
 
 	return nil

+ 37 - 5
vendor/github.com/bronze1man/goStrongswanVici/loadConn.go

@@ -1,6 +1,9 @@
 package goStrongswanVici
 
 import (
+	"crypto"
+	"crypto/x509"
+	"encoding/pem"
 	"fmt"
 )
 
@@ -11,7 +14,10 @@ type Connection struct {
 type IKEConf struct {
 	LocalAddrs  []string               `json:"local_addrs"`
 	RemoteAddrs []string               `json:"remote_addrs,omitempty"`
+	LocalPort   string                 `json:"local_port,omitempty"`
+	RemotePort  string                 `json:"remote_port,omitempty"`
 	Proposals   []string               `json:"proposals,omitempty"`
+	Vips        []string               `json:"vips,omitempty"`
 	Version     string                 `json:"version"` //1 for ikev1, 0 for ikev1 & ikev2
 	Encap       string                 `json:"encap"`   //yes,no
 	KeyingTries string                 `json:"keyingtries"`
@@ -21,13 +27,15 @@ type IKEConf struct {
 	RemoteAuth  AuthConf               `json:"remote"`
 	Pools       []string               `json:"pools,omitempty"`
 	Children    map[string]ChildSAConf `json:"children"`
+	Mobike      string                 `json:"mobike,omitempty"`
 }
 
 type AuthConf struct {
-	ID         string `json:"id"`
-	Round      string `json:"round,omitempty"`
-	AuthMethod string `json:"auth"` // (psk|pubkey)
-	EAP_ID     string `json:"eap_id,omitempty"`
+	ID         string   `json:"id"`
+	Round      string   `json:"round,omitempty"`
+	AuthMethod string   `json:"auth"` // (psk|pubkey)
+	EAP_ID     string   `json:"eap_id,omitempty"`
+	PubKeys    []string `json:"pubkeys,omitempty"` // PEM encoded public keys
 }
 
 type ChildSAConf struct {
@@ -36,7 +44,7 @@ type ChildSAConf struct {
 	ESPProposals  []string `json:"esp_proposals,omitempty"` //aes128-sha1_modp1024
 	StartAction   string   `json:"start_action"`            //none,trap,start
 	CloseAction   string   `json:"close_action"`
-	ReqID         string   `json:"reqid"`
+	ReqID         string   `json:"reqid,omitempty"`
 	RekeyTime     string   `json:"rekey_time"`
 	ReplayWindow  string   `json:"replay_window,omitempty"`
 	Mode          string   `json:"mode"`
@@ -45,6 +53,30 @@ type ChildSAConf struct {
 	Priority      string   `json:"priority,omitempty"`
 	MarkIn        string   `json:"mark_in,omitempty"`
 	MarkOut       string   `json:"mark_out,omitempty"`
+	DpdAction     string   `json:"dpd_action,omitempty"`
+	LifeTime      string   `json:"life_time,omitempty"`
+}
+
+// SetPublicKeys is a helper method that converts Public Keys to x509 PKIX PEM format
+// Supported formats are those implemented by x509.MarshalPKIXPublicKey
+func (a *AuthConf) SetPublicKeys(keys []crypto.PublicKey) error {
+	var newKeys []string
+
+	for _, key := range keys {
+		asn1Bytes, err := x509.MarshalPKIXPublicKey(key)
+		if err != nil {
+			return fmt.Errorf("Error marshaling key: %v", err)
+		}
+		pemKey := pem.Block{
+			Type:  "PUBLIC KEY",
+			Bytes: asn1Bytes,
+		}
+		pemBytes := pem.EncodeToMemory(&pemKey)
+		newKeys = append(newKeys, string(pemBytes))
+	}
+
+	a.PubKeys = newKeys
+	return nil
 }
 
 func (c *ClientConn) LoadConn(conn *map[string]IKEConf) error {

+ 1 - 1
vendor/github.com/bronze1man/goStrongswanVici/loadPrivateKey.go

@@ -59,7 +59,7 @@ func (c *ClientConn) loadPrivateKey(typ, data string) (err error) {
 
 	msg, err := c.Request("load-key", *requestMap)
 	if msg["success"] != "yes" {
-		return fmt.Errorf("unsuccessful loadPrivateKey: %v", msg["success"])
+		return fmt.Errorf("unsuccessful loadPrivateKey: %v", msg["errmsg"])
 	}
 
 	return nil

+ 255 - 0
vendor/github.com/bronze1man/goStrongswanVici/monitorSA.go

@@ -0,0 +1,255 @@
+package goStrongswanVici
+
+import (
+	"bytes"
+	"encoding/json"
+	"time"
+)
+
+const (
+	EVENT_IKE_UPDOWN   = "ike-updown"
+	EVENT_IKE_REKEY    = "ike-rekey"
+	EVENT_CHILD_UPDOWN = "child-updown"
+	EVENT_CHILD_REKEY  = "child-rekey"
+)
+
+type EventIkeSAUpDown struct {
+	Child_sas     map[string]*EventChildSAUpDown `json:"child-sas"`
+	Dh_group      string                         `json:"dh-group"`
+	Encr_keysize  string                         `json:"encr-keysize"`
+	Encr_alg      string                         `json:"encr-alg"`
+	Established   string                         `json:"established"`
+	Initiator_spi string                         `json:"initiator-spi"`
+	Integ_alg     string                         `json:"integ-alg"`
+	Local_id      string                         `json:"local-id"`
+	Local_host    string                         `json:"local-host"`
+	Local_port    string                         `json:"local-port"`
+	Nat_any       string                         `json:"nat-any"`
+	Nat_remote    string                         `json:"nat-remote"`
+	Prf_alg       string                         `json:"prf-alg"`
+	Rekey_time    string                         `json:"rekey-time"`
+	Remote_id     string                         `json:"remote-id"`
+	Remote_host   string                         `json:"remote-host"`
+	Remote_port   string                         `json:"remote-port"`
+	Remote_vips   []string                       `json:"remote-vips"`
+	Responder_spi string                         `json:"responder-spi"`
+	State         string                         `json:"state"`
+	Task_Active   []string                       `json:"tasks-active"`
+	Uniqueid      string                         `json:"uniqueid"`
+	Version       string                         `json:"version"`
+	Remote_eap_id string                         `json:"remote-eap-id"` // client user name
+}
+
+type EventChildSAUpDown struct {
+	Bytes_in      string   `json:"bytes-in"`
+	Bytes_out     string   `json:"bytes-out"`
+	Encap         string   `json:"encap"`
+	Encr_alg      string   `json:"encr-alg"`
+	Encr_keysize  string   `json:"encr-keysize"`
+	Integ_alg     string   `json:"integ-alg"`
+	Install_time  string   `json:"install-time"`
+	Life_time     string   `json:"life-time"`
+	Local_ts      []string `json:"local-ts"`
+	Mode          string   `json:"mode"`
+	Name          string   `json:"name"`
+	Protocol      string   `json:"protocol"`
+	Packets_out   string   `json:"packets-out"`
+	Packets_in    string   `json:"packets-in"`
+	Rekey_time    string   `json:"rekey-time"`
+	Remote_ts     []string `json:"remote-ts"`
+	Reqid         string   `json:"reqid"`
+	Spi_in        string   `json:"spi-in"`
+	Spi_out       string   `json:"spi-out"`
+	State         string   `json:"state"`
+	UniqueId      string   `json:"uniqueid"`
+	Remote_eap_id string   `json:"remote-eap-id"` // client user name
+}
+
+type EventIkeRekeyPair struct {
+	New EventIkeRekeySA `json:"new"`
+	Old EventIkeRekeySA `json:"old"`
+}
+
+type EventIkeRekeySA struct {
+	Child_sas     map[string]*EventChildRekeyPair `json:"child-sas"`
+	Dh_group      string                          `json:"dh-group"`
+	Encr_alg      string                          `json:"encr-alg"`
+	Encr_keysize  string                          `json:"encr-keysize"`
+	Established   string                          `json:"established"`
+	Initiator_spi string                          `json:"initiator-spi"`
+	Integ_alg     string                          `json:"integ-alg"`
+	Local_host    string                          `json:"local-host"`
+	Local_port    string                          `json:"local-port"`
+	Local_id      string                          `json:"local-id"`
+	Nat_any       string                          `json:"nat-any"`
+	Nat_remote    string                          `json:"nat-remote"`
+	Prf_alg       string                          `json:"prf-alg"`
+	Rekey_time    string                          `json:"rekey-time"`
+	Remote_id     string                          `json:"remote-id"`
+	Remote_host   string                          `json:"remote-host"`
+	Remote_port   string                          `json:"remote-port"`
+	Remote_vips   []string                        `json:"remote-vips"`
+	Responder_spi string                          `json:"responder-spi"`
+	State         string                          `json:"state"`
+	Task_Active   []string                        `json:"tasks-active"`
+	Task_Passive  []string                        `json:"tasks-passive"`
+	Uniqueid      string                          `json:"uniqueid"`
+	Version       string                          `json:"version"`
+	Remote_eap_id string                          `json:"remote-eap-id"` // client user name
+}
+
+type EventChildRekeyPair struct {
+	New EventChildRekeySA `json:"new"`
+	Old EventChildRekeySA `json:"old"`
+}
+
+type EventChildRekeySA struct {
+	Bytes_in     string   `json:"bytes-in"`
+	Bytes_out    string   `json:"bytes-out"`
+	Encap        string   `json:"encap"`
+	Encr_alg     string   `json:"encr-alg"`
+	Encr_keysize string   `json:"encr-keysize"`
+	Integ_alg    string   `json:"integ-alg"`
+	Install_time string   `json:"install-time"`
+	Life_time    string   `json:"life-time"`
+	Local_ts     []string `json:"local-ts"`
+	Mode         string   `json:"mode"`
+	Name         string   `json:"name"`
+	Packets_in   string   `json:"packets-in"`
+	Packets_out  string   `json:"packets-out"`
+	Protocol     string   `json:"protocol"`
+	Remote_ts    []string `json:"remote-ts"`
+	Rekey_time   string   `json:"rekey-time"`
+	Reqid        string   `json:"reqid"`
+	Spi_in       string   `json:"spi-in"`
+	Spi_out      string   `json:"spi-out"`
+	State        string   `json:"state"`
+	Use_in       string   `json:"use-in"`
+	Use_out      string   `json:"use-out"`
+	UniqueId     string   `json:"uniqueid"`
+}
+
+type EventIkeUpDown struct {
+	Up  bool
+	Ike map[string]*EventIkeSAUpDown
+}
+
+type EventIkeRekey struct {
+	Ike map[string]*EventIkeRekeyPair
+}
+
+type EventChildRekey struct {
+	Ike map[string]*EventIkeRekeySA
+}
+
+type EventChildUpDown struct {
+	Up  bool
+	Ike map[string]*EventIkeSAUpDown
+}
+
+type EventIkeSa struct {
+	IkeSa
+	TasksActive []string `json:"tasks-active"`
+}
+
+type EventInfo struct {
+	Up  bool
+	Ike map[string]*EventIkeSa
+}
+
+func prettyprint(b []byte) string {
+	var out bytes.Buffer
+	json.Indent(&out, b, "", "  ")
+	return string(out.Bytes())
+}
+
+type monitorCallBack func(event string, info interface{})
+
+func handleIkeUpDown(eventName string, callback monitorCallBack, response map[string]interface{}) {
+	event := &EventIkeUpDown{}
+	event.Ike = map[string]*EventIkeSAUpDown{}
+	//we need to marshall all ikes manual because json uses connections names as key
+	for name := range response {
+		value := response[name]
+		if name == "up" {
+			event.Up = true
+		} else {
+			sa := &EventIkeSAUpDown{}
+			ConvertFromGeneral(value, sa)
+			event.Ike[name] = sa
+		}
+	}
+	callback(eventName, event)
+}
+
+func handleIkeRekey(eventName string, callback monitorCallBack, response map[string]interface{}) {
+	event := &EventIkeRekey{}
+	event.Ike = map[string]*EventIkeRekeyPair{}
+	//we need to marshall all ikes manual because json uses connections names as key
+	for name := range response {
+		value := response[name]
+		sa := &EventIkeRekeyPair{}
+		ConvertFromGeneral(value, sa)
+		event.Ike[name] = sa
+	}
+	callback(eventName, event)
+}
+
+func handleChildUpDown(eventName string, callback monitorCallBack, response map[string]interface{}) {
+	event := &EventChildUpDown{}
+	event.Ike = map[string]*EventIkeSAUpDown{}
+	//we need to marshall all ikes manual because json uses connections names as key
+	for name := range response {
+		value := response[name]
+		if name == "up" {
+			event.Up = true
+		} else {
+			sa := &EventIkeSAUpDown{}
+			ConvertFromGeneral(value, sa)
+			event.Ike[name] = sa
+		}
+	}
+	callback(eventName, event)
+}
+
+func handleChildRekey(eventName string, callback monitorCallBack, response map[string]interface{}) {
+	event := &EventChildRekey{}
+	event.Ike = map[string]*EventIkeRekeySA{}
+	//we need to marshall all ikes manual because json uses connections names as key
+	for name := range response {
+		value := response[name]
+		sa := &EventIkeRekeySA{}
+		ConvertFromGeneral(value, sa)
+		event.Ike[name] = sa
+	}
+	callback(eventName, event)
+}
+
+func (c *ClientConn) MonitorSA(callback monitorCallBack, watchdog time.Duration) (err error) {
+	//register event
+	c.RegisterEvent(EVENT_CHILD_UPDOWN, func(response map[string]interface{}) {
+		//dumpResponse(response)
+		handleChildUpDown(EVENT_CHILD_UPDOWN, callback, response)
+	})
+	c.RegisterEvent(EVENT_CHILD_REKEY, func(response map[string]interface{}) {
+		//dumpResponse(response)
+		handleChildRekey(EVENT_CHILD_REKEY, callback, response)
+	})
+	c.RegisterEvent(EVENT_IKE_UPDOWN, func(response map[string]interface{}) {
+		//dumpResponse(response)
+		handleIkeUpDown(EVENT_IKE_UPDOWN, callback, response)
+	})
+	c.RegisterEvent(EVENT_IKE_REKEY, func(response map[string]interface{}) {
+		//dumpResponse(response)
+		handleIkeRekey(EVENT_IKE_REKEY, callback, response)
+	})
+
+	for {
+		time.Sleep(watchdog)
+		//collect some daemon stats to see if connection is alive
+		if _, err := c.Stats(); err != nil {
+			return err
+		}
+	}
+	return nil
+}

+ 1 - 1
vendor/github.com/bronze1man/goStrongswanVici/pools.go

@@ -29,7 +29,7 @@ func (c *ClientConn) LoadPool(ph Pool) error {
 	msg, err := c.Request("load-pool", requestMap)
 
 	if msg["success"] != "yes" {
-		return fmt.Errorf("unsuccessful LoadPool: %v", msg["success"])
+		return fmt.Errorf("unsuccessful LoadPool: %v", msg["errmsg"])
 	}
 
 	return nil

+ 1 - 0
vendor/github.com/bronze1man/goStrongswanVici/terminate.go

@@ -9,6 +9,7 @@ type TerminateRequest struct {
 	Ike      string `json:"ike,omitempty"`
 	Child_id string `json:"child-id,omitempty"`
 	Ike_id   string `json:"ike-id,omitempty"`
+	Force    string `json:"force,omitempty"`
 	Timeout  string `json:"timeout,omitempty"`
 	Loglevel string `json:"loglevel,omitempty"`
 }

+ 1 - 3
vendor/modules.txt

@@ -50,7 +50,7 @@ github.com/aws/aws-sdk-go/private/protocol/rest
 github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil
 github.com/aws/aws-sdk-go/service/ec2
 github.com/aws/aws-sdk-go/service/sts
-# github.com/bronze1man/goStrongswanVici v0.0.0-20171013065002-4d72634a2f11
+# github.com/bronze1man/goStrongswanVici v0.0.0-20201105010758-936f38b697fd
 ## explicit
 github.com/bronze1man/goStrongswanVici
 # github.com/containernetworking/plugins v0.8.6
@@ -91,8 +91,6 @@ github.com/go-logr/logr
 # github.com/gogo/protobuf v1.3.1
 github.com/gogo/protobuf/proto
 github.com/gogo/protobuf/sortkeys
-# github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
-## explicit
 # github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7
 github.com/golang/groupcache/lru
 # github.com/golang/protobuf v1.4.2