Hello community,

here is the log from the commit of package cryptctl for openSUSE:Factory 
checked in at 2017-06-04 02:00:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cryptctl (Old)
 and      /work/SRC/openSUSE:Factory/.cryptctl.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "cryptctl"

Sun Jun  4 02:00:16 2017 rev:3 rq:500581 version:2.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/cryptctl/cryptctl.changes        2017-06-01 
16:33:01.736628681 +0200
+++ /work/SRC/openSUSE:Factory/.cryptctl.new/cryptctl.changes   2017-06-04 
02:00:23.083493983 +0200
@@ -1,0 +2,10 @@
+Thu Jun  1 13:00:57 UTC 2017 - h...@suse.com
+
+- Upgrade to upstream release 2.1 that brings important enhancements
+  in effort of implementing fate#322979:
+  * Improve KMIP compatibility with key prefix names and proper
+    serialisation of authentication header.
+  * Fail over KMIP connection using a server list.
+  * Destroy key on KMIP after its tracking record is erased from DB.
+
+-------------------------------------------------------------------

Old:
----
  cryptctl-2.0.tgz

New:
----
  cryptctl-2.1.tgz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ cryptctl.spec ++++++
--- /var/tmp/diff_new_pack.5YwnLh/_old  2017-06-04 02:00:23.551427935 +0200
+++ /var/tmp/diff_new_pack.5YwnLh/_new  2017-06-04 02:00:23.555427370 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           cryptctl
-Version:        2.0
+Version:        2.1
 Release:        0
 Summary:        A utility for setting up LUKS-based disk encryption
 License:        GPL-3.0

++++++ cryptctl-2.0.tgz -> cryptctl-2.1.tgz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/command/client.go new/command/client.go
--- old/command/client.go       2017-05-11 15:49:38.135920761 +0200
+++ new/command/client.go       2017-05-31 13:42:19.429519219 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package command
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/command/server.go new/command/server.go
--- old/command/server.go       2017-05-11 15:49:38.311921813 +0200
+++ new/command/server.go       2017-06-01 12:42:35.899886409 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package command
 
