p2p: validate the network name of a group

The network name of a group is also used as the SSID.
The network name must also comply normal SSID naming rules.

Bug: 144472136
Test: atest FrameworksWifiTests
Change-Id: I63f23fdb51a1e96019025e860832f1db7ec99fd0
diff --git a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
index 3f37456..055fa72 100644
--- a/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
+++ b/service/java/com/android/server/wifi/p2p/WifiP2pServiceImpl.java
@@ -100,6 +100,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.net.InetAddress;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -148,6 +149,11 @@
             android.Manifest.permission.ACCESS_WIFI_STATE
     };
 
+    // Maximum number of bytes allowed for a network name, i.e. SSID.
+    private static final int MAX_NETWORK_NAME_BYTES = 32;
+    // Minimum number of bytes for a network name, i.e. DIRECT-xy.
+    private static final int MIN_NETWORK_NAME_BYTES = 9;
+
     // Two minutes comes from the wpa_supplicant setting
     private static final int GROUP_CREATING_WAIT_TIME_MS = 120 * 1000;
     private static int sGroupCreatingTimeoutIndex = 0;
@@ -3255,6 +3261,23 @@
         }
 
         /**
+         * Check the network name complies standard SSID naming rules.
+         *
+         * The network name of a group is also the broadcasting SSID,
+         * as a result, the network name must complies standard SSID naming
+         * rules.
+         */
+        private boolean isValidNetworkName(String networkName) {
+            if (TextUtils.isEmpty(networkName)) return false;
+
+            byte[] ssidBytes = networkName.getBytes(StandardCharsets.UTF_8);
+            if (ssidBytes.length < MIN_NETWORK_NAME_BYTES) return false;
+            if (ssidBytes.length > MAX_NETWORK_NAME_BYTES) return false;
+
+            return true;
+        }
+
+        /**
          * A config is valid as a group if it has network name and passphrase.
          * Supplicant can construct a group on the fly for creating a group with specified config
          * or join a group without negotiation and WPS.
@@ -3264,7 +3287,7 @@
         private boolean isConfigValidAsGroup(WifiP2pConfig config) {
             if (config == null) return false;
             if (TextUtils.isEmpty(config.deviceAddress)) return false;
-            if (!TextUtils.isEmpty(config.networkName)
+            if (isValidNetworkName(config.networkName)
                     && !TextUtils.isEmpty(config.passphrase)) {
                 return true;
             }
diff --git a/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java
index 15d9ef9..1091c1d 100644
--- a/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/p2p/WifiP2pServiceImplTest.java
@@ -3812,4 +3812,28 @@
         mLooper.dispatchAll();
         verify(mWifiNative).p2pStopFind();
     }
+
+    /**
+     * Verify a network name which is too long is rejected.
+     */
+    @Test
+    public void testSendConnectMsgWithTooLongNetworkName() throws Exception {
+        mTestWifiP2pFastConnectionConfig.networkName = "DIRECT-xy-abcdefghijklmnopqrstuvw";
+        sendConnectMsg(mClientMessenger, mTestWifiP2pFastConnectionConfig);
+        verify(mClientHandler).sendMessage(mMessageCaptor.capture());
+        Message message = mMessageCaptor.getValue();
+        assertEquals(WifiP2pManager.CONNECT_FAILED, message.what);
+    }
+
+    /**
+     * Verify a network name which is too short is rejected.
+     */
+    @Test
+    public void testSendConnectMsgWithTooShortNetworkName() throws Exception {
+        mTestWifiP2pFastConnectionConfig.networkName = "DIRECT-x";
+        sendConnectMsg(mClientMessenger, mTestWifiP2pFastConnectionConfig);
+        verify(mClientHandler).sendMessage(mMessageCaptor.capture());
+        Message message = mMessageCaptor.getValue();
+        assertEquals(WifiP2pManager.CONNECT_FAILED, message.what);
+    }
 }