Browse code

Limit tapctl.exe and openvpnmsica.dll to TAP-Windows6 adapters only

Note: Hardware ID check is used selectively. When naming the adapter, we
still need to check all existing adapters to prevent duplicate names.
When listing or removing adapters by name, the operation is limited to
TUN-Windows6 adapters only.

This patch follows Gert's recommendations from [openvpn-devel].

Signed-off-by: Simon Rozman <simon@rozman.si>
Message-ID: <20190120130813.GY962@greenie.muc.de>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20190224181621.27020-1-simon@rozman.si>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg18234.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Simon Rozman authored on 2019/02/25 03:16:21
Showing 5 changed files
... ...
@@ -444,9 +444,9 @@ msica_op_tap_interface_create_exec(
444 444
         }
445 445
     }
446 446
 
447
-    /* Get available network interfaces. */
447
+    /* Get all available network interfaces. */
448 448
     struct tap_interface_node *pInterfaceList = NULL;
449
-    DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList);
449
+    DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList, TRUE);
450 450
     if (dwResult == ERROR_SUCCESS)
451 451
     {
452 452
         /* Does interface exist? */
... ...
@@ -599,9 +599,9 @@ msica_op_tap_interface_delete_by_name_exec(
599 599
         }
600 600
     }
601 601
 
602
-    /* Get available network interfaces. */
602
+    /* Get available TUN/TAP interfaces. */
603 603
     struct tap_interface_node *pInterfaceList = NULL;
604
-    DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList);
604
+    DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList, FALSE);
605 605
     if (dwResult == ERROR_SUCCESS)
606 606
     {
607 607
         /* Does interface exist? */
... ...
@@ -657,9 +657,9 @@ msica_op_tap_interface_delete_by_guid_exec(
657 657
         }
658 658
     }
659 659
 
660
-    /* Get available network interfaces. */
660
+    /* Get all available interfaces. */
661 661
     struct tap_interface_node *pInterfaceList = NULL;
662
-    DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList);
662
+    DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList, TRUE);
663 663
     if (dwResult == ERROR_SUCCESS)
664 664
     {
665 665
         /* Does interface exist? */
... ...
@@ -716,9 +716,9 @@ msica_op_tap_interface_set_name_exec(
716 716
         }
717 717
     }
718 718
 
719
-    /* Get available network interfaces. */
719
+    /* Get all available network interfaces. */
720 720
     struct tap_interface_node *pInterfaceList = NULL;
721
-    DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList);
721
+    DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList, TRUE);
722 722
     if (dwResult == ERROR_SUCCESS)
723 723
     {
724 724
         /* Does interface exist? */
... ...
@@ -476,9 +476,9 @@ FindTAPInterfaces(_In_ MSIHANDLE hInstall)
476 476
 
477 477
     OPENVPNMSICA_SAVE_MSI_SESSION(hInstall);
478 478
 
479
-    /* Get available network interfaces. */
479
+    /* Get all TUN/TAP network interfaces. */
480 480
     struct tap_interface_node *pInterfaceList = NULL;
481
-    uiResult = tap_list_interfaces(NULL, &pInterfaceList);
481
+    uiResult = tap_list_interfaces(NULL, &pInterfaceList, FALSE);
482 482
     if (uiResult != ERROR_SUCCESS)
483 483
     {
484 484
         goto cleanup_CoInitialize;
... ...
@@ -517,58 +517,15 @@ FindTAPInterfaces(_In_ MSIHANDLE hInstall)
517 517
         }
518 518
     }
519 519
 
