shill: openvpn: Support no-OTP user/password authentication.

This also fixes a flimflam bug where passwords were sent unescaped, so \ and "
weren't legal password characters in no-OTP authentication mode.

BUG=chromium:137970
TEST=unit tests

Change-Id: I0caad371a5db91739eaf83fc587ad88df1433c77
Reviewed-on: https://gerrit.chromium.org/gerrit/28266
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Commit-Ready: Darin Petkov <petkov@chromium.org>
diff --git a/openvpn_management_server.h b/openvpn_management_server.h
index 025560c..f959c9f 100644
--- a/openvpn_management_server.h
+++ b/openvpn_management_server.h
@@ -47,18 +47,22 @@
 
  private:
   friend class OpenVPNManagementServerTest;
+  FRIEND_TEST(OpenVPNManagementServerTest, EscapeToQuote);
   FRIEND_TEST(OpenVPNManagementServerTest, Hold);
   FRIEND_TEST(OpenVPNManagementServerTest, OnInput);
   FRIEND_TEST(OpenVPNManagementServerTest, OnInputStop);
   FRIEND_TEST(OpenVPNManagementServerTest, OnReady);
   FRIEND_TEST(OpenVPNManagementServerTest, OnReadyAcceptFail);
   FRIEND_TEST(OpenVPNManagementServerTest, ParseNeedPasswordTag);
+  FRIEND_TEST(OpenVPNManagementServerTest, PerformAuthentication);
+  FRIEND_TEST(OpenVPNManagementServerTest, PerformAuthenticationNoCreds);
   FRIEND_TEST(OpenVPNManagementServerTest, PerformStaticChallenge);
   FRIEND_TEST(OpenVPNManagementServerTest, PerformStaticChallengeNoCreds);
   FRIEND_TEST(OpenVPNManagementServerTest, ProcessFailedPasswordMessage);
   FRIEND_TEST(OpenVPNManagementServerTest, ProcessHoldMessage);
   FRIEND_TEST(OpenVPNManagementServerTest, ProcessInfoMessage);
   FRIEND_TEST(OpenVPNManagementServerTest, ProcessMessage);
+  FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuth);
   FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageAuthSC);
   FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageTPMToken);
   FRIEND_TEST(OpenVPNManagementServerTest, ProcessNeedPasswordMessageUnknown);
@@ -91,10 +95,16 @@
   bool ProcessHoldMessage(const std::string &message);
 
   void PerformStaticChallenge(const std::string &tag);
+  void PerformAuthentication(const std::string &tag);
   void SupplyTPMToken(const std::string &tag);
 
   static std::string ParseNeedPasswordTag(const std::string &message);
 
+  // Escapes |str| per OpenVPN's command parsing rules assuming |str| will be
+  // sent over the management interface quoted (i.e., whitespace is not
+  // escaped).
+  static std::string EscapeToQuote(const std::string &str);
+
   bool IsStarted() const { return sockets_; }
 
   OpenVPNDriver *driver_;