Changeset 91769 in vbox
- Timestamp:
- Oct 15, 2021 7:24:43 PM (3 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/doc/manual/en_US/user_Networking.xml
r91416 r91769 1185 1185 </note> 1186 1186 1187 <para> 1188 On Linux, Mac OS X and Solaris &product-name; will only allow IP 1189 addresses in 192.68.56.0/21 range to be assigned to host-only 1190 adapters. For IPv6 only link-local addresses are allowed. If other 1191 ranges are desired, they can be enabled by creating 1192 <filename>/etc/vbox/networks.conf</filename> and specifying allowed 1193 ranges there. For example, to allow 10.0.0.0/8 and 192.168.0.0/16 1194 IPv4 ranges as well as 2001::/64 range put the following lines into 1195 <filename>/etc/vbox/networks.conf</filename>: 1196 <screen> 1197 * 10.0.0.0/8 192.168.0.0/16 1198 * 2001::/64 1199 </screen> 1200 Lines starting with the hash <command>#</command> are ignored. Next 1201 example allows any addresses, effectively disabling range control: 1202 <screen> 1203 * 0.0.0.0/0 ::/0 1204 </screen> 1205 If the file exists, but no ranges are specified in it, no addresses 1206 will be assigned to host-only adapters. The following example 1207 effectively disables all ranges: 1208 <screen> 1209 # No addresses are allowed for host-only adapters 1210 </screen> 1211 </para> 1212 1187 1213 </sect1> 1188 1214 -
trunk/src/VBox/HostDrivers/adpctl/Makefile.kmk
r82968 r91769 21 21 include $(KBUILD_PATH)/subheader.kmk 22 22 23 PROGRAMS += VBoxNetAdpCtl23 PROGRAMS += VBoxNetAdpCtl 24 24 ### Another template? We must *not* set RPATH! 25 VBoxNetAdpCtl_TEMPLATE = VBOXR3HARDENEDEXE 26 VBoxNetAdpCtl_SOURCES = VBoxNetAdpCtl.cpp 25 ifneq ($(KBUILD_TYPE),debug) 26 VBoxNetAdpCtl_TEMPLATE = VBoxR3SetUidToRoot 27 VBoxNetAdpCtl_LIBS += $(LIB_RUNTIME) 28 else 29 VBoxNetAdpCtl_TEMPLATE = VBoxR3Static 30 endif 31 VBoxNetAdpCtl_SOURCES = VBoxNetAdpCtl.cpp 27 32 28 33 include $(FILE_KBUILD_SUB_FOOTER) -
trunk/src/VBox/HostDrivers/adpctl/VBoxNetAdpCtl.cpp
r90773 r91769 33 33 #include <sys/stat.h> 34 34 #include <fcntl.h> 35 36 #include <iprt/err.h> 37 #include <iprt/initterm.h> 38 #include <iprt/message.h> 39 #include <iprt/net.h> 40 #include <iprt/string.h> 41 #include <iprt/uint128.h> 42 35 43 #ifdef RT_OS_LINUX 36 44 # include <arpa/inet.h> … … 49 57 # include <sys/ioccom.h> 50 58 #endif 51 52 #define NOREF(x) (void)x53 59 54 60 /** @todo Error codes must be moved to some header file */ … … 729 735 730 736 /********************************************************************************************************************************* 737 * Global config file implementation * 738 *********************************************************************************************************************************/ 739 740 #define VBOX_GLOBAL_NETWORK_CONFIG_PATH "/etc/vbox/networks.conf" 741 #define VBOXNET_DEFAULT_IPV4MASK "255.255.255.0" 742 743 class NetworkAddress 744 { 745 public: 746 bool isValidString(const char *pcszNetwork); 747 bool isValid() { return m_fValid; }; 748 virtual bool matches(const char *pcszNetwork) = 0; 749 virtual const char *defaultNetwork() = 0; 750 protected: 751 bool m_fValid; 752 753 int RTNetStrToIPv4CidrWithZeroPrefixAllowed(const char *pcszAddr, PRTNETADDRIPV4 pAddr, int *piPrefix); 754 int RTNetStrToIPv6CidrWithZeroPrefixAllowed(const char *pcszAddr, PRTNETADDRIPV6 pAddr, int *piPrefix); 755 }; 756 757 int NetworkAddress::RTNetStrToIPv4CidrWithZeroPrefixAllowed(const char *pcszAddr, PRTNETADDRIPV4 pAddr, int *piPrefix) 758 { 759 RTNETADDRIPV4 addr; 760 char *pszNext; 761 762 AssertPtrReturn(pcszAddr, VERR_INVALID_PARAMETER); 763 AssertPtrReturn(pAddr, VERR_INVALID_PARAMETER); 764 AssertPtrReturn(piPrefix, VERR_INVALID_PARAMETER); 765 766 pcszAddr = RTStrStripL(pcszAddr); 767 int rc = RTNetStrToIPv4AddrEx(pcszAddr, &addr, &pszNext); 768 if (RT_FAILURE(rc)) 769 return rc; 770 771 /* 772 * If the prefix is missing, treat is as exact (/32) address 773 * specification. 774 */ 775 if (*pszNext == '\0' || rc == VWRN_TRAILING_SPACES) 776 { 777 *pAddr = addr; 778 *piPrefix = 32; 779 return VINF_SUCCESS; 780 } 781 782 if (*pszNext == '/') 783 ++pszNext; 784 else 785 return VERR_INVALID_PARAMETER; 786 787 uint32_t prefix; 788 rc = RTStrToUInt32Ex(pszNext, &pszNext, 16, &prefix); 789 if ((rc == VINF_SUCCESS || rc == VWRN_TRAILING_SPACES) && prefix == 0) 790 { 791 *pAddr = addr; 792 *piPrefix = 0; 793 return VINF_SUCCESS; 794 } 795 return RTNetStrToIPv4Cidr(pcszAddr, pAddr, piPrefix); 796 } 797 798 RTDECL(int) NetworkAddress::RTNetStrToIPv6CidrWithZeroPrefixAllowed(const char *pcszAddr, PRTNETADDRIPV6 pAddr, int *piPrefix) 799 { 800 RTNETADDRIPV6 Addr; 801 uint8_t u8Prefix; 802 char *pszNext; 803 int rc; 804 805 AssertPtrReturn(pcszAddr, VERR_INVALID_PARAMETER); 806 AssertPtrReturn(pAddr, VERR_INVALID_PARAMETER); 807 AssertPtrReturn(piPrefix, VERR_INVALID_PARAMETER); 808 809 pcszAddr = RTStrStripL(pcszAddr); 810 rc = RTNetStrToIPv6AddrEx(pcszAddr, &Addr, &pszNext); 811 if (RT_FAILURE(rc)) 812 return rc; 813 814 /* 815 * If the prefix is missing, treat is as exact (/128) address 816 * specification. 817 */ 818 if (*pszNext == '\0' || rc == VWRN_TRAILING_SPACES) 819 { 820 *pAddr = Addr; 821 *piPrefix = 128; 822 return VINF_SUCCESS; 823 } 824 825 if (*pszNext != '/') 826 return VERR_INVALID_PARAMETER; 827 828 ++pszNext; 829 rc = RTStrToUInt8Ex(pszNext, &pszNext, 10, &u8Prefix); 830 if (RT_FAILURE(rc) || rc == VWRN_TRAILING_CHARS) 831 return VERR_INVALID_PARAMETER; 832 833 if (u8Prefix > 128) 834 return VERR_INVALID_PARAMETER; 835 836 *pAddr = Addr; 837 *piPrefix = u8Prefix; 838 return VINF_SUCCESS; 839 } 840 841 bool NetworkAddress::isValidString(const char *pcszNetwork) 842 { 843 RTNETADDRIPV4 addrv4; 844 RTNETADDRIPV6 addrv6; 845 int prefix; 846 int rc = RTNetStrToIPv4CidrWithZeroPrefixAllowed(pcszNetwork, &addrv4, &prefix); 847 if (RT_SUCCESS(rc)) 848 return true; 849 rc = RTNetStrToIPv6CidrWithZeroPrefixAllowed(pcszNetwork, &addrv6, &prefix); 850 return RT_SUCCESS(rc); 851 } 852 853 class NetworkAddressIPv4 : public NetworkAddress 854 { 855 public: 856 NetworkAddressIPv4(const char *pcszIpAddress, const char *pcszNetMask = VBOXNET_DEFAULT_IPV4MASK); 857 virtual bool matches(const char *pcszNetwork); 858 virtual const char *defaultNetwork() { return "192.168.56.1/21"; }; /* Matches defaults in VBox/Main/include/netif.h, see @bugref{10077}. */ 859 860 private: 861 RTNETADDRIPV4 m_address; 862 int m_prefix; 863 }; 864 865 NetworkAddressIPv4::NetworkAddressIPv4(const char *pcszIpAddress, const char *pcszNetMask) 866 { 867 int rc = RTNetStrToIPv4Addr(pcszIpAddress, &m_address); 868 if (RT_SUCCESS(rc)) 869 { 870 RTNETADDRIPV4 mask; 871 rc = RTNetStrToIPv4Addr(pcszNetMask, &mask); 872 if (RT_FAILURE(rc)) 873 m_fValid = false; 874 else 875 rc = RTNetMaskToPrefixIPv4(&mask, &m_prefix); 876 } 877 #if 0 /* cmd.set() does not support CIDR syntax */ 878 else 879 rc = RTNetStrToIPv4Cidr(pcszIpAddress, &m_address, &m_prefix); 880 #endif 881 m_fValid = RT_SUCCESS(rc); 882 } 883 884 bool NetworkAddressIPv4::matches(const char *pcszNetwork) 885 { 886 RTNETADDRIPV4 allowedNet, allowedMask; 887 int allowedPrefix; 888 int rc = RTNetStrToIPv4CidrWithZeroPrefixAllowed(pcszNetwork, &allowedNet, &allowedPrefix); 889 if (RT_SUCCESS(rc)) 890 rc = RTNetPrefixToMaskIPv4(allowedPrefix, &allowedMask); 891 if (RT_FAILURE(rc)) 892 return false; 893 return m_prefix >= allowedPrefix && (m_address.au32[0] & allowedMask.au32[0]) == (allowedNet.au32[0] & allowedMask.au32[0]); 894 } 895 896 class NetworkAddressIPv6 : public NetworkAddress 897 { 898 public: 899 NetworkAddressIPv6(const char *pcszIpAddress); 900 virtual bool matches(const char *pcszNetwork); 901 virtual const char *defaultNetwork() { return "FE80::/10"; }; 902 private: 903 RTNETADDRIPV6 m_address; 904 int m_prefix; 905 }; 906 907 NetworkAddressIPv6::NetworkAddressIPv6(const char *pcszIpAddress) 908 { 909 int rc = RTNetStrToIPv6Cidr(pcszIpAddress, &m_address, &m_prefix); 910 m_fValid = RT_SUCCESS(rc); 911 } 912 913 bool NetworkAddressIPv6::matches(const char *pcszNetwork) 914 { 915 RTNETADDRIPV6 allowedNet, allowedMask; 916 int allowedPrefix; 917 int rc = RTNetStrToIPv6CidrWithZeroPrefixAllowed(pcszNetwork, &allowedNet, &allowedPrefix); 918 if (RT_SUCCESS(rc)) 919 rc = RTNetPrefixToMaskIPv6(allowedPrefix, &allowedMask); 920 if (RT_FAILURE(rc)) 921 return false; 922 RTUINT128U u128Provided, u128Allowed; 923 return m_prefix >= allowedPrefix 924 && RTUInt128Compare(RTUInt128And(&u128Provided, &m_address, &allowedMask), RTUInt128And(&u128Allowed, &allowedNet, &allowedMask)) == 0; 925 } 926 927 928 class GlobalNetworkPermissionsConfig 929 { 930 public: 931 bool forbids(const char *pcszIpAddress); /* address or address with mask in cidr */ 932 bool forbids(const char *pcszIpAddress, const char *pcszNetMask); 933 934 private: 935 bool forbids(NetworkAddress& address); 936 }; 937 938 bool GlobalNetworkPermissionsConfig::forbids(const char *pcszIpAddress) 939 { 940 NetworkAddressIPv6 addrv6(pcszIpAddress); 941 942 if (addrv6.isValid()) 943 return forbids(addrv6); 944 945 NetworkAddressIPv4 addrv4(pcszIpAddress); 946 947 if (addrv4.isValid()) 948 return forbids(addrv4); 949 950 fprintf(stderr, "Error: invalid address '%s'\n", pcszIpAddress); 951 return true; 952 } 953 954 bool GlobalNetworkPermissionsConfig::forbids(const char *pcszIpAddress, const char *pcszNetMask) 955 { 956 NetworkAddressIPv4 addrv4(pcszIpAddress, pcszNetMask); 957 958 if (addrv4.isValid()) 959 return forbids(addrv4); 960 961 fprintf(stderr, "Error: invalid address '%s' with mask '%s'\n", pcszIpAddress, pcszNetMask); 962 return true; 963 } 964 965 bool GlobalNetworkPermissionsConfig::forbids(NetworkAddress& address) 966 { 967 FILE *fp = fopen(VBOX_GLOBAL_NETWORK_CONFIG_PATH, "r"); 968 if (!fp) 969 { 970 if (verbose) 971 fprintf(stderr, "Info: matching against default '%s' => %s\n", address.defaultNetwork(), 972 address.matches(address.defaultNetwork()) ? "MATCH" : "no match"); 973 return !address.matches(address.defaultNetwork()); 974 } 975 976 char *pszToken, szLine[1024]; 977 for (int line = 1; fgets(szLine, sizeof(szLine), fp); ++line) 978 { 979 /* Skip anything except '*' lines */ 980 if (strcmp("*", strtok(szLine, " \t\n"))) 981 continue; 982 /* Match the specified address against each network */ 983 while ((pszToken = strtok(NULL, " \t\n")) != NULL) 984 { 985 if (!address.isValidString(pszToken)) 986 { 987 fprintf(stderr, "Warning: %s(%d) invalid network '%s'\n", VBOX_GLOBAL_NETWORK_CONFIG_PATH, line, pszToken); 988 continue; 989 } 990 if (verbose) 991 fprintf(stderr, "Info: %s(%d) matching against '%s' => %s\n", VBOX_GLOBAL_NETWORK_CONFIG_PATH, line, pszToken, 992 address.matches(pszToken) ? "MATCH" : "no match"); 993 if (address.matches(pszToken)) 994 return false; 995 } 996 } 997 fclose(fp); 998 return true; 999 } 1000 1001 1002 /********************************************************************************************************************************* 731 1003 * Main logic, argument parsing, etc. * 732 1004 *********************************************************************************************************************************/ … … 756 1028 { 757 1029 char szAdapterName[VBOXNETADP_MAX_NAME_LEN]; 758 int rc; 1030 int rc = RTR3InitExe(argc, &argv, 0 /*fFlags*/); 1031 if (RT_FAILURE(rc)) 1032 return RTMsgInitFailure(rc); 1033 759 1034 760 1035 AddressCommand& cmd = chooseAddressCommand(); … … 899 1174 const char * const keyword = argv[2]; 900 1175 1176 GlobalNetworkPermissionsConfig config; 901 1177 902 1178 /* … … 905 1181 if (keyword == NULL) 906 1182 { 1183 if (config.forbids(addr)) 1184 { 1185 fprintf(stderr, "Error: permission denied\n"); 1186 return -VERR_ACCESS_DENIED; 1187 } 1188 907 1189 return cmd.set(ifname, addr); 908 1190 } … … 917 1199 918 1200 const char * const mask = argv[3]; 1201 if (config.forbids(addr, mask)) 1202 { 1203 fprintf(stderr, "Error: permission denied\n"); 1204 return -VERR_ACCESS_DENIED; 1205 } 1206 919 1207 return cmd.set(ifname, addr, mask); 920 1208 } -
trunk/src/VBox/Main/src-server/HostNetworkInterfaceImpl.cpp
r91503 r91769 603 603 { 604 604 LogRel(("Failed to EnableStaticIpConfig with rc=%Rrc\n", rc)); 605 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL;605 return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : (rc == VERR_ACCESS_DENIED ? E_ACCESSDENIED : E_FAIL); 606 606 } 607 607 -
trunk/src/VBox/Main/src-server/generic/NetIf-generic.cpp
r91503 r91769 81 81 LogRel(("NetIfAdpCtl: failed to create process for %s: iStats=%d enmReason=%d\n", 82 82 szAdpCtl, Status.iStatus, Status.enmReason)); 83 rc = VERR_GENERAL_FAILURE;83 rc = -Status.iStatus; 84 84 } 85 85 }
Note:
See TracChangeset
for help on using the changeset viewer.