520
-    /* Enumerate interfaces. */
521
-    struct interface_node
520
+    if (pInterfaceList != NULL)
522 521
     {
523
-        const struct tap_interface_node *iface;
524
-        struct interface_node *next;
525
-    } *interfaces_head = NULL, *interfaces_tail = NULL;
526
-    size_t interface_count = 0;
527
-    MSIHANDLE hRecord = MsiCreateRecord(1);
528
-    for (struct tap_interface_node *pInterface = pInterfaceList; pInterface; pInterface = pInterface->pNext)
529
-    {
530
-        for (LPCTSTR hwid = pInterface->szzHardwareIDs; hwid[0]; hwid += _tcslen(hwid) + 1)
522
+        /* Count interfaces. */
523
+        size_t interface_count = 0;
524
+        for (struct tap_interface_node *pInterface = pInterfaceList; pInterface; pInterface = pInterface->pNext)
531 525
         {
532
-            if (_tcsicmp(hwid, TEXT(TAP_WIN_COMPONENT_ID)) == 0
533
-                || _tcsicmp(hwid, TEXT("root\\") TEXT(TAP_WIN_COMPONENT_ID)) == 0)
534
-            {
535
-                /* TAP interface found. */
536
-
537
-                /* Report the GUID of the interface to installer. */
538
-                LPOLESTR szInterfaceId = NULL;
539
-                StringFromIID((REFIID)&pInterface->guid, &szInterfaceId);
540
-                MsiRecordSetString(hRecord, 1, szInterfaceId);
541
-                MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord);
542
-                CoTaskMemFree(szInterfaceId);
543
-
544
-                /* Append interface to the list. */
545
-                struct interface_node *node = (struct interface_node *)malloc(sizeof(struct interface_node));
546
-                if (node == NULL)
547
-                {
548
-                    MsiCloseHandle(hRecord);
549
-                    msg(M_FATAL, "%s: malloc(%u) failed", __FUNCTION__, sizeof(struct interface_node));
550
-                    uiResult = ERROR_OUTOFMEMORY; goto cleanup_pAdapterAdresses;
551
-                }
552
-
553
-                node->iface = pInterface;
554
-                node->next = NULL;
555
-                if (interfaces_head)
556
-                {
557
-                    interfaces_tail = interfaces_tail->next = node;
558
-                }
559
-                else
560
-                {
561
-                    interfaces_head = interfaces_tail = node;
562
-                }
563
-                interface_count++;
564
-                break;
565
-            }
526
+            interface_count++;
566 527
         }
567
-    }
568
-    MsiCloseHandle(hRecord);
569 528
 
570
-    if (interface_count)
571
-    {
572 529
         /* Prepare semicolon delimited list of TAP interface ID(s) and active TAP interface ID(s). */
573 530
         LPTSTR
574 531
             szTAPInterfaces     = (LPTSTR)malloc(interface_count * (38 /*GUID*/ + 1 /*separator/terminator*/) * sizeof(TCHAR)),
... ...
@@ -588,11 +545,11 @@ FindTAPInterfaces(_In_ MSIHANDLE hInstall)
588 588
             uiResult = ERROR_OUTOFMEMORY; goto cleanup_szTAPInterfaces;
589 589
         }
590 590
 
591
-        while (interfaces_head)
591
+        for (struct tap_interface_node *pInterface = pInterfaceList; pInterface; pInterface = pInterface->pNext)
592 592
         {
593 593
             /* Convert interface GUID to UTF-16 string. (LPOLESTR defaults to LPWSTR) */
594 594
             LPOLESTR szInterfaceId = NULL;
595
-            StringFromIID((REFIID)&interfaces_head->iface->guid, &szInterfaceId);
595
+            StringFromIID((REFIID)&pInterface->guid, &szInterfaceId);
596 596
 
597 597
             /* Append to the list of TAP interface ID(s). */
598 598
             if (szTAPInterfaces < szTAPInterfacesTail)
... ...
@@ -605,11 +562,11 @@ FindTAPInterfaces(_In_ MSIHANDLE hInstall)
605 605
             /* If this interface is active (connected), add it to the list of active TAP interface ID(s). */
606 606
             for (PIP_ADAPTER_ADDRESSES p = pAdapterAdresses; p; p = p->Next)
607 607
             {
608
-                OLECHAR szId[38 + 1];
608
+                OLECHAR szId[38 /*GUID*/ + 1 /*terminator*/];
609 609
                 GUID guid;
610 610
                 if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, p->AdapterName, -1, szId, _countof(szId)) > 0
611 611
                     && SUCCEEDED(IIDFromString(szId, &guid))
612
-                    && memcmp(&guid, &interfaces_head->iface->guid, sizeof(GUID)) == 0)
612
+                    && memcmp(&guid, &pInterface->guid, sizeof(GUID)) == 0)
613 613
                 {
614 614
                     if (p->OperStatus == IfOperStatusUp)
615 615
                     {
... ...
@@ -625,10 +582,6 @@ FindTAPInterfaces(_In_ MSIHANDLE hInstall)
625 625
                 }
626 626
             }