@@ -242,10 +242,9 @@
        // Walk through KMIP settings
        useExternalKMIPServer := sys.InputBool("Should encryption keys be kept 
on a KMIP-compatible key management appliance?")
        if useExternalKMIPServer {
-               sysconf.Set(keyserv.SRV_CONF_KMIP_SERVER_HOST, sys.Input(true, 
"", "KMIP server host name"))
-               sysconf.Set(keyserv.SRV_CONF_KMIP_SERVER_PORT, 
sys.InputInt(true, 5696, 1, 65535, "KMIP port number"))
+               sysconf.Set(keyserv.SRV_CONF_KMIP_SERVER_ADDRS, sys.Input(true, 
"", "Space-separated KMIP server addresses (host1:port1 host2:port2 ...)"))
                sysconf.Set(keyserv.SRV_CONF_KMIP_SERVER_USER, sys.Input(false, 
"", "KMIP username"))
-               sysconf.Set(keyserv.SRV_CONF_KMIP_SERVER_PASS, sys.Input(false, 
"", "KMIP password"))
+               sysconf.Set(keyserv.SRV_CONF_KMIP_SERVER_PASS, 
sys.InputPassword(false, "", "KMIP password"))
                sysconf.Set(keyserv.SRV_CONF_KMIP_SERVER_TLS_CA, 
sys.Input(false, "", "PEM-encoded TLS certificate authority that issued KMIP 
server certificate"))
                sysconf.Set(keyserv.SRV_CONF_KMIP_SERVER_TLS_CERT, 
sys.Input(false, "", "PEM-encoded TLS client identitiy certificate"))
                sysconf.Set(keyserv.SRV_CONF_KMIP_SERVER_TLS_KEY, 
sys.Input(false, "", "PEM-encoded TLS client identitiy certificate key"))
@@ -258,6 +257,16 @@
                sysconf.Set(keyserv.SRV_CONF_MAIL_AGENT_AND_PORT, mta)
        }
        if sysconf.GetString(keyserv.SRV_CONF_MAIL_AGENT_AND_PORT, "") != "" {
+               if username := sys.Input(false,
+                       sysconf.GetString(keyserv.SRV_CONF_MAIL_AGENT_USERNAME, 
""),
+                       "Plain authentication username for access to mail agent 
(optional)"); username != "" {
+                       sysconf.Set(keyserv.SRV_CONF_MAIL_AGENT_USERNAME, 
username)
+                       if password := sys.Input(false,
+                               
sysconf.GetString(keyserv.SRV_CONF_MAIL_AGENT_PASSWORD, ""),
+                               "Plain authentication password for access to 
mail agent (optional)"); password != "" {
+                               
sysconf.Set(keyserv.SRV_CONF_MAIL_AGENT_PASSWORD, password)
+                       }
+               }
                if fromAddr := sys.Input(false,
                        sysconf.GetString(keyserv.SRV_CONF_MAIL_FROM_ADDR, ""),
                        "Notification email's FROM address such as 
\"r...@example.com\""); fromAddr != "" {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fs/crypt.go new/fs/crypt.go
--- old/fs/crypt.go     2017-05-11 15:49:38.135920761 +0200
+++ new/fs/crypt.go     2017-05-31 13:42:19.465519425 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package fs
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fs/crypt_test.go new/fs/crypt_test.go
--- old/fs/crypt_test.go        2017-05-10 12:10:28.822405499 +0200
+++ new/fs/crypt_test.go        2017-05-31 13:42:19.485519541 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package fs
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fs/file.go new/fs/file.go
--- old/fs/file.go      2017-04-12 10:14:52.257214284 +0200
+++ new/fs/file.go      2017-05-31 13:42:19.441519289 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package fs
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fs/file_test.go new/fs/file_test.go
--- old/fs/file_test.go 2017-04-12 10:14:52.257214284 +0200
+++ new/fs/file_test.go 2017-05-31 13:42:19.401519058 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package fs
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fs/fs.go new/fs/fs.go
--- old/fs/fs.go        2017-04-12 10:14:52.257214284 +0200
+++ new/fs/fs.go        2017-05-31 13:42:19.417519150 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package fs
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fs/fs_test.go new/fs/fs_test.go
--- old/fs/fs_test.go   2017-04-12 10:14:52.257214284 +0200
+++ new/fs/fs_test.go   2017-05-31 13:42:19.453519356 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package fs
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fs/mnt.go new/fs/mnt.go
--- old/fs/mnt.go       2017-04-12 10:14:52.257214284 +0200
+++ new/fs/mnt.go       2017-05-31 13:42:24.253546901 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package fs
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/fs/mnt_test.go new/fs/mnt_test.go
--- old/fs/mnt_test.go  2017-04-12 10:14:52.257214284 +0200
+++ new/fs/mnt_test.go  2017-05-31 13:42:24.233546785 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package fs
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keydb/db.go new/keydb/db.go
--- old/keydb/db.go     2017-05-08 16:30:12.695463369 +0200
+++ new/keydb/db.go     2017-05-31 13:42:50.705698687 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package keydb
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keydb/db_test.go new/keydb/db_test.go
--- old/keydb/db_test.go        2017-05-09 11:56:13.655598444 +0200
+++ new/keydb/db_test.go        2017-05-31 13:42:50.713698733 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package keydb
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keydb/record.go new/keydb/record.go
--- old/keydb/record.go 2017-05-09 11:54:39.087076246 +0200
+++ new/keydb/record.go 2017-05-31 13:42:50.673698504 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package keydb
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keydb/record_test.go new/keydb/record_test.go
--- old/keydb/record_test.go    2017-05-10 11:53:31.925494009 +0200
+++ new/keydb/record_test.go    2017-05-31 13:42:50.685698572 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package keydb
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyserv/kmip_client.go new/keyserv/kmip_client.go
--- old/keyserv/kmip_client.go  2017-05-10 11:53:31.929494027 +0200
+++ new/keyserv/kmip_client.go  2017-06-01 14:52:47.172639453 +0200
@@ -1,3 +1,5 @@
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
+// This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package keyserv
 
 import (
@@ -12,6 +14,7 @@
        "io"
        "log"
        "reflect"
+       "time"
 )
 
 const (
@@ -22,6 +25,7 @@
        */
        MaxKMIPStructLen   = 65536
        KMIPAESKeySizeBits = 256 // The only kind of AES encryption key the 
KMIP server and client will expect to use
+       ClientMaxRetry     = 7   // Maximum number of times for client to retry 
failed KMIP connection.
 )
 
 /*
@@ -30,8 +34,7 @@
 KMIP servers implemented by other vendors.
 */
 type KMIPClient struct {
-       ServerHost         string
-       ServerPort         int
+       ServerAddrs        []string
        Username, Password string
        TLSConfig          *tls.Config
 }
@@ -40,13 +43,12 @@
 Initialise a KMIP client.
 The function does not immediately establish a connection to server.
 */
-func NewKMIPClient(host string, port int, username, password string, caCertPEM 
[]byte, certFilePath, certKeyPath string) (*KMIPClient, error) {
+func NewKMIPClient(addrs []string, username, password string, caCertPEM 
[]byte, certFilePath, certKeyPath string) (*KMIPClient, error) {
        client := &KMIPClient{
-               ServerHost: host,
-               ServerPort: port,
-               Username:   username,
-               Password:   password,
-               TLSConfig:  new(tls.Config),
+               ServerAddrs: addrs,
+               Username:    username,
+               Password:    password,
+               TLSConfig:   new(tls.Config),
        }
        if caCertPEM != nil && len(caCertPEM) > 0 {
                // Use custom CA
@@ -100,23 +102,49 @@
 
 /*
 Establish a TLS connection to server, send exactly one request and expect 
exactly one response, then close the connection.
-TLS handshake is way more expensive than KMIP operations, so consider using 
the connection for more requests in the future.
+Retry up to a certain number of times in case IO error occurs.
 */
-func (client *KMIPClient) MakeRequest(request structure.SerialisedItem) 
(structure.SerialisedItem, error) {
-       addr := fmt.Sprintf("%s:%d", client.ServerHost, client.ServerPort)
-       conn, err := tls.Dial("tcp", addr, client.TLSConfig)
-       if err != nil {
-               return nil, fmt.Errorf("KMIPClient.MakeRequest: connection to 
\"%s\" failed - %v", addr, err)
-       }
-       defer conn.Close()
+func (client *KMIPClient) ConverseWithRetry(request structure.SerialisedItem) 
(ttlv.Item, error) {
+       var err error
        serialisedRequest := request.SerialiseToTTLV()
        encodedRequest := ttlv.EncodeAny(serialisedRequest)
-       if _, err = conn.Write(encodedRequest); err != nil {
-               return nil, fmt.Errorf("KMIPClient.MakeRequest: failed to write 
request - %v", err)
+       for i := 0; i < ClientMaxRetry; i++ {
+               if i > 0 {
+                       // Introduce an artificial sleep to delay attempts 
after failure
+                       time.Sleep(1 * time.Second)
+               }
+               // Always prefer to use the first server among the list of 
servers
+               addr := client.ServerAddrs[i%len(client.ServerAddrs)]
+               conn, err := tls.Dial("tcp", addr, client.TLSConfig)
+               if err != nil {
+                       log.Printf("KMIPClient.ConverseWithRetry: IO failure 
occured with KMIP server %s", addr)
+                       continue
+               }
+               if _, err = conn.Write(encodedRequest); err != nil {
+                       log.Printf("KMIPClient.ConverseWithRetry: IO failure 
occured with KMIP server %s", addr)
+                       conn.Close()
+                       continue
+               }
+               ttlvResp, err := ReadFullTTLV(conn)
+               if err != nil {
+                       log.Printf("KMIPClient.ConverseWithRetry: IO failure 
occured with KMIP server %s", addr)
+                       conn.Close()
+                       continue
+               }
+               conn.Close()
+               return ttlvResp, nil
        }
-       ttlvResp, err := ReadFullTTLV(conn)
+       return nil, fmt.Errorf("KMIPClient.ConverseWithRetry: ultimately failed 
in all attempts at conversing with server - %v", err)
+}
+
+/*
+Establish a TLS connection to server, send exactly one request and expect 
exactly one response, then close the connection.
+TLS handshake is way more expensive than KMIP operations, so consider using 
the connection for more requests in the future.
+*/
+func (client *KMIPClient) MakeRequest(request structure.SerialisedItem) 
(structure.SerialisedItem, error) {
+       ttlvResp, err := client.ConverseWithRetry(request)
        if err != nil {
-               return nil, fmt.Errorf("KMIPClient.MakeRequest: failed to read 
response - %v", err)
+               return nil, err
        }
        // TODO: refactor this into interface function in all request structures
        var respItem structure.SerialisedItem
@@ -169,13 +197,11 @@
 func (client *KMIPClient) CreateKey(keyName string) (id string, err error) {
        defer func() {
                // In the unlikely case that a misbehaving server causes client 
to crash.
-               /*
-                       if r := recover(); r != nil {
-                               msg := fmt.Sprintf("KMIPClient.CreateKey: the 
function crashed due to programming error - %v", r)
-                               log.Print(msg)
-                               err = errors.New(msg)
-                       }
-               */
+               if r := recover(); r != nil {
+                       msg := fmt.Sprintf("KMIPClient.CreateKey: the function 
crashed due to programming error - %v", r)
+                       log.Print(msg)
+                       err = errors.New(msg)
+               }
        }()
        resp, err := client.MakeRequest(&structure.SCreateRequest{
                SRequestHeader: client.GetRequestHeader(),
@@ -270,7 +296,7 @@
        defer func() {
                // In the unlikely case that a misbehaving server causes client 
to crash.
                if r := recover(); r != nil {
-                       msg := fmt.Sprintf("KMIPClient.GetKey: (ID %s) the 
function crashed due to programming error - %v", id, r)
+                       msg := fmt.Sprintf("KMIPClient.DestroyKey: (ID %s) the 
function crashed due to programming error - %v", id, r)
                        log.Print(msg)
                        err = errors.New(msg)
                }
@@ -287,6 +313,5 @@
        if err != nil {
                return
        }
-       err = 
ResponseItemToError(resp.(*structure.SDestroyResponse).SResponseBatchItem)
-       return
+       return 
ResponseItemToError(resp.(*structure.SDestroyResponse).SResponseBatchItem)
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyserv/kmip_server.go new/keyserv/kmip_server.go
--- old/keyserv/kmip_server.go  2017-05-11 15:49:38.135920761 +0200
+++ new/keyserv/kmip_server.go  2017-05-31 13:42:56.253730524 +0200
@@ -1,3 +1,5 @@
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
+// This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package keyserv
 
 import (
@@ -13,6 +15,7 @@
        "log"
        "net"
        "reflect"
+       "strings"
        "time"
 )
 
@@ -181,6 +184,7 @@
        default:
                err = fmt.Errorf("KMIPServer.HandleRequest: unknown request 
type %s", reflect.TypeOf(req).String())
        }
+       log.Printf("KMIPServer.HandleRequest: handled request type %s from %s, 
err is %v", reflect.TypeOf(req).String(), conn.RemoteAddr().String(), err)
        if err == nil {
                conn.SetWriteDeadline(time.Now().Add(KMIPTimeoutSec * 
time.Second))
                _, err = conn.Write(ttlv.EncodeAny(resp.SerialiseToTTLV()))
@@ -202,7 +206,11 @@
        */
        creationTime := time.Now()
        kmipID, err := srv.DB.Upsert(keydb.Record{
-               UUID:         keyName,
+               /*
+                       Name prefix explains key's origin to make it more 
visible when stored in an external KMIP appliance.
+                       But key database only recognises UUID, there's no need 
for a prefix to be stored in key database.
+               */
+               UUID:         strings.TrimPrefix(keyName, KeyNamePrefix),
                CreationTime: creationTime,
                Key:          GetNewDiskEncryptionKeyBits(),
        })
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyserv/kmip_server_test.go 
new/keyserv/kmip_server_test.go
--- old/keyserv/kmip_server_test.go     2017-05-11 15:49:38.311921813 +0200
+++ new/keyserv/kmip_server_test.go     2017-05-31 13:42:59.933751639 +0200
@@ -1,3 +1,5 @@
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
+// This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package keyserv
 
 import (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyserv/kmip_test.go new/keyserv/kmip_test.go
--- old/keyserv/kmip_test.go    2017-05-10 11:53:31.933494045 +0200
+++ new/keyserv/kmip_test.go    2017-06-01 14:32:34.225304203 +0200
@@ -1,3 +1,5 @@
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
+// This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package keyserv
 
 import (
@@ -7,6 +9,7 @@
        "os"
        "path"
        "reflect"
+       "strconv"
        "testing"
        "time"
 )
@@ -41,7 +44,10 @@
        }
        // Expect server to start in a second
        time.Sleep(1 * time.Second)
-       client, err := NewKMIPClient("localhost", server.GetPort(), 
"username-does-not-matter", string(server.PasswordChallenge), caCert,
+       client, err := NewKMIPClient([]string{
+               "bad-server:1234",
+               "localhost:" + strconv.Itoa(server.GetPort()),
+       }, "username-does-not-matter", string(server.PasswordChallenge), caCert,
                path.Join(PkgInGopath, "keyserv", "rpc_test.crt"), 
path.Join(PkgInGopath, "keyserv", "rpc_test.key"))
        if err != nil {
                t.Fatal(err)
@@ -112,7 +118,54 @@
                time.sleep(100)
        */
        t.Skip("Start PyKMIP server manually and remove this skip statement to 
run this test case")
-       client, err := NewKMIPClient("127.0.0.1", 5696, "testuser", "testpass", 
nil, "/etc/pykmip/client.crt", "/etc/pykmip/client.key")
+       client, err := NewKMIPClient([]string{"127.0.0.1:5696"}, "testuser", 
"testpass", nil, "/etc/pykmip/kmipclient.com.crt", 
"/etc/pykmip/kmipclient.com.key")
+       if err != nil {
+               t.Fatal(err)
+       }
+       client.TLSConfig.InsecureSkipVerify = true
+       if err != nil {
+               t.Fatal(err)
+       }
+       // Create two keys
+       var id1, id2 string
+       if id1, err = client.CreateKey("test key 1"); err != nil || id1 == "" {
+               t.Fatal(err, id1)
+       }
+       if id2, err = client.CreateKey("test key 2"); err != nil || id2 == "" {
+               t.Fatal(err, id2)
+       }
+       // Retrieve both keys and non-existent key
+       received1, err := client.GetKey(id1)
+       if err != nil {
+               t.Fatal(err)
+       }
+       received2, err := client.GetKey(id2)
+       if err != nil {
+               t.Fatal(err)
+       }
+       if _, err := client.GetKey("does not exist"); err == nil {
+               t.Fatal("did not error")
+       }
+       if reflect.DeepEqual(received1, received2) || len(received1) == 0 {
+               t.Fatal(hex.Dump(received1), hex.Dump(received2))
+       }
+       if err := client.DestroyKey(id1); err != nil {
+               t.Fatal(err)
+       }
+       if err := client.DestroyKey(id2); err != nil {
+               t.Fatal(err)
+       }
+       if err := client.DestroyKey("does not exist"); err == nil {
+               t.Fatal("did not error")
+       }
+}
+
+func TestKMIPAgainstHpeEskm(t *testing.T) {
+       t.Skip("Acquire HPE ESKM credentials and remove this skip statement to 
run this test case")
+       client, err := NewKMIPClient([]string{"SERVER:5696"}, "USERNAME", 
"PASSWORD", nil, "PATH_TO_CRT", "PATH_TO_KEY")
+       if err != nil {
+               t.Fatal(err)
+       }
        client.TLSConfig.InsecureSkipVerify = true
        if err != nil {
                t.Fatal(err)
@@ -140,10 +193,12 @@
        if reflect.DeepEqual(received1, received2) || len(received1) == 0 {
                t.Fatal(hex.Dump(received1), hex.Dump(received2))
        }
-       // Destroy and retrieve again
        if err := client.DestroyKey(id1); err != nil {
                t.Fatal(err)
        }
+       if err := client.DestroyKey(id2); err != nil {
+               t.Fatal(err)
+       }
        if err := client.DestroyKey("does not exist"); err == nil {
                t.Fatal("did not error")
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyserv/mail.go new/keyserv/mail.go
--- old/keyserv/mail.go 2017-05-03 11:15:05.719097537 +0200
+++ new/keyserv/mail.go 2017-05-31 13:43:06.737790683 +0200
@@ -1,3 +1,5 @@
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
+// This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package keyserv
 
 import (
@@ -13,6 +15,8 @@
        SRV_CONF_MAIL_RECIPIENTS     = "EMAIL_RECIPIENTS"
        SRV_CONF_MAIL_FROM_ADDR      = "EMAIL_FROM_ADDRESS"
        SRV_CONF_MAIL_AGENT_AND_PORT = "EMAIL_AGENT_AND_PORT"
+       SRV_CONF_MAIL_AGENT_USERNAME = "EMAIL_AGENT_USERNAME"
+       SRV_CONF_MAIL_AGENT_PASSWORD = "EMAIL_AGENT_PASSWORD"
 )
 
 // Return true only if both at-sign and full-stop are in the string.
@@ -25,6 +29,8 @@
        Recipients       []string // List of Email addresses that receive 
notifications
        FromAddress      string   // FROM address of the notifications
        AgentAddressPort string   // Address and port number of mail 
transportation agent for sending notifications
+       AuthUsername     string   // (Optional) Username for plain 
authentication, if the SMTP server requires it.
+       AuthPassword     string   // (Optional) Password for plain 
authentication, if the SMTP server requires it.
 }
 
 // Return true only if all mail parameters are present.
@@ -65,11 +71,17 @@
 
 // Deliver an email to all recipients.
 func (mail *Mailer) Send(subject, text string) error {
-       msg := fmt.Sprintf("Subject: %s\r\n\r\n%s", subject, text)
-       if err := smtp.SendMail(mail.AgentAddressPort, nil, mail.FromAddress, 
mail.Recipients, []byte(msg)); err != nil {
-               return fmt.Errorf("Send: failed to send email to \"%v\" - %v", 
mail.Recipients, err)
+       if mail.Recipients == nil || len(mail.Recipients) == 0 {
+               return fmt.Errorf("No recipient specified for mail \"%s\"", 
subject)
+       }
+       var auth smtp.Auth
+       if mail.AuthUsername != "" {
+               auth = smtp.PlainAuth("", mail.AuthUsername, mail.AuthPassword, 
mail.AgentAddressPort)
        }
-       return nil
+       // Construct appropriate mail headers
+       mailBody := fmt.Sprintf("MIME-Version: 1.0\r\nContent-type: text/plain; 
charset=utf-8\r\nFrom: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s",
+               mail.FromAddress, strings.Join(mail.Recipients, ", "), subject, 
text)
+       return smtp.SendMail(mail.AgentAddressPort, auth, mail.FromAddress, 
mail.Recipients, []byte(mailBody))
 }
 
 // Read mail settings from keys in sysconfig file.
@@ -77,4 +89,6 @@
        mail.Recipients = sysconf.GetStringArray(SRV_CONF_MAIL_RECIPIENTS, 
[]string{})
        mail.FromAddress = sysconf.GetString(SRV_CONF_MAIL_FROM_ADDR, "")
        mail.AgentAddressPort = sysconf.GetString(SRV_CONF_MAIL_AGENT_AND_PORT, 
"")
+       mail.AuthUsername = sysconf.GetString(SRV_CONF_MAIL_AGENT_USERNAME, "")
+       mail.AuthPassword = sysconf.GetString(SRV_CONF_MAIL_AGENT_PASSWORD, "")
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyserv/mail_test.go new/keyserv/mail_test.go
--- old/keyserv/mail_test.go    2017-05-03 11:15:05.667097294 +0200
+++ new/keyserv/mail_test.go    2017-05-31 13:44:56.310419438 +0200
@@ -1,8 +1,9 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package keyserv
 
 import (
+       "net"
        "testing"
 )
 
@@ -42,6 +43,13 @@
        if err := m.Send("abc", "123"); err == nil {
                t.Fatal("did not error")
        }
+       if _, err := net.Dial("tcp", "localhost:25"); err != nil {
+               t.Skip("an MTA on localhost would be required to continue this 
test")
+       }
+       m = Mailer{Recipients: []string{"root@localhost"}, FromAddress: 
"root@localhost", AgentAddressPort: "localhost:25"}
+       if err := m.Send("cryptctl mailer test subject", "cryptctl mailer test 
text body"); err != nil {
+               t.Fatal(err)
+       }
 }
 
 func TestMailerReadFromSysconfig(t *testing.T) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyserv/rpc_client.go new/keyserv/rpc_client.go
--- old/keyserv/rpc_client.go   2017-05-11 15:49:38.311921813 +0200
+++ new/keyserv/rpc_client.go   2017-05-31 13:44:56.558420862 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package keyserv
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyserv/rpc_client_test.go 
new/keyserv/rpc_client_test.go
--- old/keyserv/rpc_client_test.go      2017-05-11 15:49:38.311921813 +0200
+++ new/keyserv/rpc_client_test.go      2017-05-31 13:44:56.526420678 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package keyserv
 
@@ -193,12 +193,13 @@
        }); err == nil {
                t.Fatal("did not error")
        }
+       // Erasing a non-existent key should not result in an error
        if err := client.EraseKey(EraseKeyReq{
                Password: HashPassword(salt, TEST_RPC_PASS),
                Hostname: "localhost",
                UUID:     "doesnotexist",
-       }); err == nil {
-               t.Fatal("did not error")
+       }); err != nil {
+               t.Fatal(err)
        }
        if err := client.EraseKey(EraseKeyReq{
                Password: HashPassword(salt, TEST_RPC_PASS),
@@ -207,12 +208,13 @@
        }); err != nil {
                t.Fatal(err)
        }
+       // Erasing a non-existent key should not result in an error
        if err := client.EraseKey(EraseKeyReq{
                Password: HashPassword(salt, TEST_RPC_PASS),
                Hostname: "localhost",
                UUID:     "aaa",
-       }); err == nil {
-               t.Fatal("did not error")
+       }); err != nil {
+               t.Fatal(err)
        }
        fmt.Println("About to run teardown")
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyserv/rpc_svc.go new/keyserv/rpc_svc.go
--- old/keyserv/rpc_svc.go      2017-05-11 15:49:38.311921813 +0200
+++ new/keyserv/rpc_svc.go      2017-06-01 12:41:26.439420140 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package keyserv
 
@@ -22,6 +22,7 @@
        "path"
        "path/filepath"
        "reflect"
+       "strconv"
        "strings"
        "time"
 )
@@ -45,13 +46,14 @@
        SRV_CONF_MAIL_RETRIEVAL_SUBJ = "EMAIL_KEY_RETRIEVAL_SUBJECT"
        SRV_CONF_MAIL_RETRIEVAL_TEXT = "EMAIL_KEY_RETRIEVAL_GREETING"
 
-       SRV_CONF_KMIP_SERVER_HOST     = "KMIP_SERVER_HOST"
-       SRV_CONF_KMIP_SERVER_PORT     = "KMIP_SERVER_PORT"
+       SRV_CONF_KMIP_SERVER_ADDRS    = "KMIP_SERVER_ADDRESSES"
        SRV_CONF_KMIP_SERVER_USER     = "KMIP_SERVER_USER"
        SRV_CONF_KMIP_SERVER_PASS     = "KMIP_SERVER_PASS"
        SRV_CONF_KMIP_SERVER_TLS_CA   = "KMIP_CA_PEM"
        SRV_CONF_KMIP_SERVER_TLS_CERT = "KMIP_TLS_CERT_PEM"
        SRV_CONF_KMIP_SERVER_TLS_KEY  = "KMIP_TLS_CERT_KEY_PEM"
+
+       KeyNamePrefix = "cryptctl-" // Prefix string prepended to KMIP keys
 )
 
 var PkgInGopath = path.Join(path.Join(os.Getenv("GOPATH"), 
"/src/github.com/HouzuoGuo/cryptctl")) // this package in gopath
@@ -101,8 +103,7 @@
        KeyCreationGreeting  string              // greeting of the 
notification email sent by key creation request
        KeyRetrievalSubject  string              // subject of the notification 
email sent by key retrieval request
        KeyRetrievalGreeting string              // greeting of the 
notification email sent by key retrieval request
-       KMIPHost             string              // optional KMIP server host
-       KMIPPort             int                 // optional KMIP server port
+       KMIPAddresses        []string            // optional KMIP server 
addresses (server1:port1 server2:port2 ...)
        KMIPUser             string              // optional KMIP service 
access user
        KMIPPass             string              // optional KMIP service 
access password
        KMIPCertAuthorityPEM string              // optional KMIP server CA 
certificate
@@ -153,8 +154,8 @@
        conf.KeyRetrievalSubject = 
sysconf.GetString(SRV_CONF_MAIL_RETRIEVAL_SUBJ, "An encrypted file system has 
been accessed")
        conf.KeyRetrievalGreeting = 
sysconf.GetString(SRV_CONF_MAIL_RETRIEVAL_TEXT, "The key server has sent the 
following encryption key to allow access to its file systems:")
 
-       conf.KMIPHost = sysconf.GetString(SRV_CONF_KMIP_SERVER_HOST, "")
-       conf.KMIPPort = sysconf.GetInt(SRV_CONF_KMIP_SERVER_PORT, 0)
+       conf.KMIPAddresses = sysconf.GetStringArray(SRV_CONF_KMIP_SERVER_ADDRS, 
[]string{})
+
        conf.KMIPUser = sysconf.GetString(SRV_CONF_KMIP_SERVER_USER, "")
        conf.KMIPPass = sysconf.GetString(SRV_CONF_KMIP_SERVER_PASS, "")
        conf.KMIPCertAuthorityPEM = 
sysconf.GetString(SRV_CONF_KMIP_SERVER_TLS_CA, "")
@@ -189,6 +190,9 @@
        if err != nil {
                return nil, err
        }
+       /*
+        The author of TLS related libraries in Go has an opinion about CRL
+       */
        srv.TLSConfig.Certificates = make([]tls.Certificate, 1)
        srv.TLSConfig.Certificates[0], err = 
tls.LoadX509KeyPair(config.CertPEM, config.KeyPEM)
        // Configure client authentication upon request
@@ -218,7 +222,7 @@
 */
 func (srv *CryptServer) ListenRPC() error {
        var err error
-       if srv.Config.KMIPHost == "" {
+       if len(srv.Config.KMIPAddresses) == 0 {
                // If RPC server settings do not have KMIP connectivity 
settings, start my own KMIP server.
                if srv.BuiltInKMIPServer, err = NewKMIPServer(srv.KeyDB, 
srv.Config.CertPEM, srv.Config.KeyPEM); err != nil {
                        return err
@@ -229,7 +233,7 @@
                go srv.BuiltInKMIPServer.HandleConnections()
                // The client initialisation routine does not immediately 
connect to server.
                if srv.KMIPClient, err = NewKMIPClient(
-                       "localhost", srv.BuiltInKMIPServer.GetPort(),
+                       []string{"localhost:" + 
strconv.Itoa(srv.BuiltInKMIPServer.GetPort())},
                        "does-not-matter", 
string(srv.BuiltInKMIPServer.PasswordChallenge),
                        nil, "", ""); err != nil {
                        return err
@@ -245,7 +249,7 @@
                        }
                }
                if srv.KMIPClient, err = NewKMIPClient(
-                       srv.Config.KMIPHost, srv.Config.KMIPPort,
+                       srv.Config.KMIPAddresses,
                        srv.Config.KMIPUser, srv.Config.KMIPPass,
                        caCert, srv.Config.KMIPCertPEM, srv.Config.KMIPKeyPEM); 
err != nil {
                        return err
@@ -395,8 +399,14 @@
        } else if err := req.Validate(); err != nil {
                return err
        }
-       // No matter key is located in built-in KMIP server or external KMIP 
server, the KMIP client needs to create the key.
-       kmipKeyID, err := rpcConn.Svc.KMIPClient.CreateKey(req.UUID)
+       /*
+               No matter key is located in built-in KMIP server or external 
KMIP server, the KMIP client needs to create the key.
+               But if the KMIP server is an external appliance, having the 
name prefix makes it more apparent where the key
+               originates.
+               If KMIP server is the built-in one, the server will remove the 
prefix string before storing record UUID in built-in key database.
+               But key database only recognises UUID, there's no need for a 
prefix to be stored in key database.
+       */
+       kmipKeyID, err := rpcConn.Svc.KMIPClient.CreateKey(KeyNamePrefix + 
req.UUID)
        if err != nil {
                return fmt.Errorf("CryptServiceConn.CreateKey: KMIP client 
refused to create the key - %v", err)
        }
@@ -605,7 +615,17 @@
        if err := rpcConn.Svc.ValidatePassword(req.Password); err != nil {
                return err
        }
-       return rpcConn.Svc.KeyDB.Erase(req.UUID)
+       rec, found := rpcConn.Svc.KeyDB.GetByUUID(req.UUID)
+       if !found {
+               // No need to return error in case key has already disappeared 
from key server
+               return nil
+       }
+       kmipErr := rpcConn.Svc.KMIPClient.DestroyKey(rec.ID)
+       dbErr := rpcConn.Svc.KeyDB.Erase(req.UUID)
+       if dbErr == nil && kmipErr != nil {
+               return fmt.Errorf("EraseKey: key tracking record has been 
erased from database, but KMIP did not erase it - %v", kmipErr)
+       }
+       return dbErr
 }
 
 // Reload key database into memory. This function can only be called from 
127.0.0.1. No password is required.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyserv/rpc_svc_test.go new/keyserv/rpc_svc_test.go
--- old/keyserv/rpc_svc_test.go 2017-05-05 15:40:57.623136513 +0200
+++ new/keyserv/rpc_svc_test.go 2017-06-01 14:25:52.106974576 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package keyserv
 
@@ -107,6 +107,7 @@
                KeyCreationGreeting:  "b",
                KeyRetrievalSubject:  "c",
                KeyRetrievalGreeting: "d",
+               KMIPAddresses:        []string{},
        }) {
                t.Fatalf("%+v", svcConf)
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmip/structure/const.go new/kmip/structure/const.go
--- old/kmip/structure/const.go 2017-05-05 16:33:24.064824922 +0200
+++ new/kmip/structure/const.go 2017-05-31 13:44:56.466420334 +0200
@@ -1,3 +1,5 @@
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
+// This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package structure
 
 import (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmip/structure/op_common.go 
new/kmip/structure/op_common.go
--- old/kmip/structure/op_common.go     2017-05-08 10:31:01.908508293 +0200
+++ new/kmip/structure/op_common.go     2017-06-01 14:55:51.121761395 +0200
@@ -1,3 +1,5 @@
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
+// This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package structure
 
 import (
@@ -135,21 +137,29 @@
 
 func (header SRequestHeader) SerialiseToTTLV() ttlv.Item {
        header.IBatchCount.Tag = TagBatchCount
-       return ttlv.NewStructure(
-               TagRequestHeader,
-               header.SProtocolVersion.SerialiseToTTLV(),
-               header.SAuthentication.SerialiseToTTLV(),
-               &header.IBatchCount)
+       if header.SAuthentication.SCredential.SCredentialValue.TUsername.Value 
== "" {
+               // Omit authentication header if no username data is given
+               return ttlv.NewStructure(
+                       TagRequestHeader,
+                       header.SProtocolVersion.SerialiseToTTLV(),
+                       &header.IBatchCount)
+       } else {
+               return ttlv.NewStructure(
+                       TagRequestHeader,
+                       header.SProtocolVersion.SerialiseToTTLV(),
+                       header.SAuthentication.SerialiseToTTLV(),
+                       &header.IBatchCount)
+       }
 }
 
 func (header *SRequestHeader) DeserialiseFromTTLV(in ttlv.Item) error {
        if err := DecodeStructItem(in, TagRequestHeader, TagProtocolVersion, 
&header.SProtocolVersion); err != nil {
                return err
-       } else if err := DecodeStructItem(in, TagRequestHeader, 
TagAuthentication, &header.SAuthentication); err != nil {
-               return err
        } else if err := DecodeStructItem(in, TagRequestHeader, TagBatchCount, 
&header.IBatchCount); err != nil {
                return err
        }
+       // Decode authentication header if it is given
+       DecodeStructItem(in, TagRequestHeader, TagAuthentication, 
&header.SAuthentication)
        return nil
 }
 
@@ -346,6 +356,8 @@
        if respItem.EResultStatus.Value == ValResultStatusSuccess {
                items = append(items, 
respItem.SResponsePayload.SerialiseToTTLV())
        } else {
+               respItem.EResultReason.Tag = TagResultReason
+               respItem.EResultMessage.Tag = TagResultMessage
                items = append(items, &respItem.EResultReason, 
&respItem.EResultMessage)
        }
        return ttlv.NewStructure(TagBatchItem, items...)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmip/structure/op_create.go 
new/kmip/structure/op_create.go
--- old/kmip/structure/op_create.go     2017-05-05 14:27:21.355190669 +0200
+++ new/kmip/structure/op_create.go     2017-05-31 13:44:56.298419370 +0200
@@ -1,6 +1,9 @@
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
+// This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package structure
 
 import (
+       "errors"
        "fmt"
        "github.com/HouzuoGuo/cryptctl/kmip/ttlv"
 )
@@ -27,6 +30,9 @@
        if err := DecodeStructItem(in, TagRequestMessage, TagBatchItem, 
&createReq.SRequestBatchItem); err != nil {
                return err
        }
+       if createReq.SRequestBatchItem.EOperation.Value != ValOperationCreate {
+               return errors.New("SCreateRequest.DeserialiseFromTTLV: input is 
not a create request")
+       }
        return nil
 }
 
@@ -91,6 +97,9 @@
        if err := DecodeStructItem(in, TagResponseMessage, TagBatchItem, 
&createResp.SResponseBatchItem); err != nil {
                return err
        }
+       if createResp.SResponseBatchItem.EOperation.Value != ValOperationCreate 
{
+               return errors.New("SCreateResponse.DeserialiseFromTTLV: input 
is not a create response")
+       }
        return nil
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmip/structure/op_destroy.go 
new/kmip/structure/op_destroy.go
--- old/kmip/structure/op_destroy.go    2017-05-02 11:44:07.005652544 +0200
+++ new/kmip/structure/op_destroy.go    2017-05-31 13:44:56.354419690 +0200
@@ -1,6 +1,9 @@
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
+// This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package structure
 
 import (
+       "errors"
        "fmt"
        "github.com/HouzuoGuo/cryptctl/kmip/ttlv"
 )
@@ -27,6 +30,9 @@
        if err := DecodeStructItem(in, TagRequestMessage, TagBatchItem, 
&destroyReq.SRequestBatchItem); err != nil {
                return err
        }
+       if destroyReq.SRequestBatchItem.EOperation.Value != ValOperationDestroy 
{
+               return errors.New("SDestroyRequest.DeserialiseFromTTLV: input 
is not a destroy request")
+       }
        return nil
 }
 
@@ -68,6 +74,9 @@
        if err := DecodeStructItem(in, TagResponseMessage, TagBatchItem, 
&destroyResp.SResponseBatchItem); err != nil {
                return err
        }
+       if destroyResp.SResponseBatchItem.EOperation.Value != 
ValOperationDestroy {
+               return errors.New("SDestroyResponse.DeserialiseFromTTLV: input 
is not a destroy response")
+       }
        return nil
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmip/structure/op_get.go new/kmip/structure/op_get.go
--- old/kmip/structure/op_get.go        2017-05-02 11:44:07.009652563 +0200
+++ new/kmip/structure/op_get.go        2017-05-31 13:44:56.434420149 +0200
@@ -1,6 +1,9 @@
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
+// This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package structure
 
 import (
+       "errors"
        "fmt"
        "github.com/HouzuoGuo/cryptctl/kmip/ttlv"
 )
@@ -27,6 +30,9 @@
        if err := DecodeStructItem(in, TagRequestMessage, TagBatchItem, 
&getReq.SRequestBatchItem); err != nil {
                return err
        }
+       if getReq.SRequestBatchItem.EOperation.Value != ValOperationGet {
+               return errors.New("SGetRequest.DeserialiseFromTTLV: input is 
not a get request")
+       }
        return nil
 }
 
@@ -68,6 +74,9 @@
        if err := DecodeStructItem(in, TagResponseMessage, TagBatchItem, 
&getResp.SResponseBatchItem); err != nil {
                return err
        }
+       if getResp.SResponseBatchItem.EOperation.Value != ValOperationGet {
+               return errors.New("SGetResponse.DeserialiseFromTTLV: input is 
not a get response")
+       }
        return nil
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmip/structure/serialisation_test.go 
new/kmip/structure/serialisation_test.go
--- old/kmip/structure/serialisation_test.go    2017-05-08 10:15:35.383887948 
+0200
+++ new/kmip/structure/serialisation_test.go    2017-05-31 13:44:56.386419875 
+0200
@@ -1,3 +1,5 @@
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
+// This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package structure
 
 import (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmip/ttlv/dencode.go new/kmip/ttlv/dencode.go
--- old/kmip/ttlv/dencode.go    2017-05-08 11:38:54.789105478 +0200
+++ new/kmip/ttlv/dencode.go    2017-05-31 13:44:56.498420517 +0200
@@ -1,3 +1,5 @@
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
+// This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package ttlv
 
 import (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmip/ttlv/encoding_test.go 
new/kmip/ttlv/encoding_test.go
--- old/kmip/ttlv/encoding_test.go      2017-05-04 10:26:26.112467080 +0200
+++ new/kmip/ttlv/encoding_test.go      2017-05-31 13:44:56.330419553 +0200
@@ -1,3 +1,5 @@
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
+// This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package ttlv
 
 import (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmip/ttlv/sample.go new/kmip/ttlv/sample.go
--- old/kmip/ttlv/sample.go     2017-05-05 16:33:24.072824969 +0200
+++ new/kmip/ttlv/sample.go     2017-05-31 13:44:56.506420563 +0200
@@ -1,3 +1,5 @@
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
+// This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package ttlv
 
 var SampleCreateRequest = WiresharkDumpToBytes(`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kmip/ttlv/types.go new/kmip/ttlv/types.go
--- old/kmip/ttlv/types.go      2017-05-08 10:08:46.273873037 +0200
+++ new/kmip/ttlv/types.go      2017-05-31 13:44:56.422420082 +0200
@@ -1,3 +1,5 @@
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
+// This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package ttlv
 
 import (
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/main.go new/main.go
--- old/main.go 2017-04-12 10:14:52.257214284 +0200
+++ new/main.go 2017-06-01 11:17:39.060901553 +0200
@@ -1,5 +1,5 @@
 // +build linux
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package main
 
@@ -15,7 +15,7 @@
 
 func PrintHelpAndExit(exitStatus int) {
        fmt.Println(`cryptctl: encrypt and decrypt file systems using network 
key server.
-Copyright (C) 2016  SUSE Linux GmbH, Germany
+Copyright (C) 2017 SUSE Linux GmbH, Germany
 This program comes with ABSOLUTELY NO WARRANTY.This is free software, and you
 are welcome to redistribute it under certain conditions; see file "LICENSE".
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ospackage/etc/sysconfig/cryptctl-server 
new/ospackage/etc/sysconfig/cryptctl-server
--- old/ospackage/etc/sysconfig/cryptctl-server 2017-05-11 15:49:38.135920761 
+0200
+++ new/ospackage/etc/sysconfig/cryptctl-server 2017-06-01 13:50:17.938692498 
+0200
@@ -78,10 +78,22 @@
 ## Default: ""
 #
 # Mail agent address and port number in the format of "address:port". The 
address must be fully qualified domain name.
-# If all Email parameters are filled in, notifications will be sent upon key 
creation/retrieval events.
+# If this parameter is set, mail notifications will be sent upon key 
creation/retrieval events.
 EMAIL_AGENT_AND_PORT=""
 
 ## Type:    string
+## Default: ""
+#
+# Mail agent plain authentication username (optional).
+EMAIL_AGENT_USERNAME=""
+
+## Type:    string
+## Default: ""
+#
+# Mail agent plain authentication password (optional).
+EMAIL_AGENT_PASSWORD=""
+
+## Type:    string
 ## Default: "A new file system has been encrypted"
 #
 # Subject shown in notification emails sent by key creation events.
@@ -108,8 +120,9 @@
 ## Type:    string
 ## Default: ""
 #
-# If key server should act as KMIP proxy, this is the KMIP host name.
-KMIP_SERVER_HOST=""
+# If key server should act as KMIP proxy, this is the KMIP hostname:port list, 
separated by space.
+# (e.g. host1:port1 host2:port2 ...)
+KMIP_SERVER_ADDRESSES=""
 
 ## Type:    integer
 ## Default: ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ospackage/man/cryptctl.8 new/ospackage/man/cryptctl.8
--- old/ospackage/man/cryptctl.8        2017-05-11 15:49:38.491922888 +0200
+++ new/ospackage/man/cryptctl.8        2017-05-31 13:45:21.458563746 +0200
@@ -1,6 +1,6 @@
 .\"/*
 .\" * All rights reserved
-.\" * Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
+.\" * Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
 .\" * Authors: Howard Guo
 .\" *
 .\" * This program is free software; you can redistribute it and/or
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/routine/encrypt.go new/routine/encrypt.go
--- old/routine/encrypt.go      2017-05-11 15:49:38.311921813 +0200
+++ new/routine/encrypt.go      2017-05-31 13:44:56.286419301 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package routine
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/routine/encrypt_test.go new/routine/encrypt_test.go
--- old/routine/encrypt_test.go 2017-05-11 15:49:38.135920761 +0200
+++ new/routine/encrypt_test.go 2017-05-31 13:44:56.518420632 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package routine
 
@@ -487,7 +487,8 @@
        resetDisks()
        // Now that server has shut down, try to unlock disks using key records 
only.
        if len(srv.KeyDB.RecordsByUUID) != 2 {
-               t.Fatal(srv.KeyDB.RecordsByUUID)
+
+               t.Fatalf("%+v\n", srv.KeyDB.RecordsByUUID)
        }
        records := make([]keydb.Record, 0, 0)
        for _, record := range srv.KeyDB.RecordsByUUID {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/routine/openssl.go new/routine/openssl.go
--- old/routine/openssl.go      2017-04-12 10:14:52.257214284 +0200
+++ new/routine/openssl.go      2017-05-31 13:44:56.550420815 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package routine
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/routine/openssl_test.go new/routine/openssl_test.go
--- old/routine/openssl_test.go 2017-04-12 10:14:52.257214284 +0200
+++ new/routine/openssl_test.go 2017-05-31 13:44:56.486420449 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package routine
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/routine/unlock.go new/routine/unlock.go
--- old/routine/unlock.go       2017-05-11 15:49:38.311921813 +0200
+++ new/routine/unlock.go       2017-05-31 13:44:56.538420747 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package routine
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sys/daemon.go new/sys/daemon.go
--- old/sys/daemon.go   2017-04-12 10:14:52.257214284 +0200
+++ new/sys/daemon.go   2017-05-31 13:44:56.454420264 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package sys
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sys/daemon_test.go new/sys/daemon_test.go
--- old/sys/daemon_test.go      2017-04-12 10:14:52.257214284 +0200
+++ new/sys/daemon_test.go      2017-05-31 13:44:56.374419805 +0200
@@ -1,3 +1,5 @@
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
+// This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package sys
 
 import "testing"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sys/exec.go new/sys/exec.go
--- old/sys/exec.go     2017-04-12 10:14:52.257214284 +0200
+++ new/sys/exec.go     2017-05-31 13:44:56.414420036 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package sys
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sys/exec_test.go new/sys/exec_test.go
--- old/sys/exec_test.go        2017-04-12 10:14:52.257214284 +0200
+++ new/sys/exec_test.go        2017-05-31 13:44:56.318419484 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package sys
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sys/sysconfig.go new/sys/sysconfig.go
--- old/sys/sysconfig.go        2017-04-12 10:14:52.257214284 +0200
+++ new/sys/sysconfig.go        2017-05-31 13:44:56.394419921 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package sys
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sys/sysconfig_test.go new/sys/sysconfig_test.go
--- old/sys/sysconfig_test.go   2017-04-12 10:14:52.257214284 +0200
+++ new/sys/sysconfig_test.go   2017-05-31 13:44:56.406419990 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package sys
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sys/term.go new/sys/term.go
--- old/sys/term.go     2017-05-11 15:49:38.135920761 +0200
+++ new/sys/term.go     2017-05-31 13:44:56.442420197 +0200
@@ -1,4 +1,4 @@
-// cryptctl - Copyright (c) 2016 SUSE Linux GmbH, Germany
+// cryptctl - Copyright (c) 2017 SUSE Linux GmbH, Germany
 // This source code is licensed under GPL version 3 that can be found in 
LICENSE file.
 package sys
 


Reply via email to