[RFC] Handle ipv6 connections 23/178723/3
authorPaweł Szewczyk <p.szewczyk@samsung.com>
Fri, 11 May 2018 11:27:55 +0000 (13:27 +0200)
committerManish Rathod <manish.r@samsung.com>
Fri, 25 May 2018 06:53:11 +0000 (06:53 +0000)
It was assumed that connection to sdbd over tcp uses ipv4. Now it is
possible to receive ipv6 connection as well (not only IPv4-mapped, but a
real one). This requires ipv6 address validation in plugin API.

This commit adds such API, with default implementation to block all ipv6
addresses. It should be implemented according to security policy on
given platform.

Change-Id: I056c63485e2d6e23269091822a231d7b9b817048
Signed-off-by: Paweł Szewczyk <p.szewczyk@samsung.com>
src/default_plugin_basic.c
src/default_plugin_main.c
src/sdbd_plugin.h
src/transport_local.c

index 18fed8a..8a180a1 100644 (file)
@@ -181,6 +181,33 @@ int verify_peer_ip ( parameters* in, parameters* out )
     return PLUGIN_CMD_SUCCESS;
 }
 
+int verify_peer_ipv6 ( parameters* in, parameters* out )
+{
+    if ( in == NULL || in->number_of_parameter != 1 || in->array_of_parameter == NULL
+            || in->array_of_parameter[0].type != type_string ) {
+        D ( "Invalid argument\n" );
+        return PLUGIN_CMD_FAIL;
+    }
+
+    if ( out == NULL ) {
+        D ( "Invalid argument\n" );
+        return PLUGIN_CMD_FAIL;
+    }
+
+    D ( "shell command : %s\n", in->array_of_parameter[0].v_string.data );
+
+    out->number_of_parameter = 1;
+    out->array_of_parameter = ( parameter* ) malloc ( sizeof ( parameter ) );
+    if (out->array_of_parameter == NULL) {
+        D("failed to allocate memory for the parameter\n");
+        return PLUGIN_CMD_FAIL;
+    }
+    out->array_of_parameter[0].type = type_int32;
+    out->array_of_parameter[0].v_int32 = PLUGIN_RET_INVALID;
+
+    return PLUGIN_CMD_SUCCESS;
+}
+
 int verify_sdbd_launch ( parameters* in, parameters* out )
 {
     if ( out == NULL ) {
@@ -273,4 +300,4 @@ int verify_push ( parameters* in, parameters* out )
     out->array_of_parameter[0].v_int32 = PLUGIN_RET_VALID;
 
     return PLUGIN_CMD_SUCCESS;
-}
\ No newline at end of file
+}
index 9195449..cc1abf4 100644 (file)
@@ -46,6 +46,8 @@ int default_plugin_sync_proc ( int cmd, parameters* in, parameters* out )
         ret = convert_shell_cmd ( in, out );
     } else if ( cmd == PLUGIN_SYNC_CMD_VERIFY_PEERIP ) {
         ret = verify_peer_ip ( in, out );
+    } else if ( cmd == PLUGIN_SYNC_CMD_VERIFY_PEERIPV6 ) {
+        ret = verify_peer_ipv6 ( in, out );
     } else if ( cmd == PLUGIN_SYNC_CMD_VERIFY_LAUNCH ) {
         ret = verify_sdbd_launch ( in, out );
     } else if ( cmd == PLUGIN_SYNC_CMD_VERIFY_ROOTCMD ) {
index d8cb702..e31eb31 100644 (file)
@@ -35,6 +35,7 @@
 #define PLUGIN_SYNC_CMD_GET_LOCK_STATE              1008
 #define PLUGIN_SYNC_CMD_GET_SHELL_ENV               1009
 #define PLUGIN_SYNC_CMD_VERITY_PUSH                 1010
+#define PLUGIN_SYNC_CMD_VERIFY_PEERIPV6             1011
 
 #define PLUGIN_SYNC_CMD_SEC_INIT                    1100
 #define PLUGIN_SYNC_CMD_SEC_DEINIT                  1101
index 294a365..20f2747 100644 (file)
@@ -152,6 +152,8 @@ static void *server_socket_thread(void * arg)
     struct sockaddr_storage addr;
     struct sockaddr_in *addr_v4;
     struct sockaddr_in6 *addr_v6;
+    char addr_buffer[INET6_ADDRSTRLEN];
+    int validate_cmd;
 
     D("transport: server_socket_thread() starting\n");
     serverfd = sdb_port_get_tcp_listenfd();
@@ -188,13 +190,22 @@ static void *server_socket_thread(void * arg)
            if (addr.ss_family == AF_INET) {
                    addr_v4 = (struct sockaddr_in *)(&addr);
                    addr_str = inet_ntoa(addr_v4->sin_addr);
+                   validate_cmd = PLUGIN_SYNC_CMD_VERIFY_PEERIP;
                    D("IPv4 connection (addr %s)\n", addr_str);
            } else if (addr.ss_family == AF_INET6) {
                    struct in_addr in;
                    addr_v6 = (struct sockaddr_in6 *)(&addr);
-                   memcpy(&in, addr_v6->sin6_addr.s6_addr + 12, sizeof(in));
-                   addr_str = inet_ntoa(in);
-                   D("IPv6 connection, mapped IPv4 addr: %s\n", addr_str);
+                   if (IN6_IS_ADDR_V4MAPPED(&addr_v6->sin6_addr)) {
+                           memcpy(&in, addr_v6->sin6_addr.s6_addr + 12, sizeof(in));
+                           addr_str = inet_ntoa(in);
+                           validate_cmd = PLUGIN_SYNC_CMD_VERIFY_PEERIP;
+                           D("IPv6 connection, mapped IPv4 addr: %s\n", addr_str);
+                   } else {
+                           addr_str = inet_ntop(addr.ss_family, &addr_v6->sin6_addr,
+                                           addr_buffer, INET6_ADDRSTRLEN);
+                           validate_cmd = PLUGIN_SYNC_CMD_VERIFY_PEERIPV6;
+                           D("IPv6 connection, addr: %s\n", addr_str);
+                   }
            } else {
                    D("Unknown socket family %d\n", addr.ss_family);
                    continue;
@@ -202,7 +213,7 @@ static void *server_socket_thread(void * arg)
 
             // Check the peer ip validation.
             if (!is_emulator()
-                && !request_validity_to_plugin(PLUGIN_SYNC_CMD_VERIFY_PEERIP, addr_str)) {
+                && !request_validity_to_plugin(validate_cmd, addr_str)) {
                 sdb_close(fd);
             } else {
                 int ret = -1;