627 627
             CoTaskMemFree(szInterfaceId);
628
-
629
-            struct interface_node *p = interfaces_head;
630
-            interfaces_head = interfaces_head->next;
631
-            free(p);
632 628
         }
633 629
         szTAPInterfacesTail      [0] = 0;
634 630
         szTAPInterfacesActiveTail[0] = 0;
... ...
@@ -58,7 +58,7 @@ static const TCHAR usage_message[] =
58 58
     TEXT("Commands:\n")
59 59
     TEXT("\n")
60 60
     TEXT("create     Create a new TUN/TAP interface\n")
61
-    TEXT("list       List network interfaces\n")
61
+    TEXT("list       List TUN/TAP interfaces\n")
62 62
     TEXT("delete     Delete specified network interface\n")
63 63
     TEXT("help       Display this text\n")
64 64
     TEXT("\n")
... ...
@@ -90,7 +90,7 @@ static const TCHAR usage_message_create[] =
90 90
 static const TCHAR usage_message_list[] =
91 91
     TEXT("%s\n")
92 92
     TEXT("\n")
93
-    TEXT("Lists network interfaces\n")
93
+    TEXT("Lists TUN/TAP interfaces\n")
94 94
     TEXT("\n")
95 95
     TEXT("Usage:\n")
96 96
     TEXT("\n")
... ...
@@ -98,7 +98,7 @@ static const TCHAR usage_message_list[] =
98 98
     TEXT("\n")
99 99
     TEXT("Output:\n")
100 100
     TEXT("\n")
101
-    TEXT("This command prints all network interfaces to stdout.                          \n")
101
+    TEXT("This command prints all TUN/TAP interfaces to stdout.                          \n")
102 102
 ;
103 103
 
104 104
 static const TCHAR usage_message_delete[] =
... ...
@@ -200,9 +200,9 @@ _tmain(int argc, LPCTSTR argv[])
200 200
 
201 201
         if (szName)
202 202
         {
203
-            /* Get the list of available interfaces. */
203
+            /* Get the list of all available interfaces. */
204 204
             struct tap_interface_node *pInterfaceList = NULL;
205
-            dwResult = tap_list_interfaces(NULL, &pInterfaceList);
205
+            dwResult = tap_list_interfaces(NULL, &pInterfaceList, TRUE);
206 206
             if (dwResult != ERROR_SUCCESS)
207 207
             {
208 208
                 _ftprintf(stderr, TEXT("Enumerating interfaces failed (error 0x%x).\n"), dwResult);
... ...
@@ -257,12 +257,12 @@ create_delete_interface:
257 257
     }
258 258
     else if (_tcsicmp(argv[1], TEXT("list")) == 0)
259 259
     {
260
-        /* Output list of network interfaces. */
260
+        /* Output list of TUN/TAP interfaces. */
261 261
         struct tap_interface_node *pInterfaceList = NULL;
262
-        DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList);
262
+        DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList, FALSE);
263 263
         if (dwResult != ERROR_SUCCESS)
