[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 18fed8a62e6077bfc7107a471469e7b617d3e5d5..8a180a15922ac3b7c2718d7f7404fbf86eacbe74 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 9195449e74dd96762aba47bc8e7897fe68d14e4d..cc1abf42c3f0248f4b84197099fe043bb0d57236 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 d8cb7021fbf4d02697fdcf27c66f5eb06965e01b..e31eb310f6308eb28ee7190003b50971bdff3ed4 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 294a365740c0c5cd2c2fa651e95e7531faec1e3b..20f27478250ebd9927eec3cb9ff8b5a9349ef81c 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;