security/agent: Bugfix for passphrase encoded private keys.

Prior to this change, if you had a passphrase on the private key, then
the agent would fail to start the child process. Likely a fallout from
the veyron2.Init refactorings.

This commit makes the agent usable again with passphrase protected
keys and adds a shell test that would fail without the corresponding
change to agentd/main.go.

Change-Id: I1fd959cc4609b3f6b6a6ac7ab384f8e7be9e5660
diff --git a/security/agent/agentd/main.go b/security/agent/agentd/main.go
index ec7babd..f0fed27 100644
--- a/security/agent/agentd/main.go
+++ b/security/agent/agentd/main.go
@@ -64,7 +64,13 @@
 		return
 	}
 
-	dir := flag.Lookup("veyron.credentials").Value.String()
+	var dir string
+	if f := flag.Lookup("veyron.credentials").Value; true {
+		dir = f.String()
+		// Clear out the flag value to prevent veyron2.Init from
+		// trying to load this password protected principal.
+		f.Set("")
+	}
 	if len(dir) == 0 {
 		vlog.Fatalf("The %v environment variable must be set to a directory", consts.VeyronCredentials)
 	}
@@ -74,6 +80,10 @@
 		vlog.Fatalf("failed to create new principal from dir(%s): %v", dir, err)
 	}
 
+	// Clear out the environment variable before veyron2.Init.
+	if err = os.Setenv(consts.VeyronCredentials, ""); err != nil {
+		vlog.Fatalf("setenv: %v", err)
+	}
 	ctx, shutdown := veyron2.Init()
 	defer shutdown()
 
@@ -84,9 +94,6 @@
 	if err = os.Setenv(agent.FdVarName, "3"); err != nil {
 		vlog.Fatalf("setenv: %v", err)
 	}
-	if err = os.Setenv(consts.VeyronCredentials, ""); err != nil {
-		vlog.Fatalf("setenv: %v", err)
-	}
 
 	if *keypath == "" && passphrase != nil {
 		// If we're done with the passphrase, zero it out so it doesn't stay in memory
diff --git a/security/agent/test.sh b/security/agent/test.sh
index f4aaeba..2d05ccd 100755
--- a/security/agent/test.sh
+++ b/security/agent/test.sh
@@ -21,9 +21,28 @@
 
 
   shell_test::setup_server_test || shell_test::fail "line ${LINENO} failed to setup server test"
+
+  # Test passphrase use
   export VEYRON_CREDENTIALS="$(shell::tmp_dir)"
+  local -r LOG_DIR="$(shell::tmp_dir)"
+  echo -n "agentd: passphrase..."
+  # Create the passphrase
+  echo "PASSWORD" | "${AGENTD_BIN}" echo "Hello" &>"${LOG_DIR}/1" || shell_test::fail "line ${LINENO}: agent failed to create passphrase protected principal: $(cat "${LOG_DIR}/1")"
+  # Use it successfully
+  echo "PASSWORD" | "${AGENTD_BIN}" echo "Hello" &>"${LOG_DIR}/2"  || shell_test::fail "line ${LINENO}: agent failed to use passphrase protected principal: $(cat "${LOG_DIR}/2")"
+  # Wrong passphrase should fail
+  echo "BADPASSWORD" | "${AGENTD_BIN}" echo "Hello" &>"${LOG_DIR}/3" && shell_test::fail "line ${LINENO}: agent should have failed with wrong passphrase"
+  local -r NHELLOS="$(grep "Hello" "${LOG_DIR}"/* | wc -l)"
+  if [[ "${NHELLOS}" -ne 2 ]]; then
+	  shell_test::fail "line ${LINENO}: expected 2 'Hello's, got "${NHELLOS}" in $(cat "${LOG_DIR}"/*)"
+  fi
+  echo "OK"
+
+
+
   # Test all methods of the principal interface.
   # (Errors are printed to STDERR)
+  export VEYRON_CREDENTIALS="$(shell::tmp_dir)"
   echo -n "agentd: test_principal..."
   "${AGENTD_BIN}" "${TESTPRINCIPAL_BIN}" >/dev/null || shell_test::fail "line ${LINENO}"
   echo "OK"