264 264
         {
265
-            _ftprintf(stderr, TEXT("Enumerating interfaces failed (error 0x%x).\n"), dwResult);
265
+            _ftprintf(stderr, TEXT("Enumerating TUN/TAP interfaces failed (error 0x%x).\n"), dwResult);
266 266
             iResult = 1; goto quit;
267 267
         }
268 268
 
... ...
@@ -290,10 +290,10 @@ create_delete_interface:
290 290
         {
291 291
             /* The argument failed to covert to GUID. Treat it as the interface name. */
292 292
             struct tap_interface_node *pInterfaceList = NULL;
293
-            DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList);
293
+            DWORD dwResult = tap_list_interfaces(NULL, &pInterfaceList, FALSE);
294 294
             if (dwResult != ERROR_SUCCESS)
295 295
             {
296
-                _ftprintf(stderr, TEXT("Enumerating interfaces failed (error 0x%x).\n"), dwResult);
296
+                _ftprintf(stderr, TEXT("Enumerating TUN/TAP interfaces failed (error 0x%x).\n"), dwResult);
297 297
                 iResult = 1; goto quit;
298 298
             }
299 299
 
... ...
@@ -953,7 +953,8 @@ cleanup_szInterfaceId:
953 953
 DWORD
954 954
 tap_list_interfaces(
955 955
     _In_opt_ HWND hwndParent,
956
-    _Out_ struct tap_interface_node **ppInterface)
956
+    _Out_ struct tap_interface_node **ppInterface,
957
+    _In_ BOOL bAll)
957 958
 {
958 959
     DWORD dwResult;
959 960
 
... ...
@@ -1015,19 +1016,6 @@ tap_list_interfaces(
1015 1015
             }
1016 1016
         }
1017 1017
 
1018
-        /* Get interface GUID. */
1019
-        GUID guidInterface;
1020
-        dwResult = get_net_interface_guid(hDevInfoList, &devinfo_data, 1, &guidInterface);
1021
-        if (dwResult != ERROR_SUCCESS)
1022
-        {
1023
-            /* Something is wrong with this device. Skip it. */
1024
-            continue;
1025
-        }
1026
-
1027
-        /* Get the interface GUID as string. */
1028
-        LPOLESTR szInterfaceId = NULL;
1029
-        StringFromIID((REFIID)&guidInterface, &szInterfaceId);
1030
-
1031 1018
         /* Get device hardware ID(s). */
1032 1019
         DWORD dwDataType = REG_NONE;
1033 1020
         LPTSTR szzDeviceHardwareIDs = NULL;
... ...
@@ -1039,9 +1027,57 @@ tap_list_interfaces(
1039 1039
             (LPVOID)&szzDeviceHardwareIDs);
1040 1040
         if (dwResult != ERROR_SUCCESS)
1041 1041
         {
1042
-            goto cleanup_szInterfaceId;
1042
+            /* Something is wrong with this device. Skip it. */
1043
+            continue;
1043 1044
         }
1044 1045
 
1046
+        /* Check that hardware ID is REG_SZ/REG_MULTI_SZ, and optionally if it matches ours. */
1047
+        if (dwDataType == REG_SZ)
1048
+        {
1049
+            if (!bAll && _tcsicmp(szzDeviceHardwareIDs, szzHardwareIDs) != 0)
1050
+            {
1051
+                /* This is not our device. Skip it. */
1052
+                goto cleanup_szzDeviceHardwareIDs;
1053
+            }
1054
+        }
1055
+        else if (dwDataType == REG_MULTI_SZ)
1056
+        {
1057
+            if (!bAll)
1058
+            {
1059
+                for (LPTSTR szHwdID = szzDeviceHardwareIDs;; szHwdID += _tcslen(szHwdID) + 1)
1060
+                {
1061
+                    if (szHwdID[0] == 0)
1062
+                    {
1063
+                        /* This is not our device. Skip it. */
1064
+                        goto cleanup_szzDeviceHardwareIDs;
1065
+                    }
1066
+                    else if (_tcsicmp(szHwdID, szzHardwareIDs) == 0)
1067
+                    {
1068
+                        /* This is our device. */
1069
+                        break;
1070
+                    }
1071
+                }
1072
+            }
1073
+        }
1074
+        else
1075
+        {
1076
+            /* Unexpected hardware ID format. Skip device. */
1077
+            goto cleanup_szzDeviceHardwareIDs;
1078
+        }
1079
+
1080
+        /* Get interface GUID. */
1081
+        GUID guidInterface;
1082
+        dwResult = get_net_interface_guid(hDevInfoList, &devinfo_data, 1, &guidInterface);
1083
+        if (dwResult != ERROR_SUCCESS)
1084
+        {
1085
+            /* Something is wrong with this device. Skip it. */
1086
+            goto cleanup_szzDeviceHardwareIDs;
1087
+        }
1088
+
1089
+        /* Get the interface GUID as string. */
1090
+        LPOLESTR szInterfaceId = NULL;
1091
+        StringFromIID((REFIID)&guidInterface, &szInterfaceId);
1092
+
1045 1093
         /* Render registry key path. */
1046 1094
         TCHAR szRegKey[INTERFACE_REGKEY_PATH_MAX];
1047 1095
         _stprintf_s(
... ...
@@ -1062,7 +1098,7 @@ tap_list_interfaces(
1062 1062
         {
1063 1063
             SetLastError(dwResult); /* MSDN does not mention RegOpenKeyEx() to set GetLastError(). But we do have an error code. Set last error manually. */
1064 1064
             msg(M_WARN | M_ERRNO, "%s: RegOpenKeyEx(HKLM, \"%" PRIsLPTSTR "\") failed", __FUNCTION__, szRegKey);
1065
-            goto cleanup_szzDeviceHardwareIDs;
1065
+            goto cleanup_szInterfaceId;
1066 1066
         }
1067 1067
 
1068 1068
         /* Read interface name. */
... ...
@@ -1108,10 +1144,10 @@ cleanup_szName:
1108 1108
         free(szName);
1109 1109
 cleanup_hKey:
1110 1110
         RegCloseKey(hKey);
1111
-cleanup_szzDeviceHardwareIDs:
1112
-        free(szzDeviceHardwareIDs);
1113 1111
 cleanup_szInterfaceId:
1114 1112
         CoTaskMemFree(szInterfaceId);
1113
+cleanup_szzDeviceHardwareIDs:
1114
+        free(szzDeviceHardwareIDs);
1115 1115
     }
1116 1116
 
1117 1117
     dwResult = ERROR_SUCCESS;
... ...
@@ -55,7 +55,7 @@ tap_create_interface(
55 55
 
56 56
 
57 57
 /**
58
- * Deletes a TUN/TAP interface.
58
+ * Deletes an interface.
59 59
  *
60 60
  * @param hwndParent    A handle to the top-level window to use for any user interface that is
61 61
  *                      related to non-device-specific actions (such as a select-device dialog
... ...
@@ -120,12 +120,16 @@ struct tap_interface_node
120 120
  *                      the list. After the list is no longer required, free it using
121 121
  *                      tap_free_interface_list().
122 122
  *
123
+ * @param bAll          When TRUE, all network interfaces found are added to the list. When
124
+ *                      FALSE, only TUN/TAP interfaces found are added.
125
+ *
123 126
  * @return ERROR_SUCCESS on success; Win32 error code otherwise
124 127
  */
125 128
 DWORD
126 129
 tap_list_interfaces(
127 130
     _In_opt_ HWND hwndParent,
128
-    _Out_ struct tap_interface_node **ppInterfaceList);
131
+    _Out_ struct tap_interface_node **ppInterfaceList,
132
+    _In_ BOOL bAll);
129 133
 
130 134
 
131 135
 /**