├── Makefile ├── kv_cfg.ini ├── kv_client.h ├── kv_cfg.h ├── README.md ├── kv_serv.h ├── kv_lib.h ├── kv_cfg.c ├── kv_lib.c ├── kv_main.c ├── kv_serv.c ├── kv_client.c └── LICENSE /Makefile: -------------------------------------------------------------------------------- 1 | # KidVPN Makefile for linux 2 | # Author: hanhui (hanhui@acoinfo.com) 3 | 4 | %.o: %.c 5 | gcc -DUSE_OPENSSL=1 -c $< -o $@ 6 | 7 | kidvpn: kv_cfg.o kv_lib.o kv_client.o kv_serv.o kv_main.o 8 | gcc -o kidvpn kv_cfg.o kv_lib.o kv_client.o kv_serv.o kv_main.o -lpthread -lcrypto 9 | 10 | all: kidvpn 11 | 12 | .PHONY: clean 13 | clean: 14 | -rm -rf kidvpn *.o 15 | 16 | # end 17 | -------------------------------------------------------------------------------- /kv_cfg.ini: -------------------------------------------------------------------------------- 1 | [server_0] 2 | mode=server # Run as server mode 3 | key_file=serv.key # AES key file 4 | vnd_id=0 # Virtual network device ID (For SylixOS) 5 | tap_name=tap0 # Virtual network device name (For Linux & Windows) 6 | mtu=1464 # 1280 ~ 1472 (Optional default: 1464) 7 | local_ip=192.168.0.1 # Local IP address in this system 8 | port=10088 # Local port (Optional default: 10088) 9 | 10 | [client_0] 11 | mode=client # Run as client mode 12 | key_file=cli.key # AES key file 13 | vnd_id=0 # Virtual network device ID (For SylixOS) 14 | tap_name=tap0 # Virtual network device name (For Linux & Windows) 15 | mtu=1464 # 1280 ~ 1472 must same as server (Optional default: 1464) 16 | server=123.123.123.123 # KidVPN Server address 17 | port=10088 # Server port (Optional default: 10088) 18 | hole_punching=0 # UDP hole punching enable (Optional default: 0) -------------------------------------------------------------------------------- /kv_client.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * KidVPN client. 4 | * Verification using sylixos(tm) real-time operating system 5 | */ 6 | 7 | /* 8 | * Copyright (c) 2006-2018 SylixOS Group. 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. The name of the author may not be used to endorse or promote products 20 | * derived from this software without specific prior written permission. 21 | * 4. This code has been or is applying for intellectual property protection 22 | * and can only be used with acoinfo software products. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 25 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 27 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 29 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 32 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 33 | * OF SUCH DAMAGE. 34 | * 35 | * Author: Han.hui 36 | * 37 | */ 38 | 39 | #ifndef __KV_CLIENT_H 40 | #define __KV_CLIENT_H 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | /* KidVPN client start */ 47 | int kv_cli_start(int vnd_id, const char *tap_name, const unsigned char *key, unsigned int keybits, 48 | const char *server, unsigned int port, int mtu, int hole_punching); 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif /* __KV_CLIENT_H */ 55 | /* 56 | * end 57 | */ 58 | -------------------------------------------------------------------------------- /kv_cfg.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * KidVPN configure. 4 | * Verification using sylixos(tm) real-time operating system 5 | */ 6 | 7 | /* 8 | * Copyright (c) 2006-2018 SylixOS Group. 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. The name of the author may not be used to endorse or promote products 20 | * derived from this software without specific prior written permission. 21 | * 4. This code has been or is applying for intellectual property protection 22 | * and can only be used with acoinfo software products. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 25 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 27 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 29 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 32 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 33 | * OF SUCH DAMAGE. 34 | * 35 | * Author: Han.hui 36 | * 37 | */ 38 | 39 | #ifndef __KV_CFG_H 40 | #define __KV_CFG_H 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | /* KidVPN config file load */ 47 | void *kv_cfg_load(const char *file, const char *sector); 48 | void kv_cfg_unload(void *loadret); 49 | int kv_cfg_getint(void *loadret, const char *keyword, int def); 50 | const char *kv_cfg_getstring(void *loadret, const char *keyword, const char *def); 51 | int kv_cfg_getboolean(void *loadret, const char *keyword, int def); 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | 57 | #endif /* __KV_CFG_H */ 58 | /* 59 | * end 60 | */ 61 | 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KidVPN 2 | The world's smallest VPN server and client (For SylixOS and Linux). 3 | 4 | ## Configure File 5 | * Configure file is a ini format: 6 | > 7 | |keywords| description | 8 | |:----:|:----| 9 | |**mode**|KidVPN run mode, `'server'` or `'client'`| 10 | |**key_file**|KidVPN AES Key file| 11 | |**iv_file**|Cipher initial vector (Optional default use ECB)| 12 | |**vnd_id**|Virtual network device ID (Only for SylixOS)| 13 | |**tap_name**|Virtual network device name (Only for Linux)| 14 | |**mtu**|`1280` ~ `1472` (Optional default: `1464`)| 15 | |**local_ip**|Local IP address (Only for Server)| 16 | |**server**|Server IP address (Only for Client)| 17 | |**port**|Local port (Optional default: `10088`)| 18 | |**hole_punching**|UDP Hole punching (Optional default: `0`)| 19 | 20 | \* *If too many client in one VPN net you can use UDP hole punching to reduce server forwarding pressure.* 21 | 22 | * Server configure like this: 23 | ``` ini 24 | [server_0] 25 | mode=server 26 | key_file=serv.key 27 | iv_file=serv.iv 28 | vnd_id=0 29 | tap_name=tap0 30 | mtu=1464 31 | local_ip=192.168.0.1 32 | port=10088 33 | ``` 34 | 35 | * Client configure like this: 36 | ``` ini 37 | [client_0] 38 | mode=client 39 | key_file=cli.key 40 | iv_file=cli.iv 41 | vnd_id=0 42 | tap_name=tap0 43 | mtu=1464 44 | server=123.123.123.123 45 | port=10088 46 | ``` 47 | 48 | \* KidVPN daemon allow dynamic update of IV parameters using `SIGUSR1` signal.* 49 | 50 | ## For SylixOS 51 | * Step 1: Add vnd interface parameter in **/etc/ifparam.ini** 52 | ``` ini 53 | [vnd-X] 54 | # X is a number of vnd ID) 55 | enable=1 56 | # Enable(up) this interface 57 | ipaddr=x.x.x.x 58 | # Virtual network ip address 59 | netmask=x.x.x.x 60 | # Virtual network netmask 61 | mac=xx:xx:xx:xx:xx:xx 62 | # Virtual network MAC address, If not, the system will use random numbers 63 | ``` 64 | 65 | * Step 2: Use **'vnd'** command add a virtual net device. 66 | ``` sh 67 | vnd add X 68 | # X is a number of vnd ID 69 | ``` 70 | 71 | * Step 3: Use **'kidvpn'** to create a VPN connect. 72 | ``` sh 73 | kidvpn x.ini sector password 74 | # 'x.ini' is vpn config file, 'sector' is ini sector which we will use, 'password' is password 75 | ``` 76 | 77 | * Step 4: Use **'route'** command add some route entry to system, make route rules. 78 | 79 | ## For Linux 80 | * Prepare for work: 81 | ``` sh 82 | sudo apt-get install openssl 83 | # Install OpenSSL library 84 | 85 | sudo apt-get install libssl-dev 86 | # Install OpenSSL develop library 87 | 88 | make 89 | # Build kidvpn target 90 | ``` 91 | 92 | * Step 1: Add tap interface 93 | ``` sh 94 | sudo tunctl -t tapX -u root 95 | # X is tap number 96 | 97 | sudo ifconfig tapX up 98 | # Enable tapX network 99 | ``` 100 | 101 | * Step 2: Use **'ifconfig'** command set tapX address 102 | ``` sh 103 | ifconfig tapX inet x.x.x.x netmask x.x.x.x 104 | ``` 105 | 106 | * Step 3: Use **'kidvpn'** to create a VPN connect. 107 | ``` sh 108 | sudo ./kidvpn x.ini sector password 109 | # 'x.ini' is vpn config file, 'sector' is ini sector which we will use, 'password' is password 110 | ``` 111 | 112 | * Step 4: Use **'route'** command add some route entry to system, make route rules. 113 | 114 | Enjoy yourself \^\_\^ 115 | -------------------------------------------------------------------------------- /kv_serv.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * KidVPN server. 4 | * Verification using sylixos(tm) real-time operating system 5 | */ 6 | 7 | /* 8 | * Copyright (c) 2006-2018 SylixOS Group. 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. The name of the author may not be used to endorse or promote products 20 | * derived from this software without specific prior written permission. 21 | * 4. This code has been or is applying for intellectual property protection 22 | * and can only be used with acoinfo software products. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 25 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 27 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 29 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 32 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 33 | * OF SUCH DAMAGE. 34 | * 35 | * Author: Han.hui 36 | * 37 | */ 38 | 39 | #ifndef __KV_SERV_H 40 | #define __KV_SERV_H 41 | 42 | #include 43 | 44 | #ifdef __cplusplus 45 | extern "C" { 46 | #endif 47 | 48 | /* server port */ 49 | #define KV_SERV_PORT 10088 50 | 51 | /* packet aligned */ 52 | #define KV_PACK_ALIGN 4 53 | 54 | /* KidVPN magic */ 55 | #define KV_CMD_MAGIC0 0x35 56 | #define KV_CMD_MAGIC1 0x22 57 | #define KV_CMD_MAGIC2 0xf1 58 | #define KV_CMD_MAGIC3 0xc2 59 | 60 | #if BYTE_ORDER == LITTLE_ENDIAN 61 | #define KV_CMD_MAGIC 0xc2f12235 62 | #else 63 | #define KV_CMD_MAGIC 0x3522f1c2 64 | #endif 65 | 66 | /* control command */ 67 | #define KV_CMD_HELLO 0 /* Client to server say hello */ 68 | #define KV_CMD_WELCOME 1 /* Server to client say welcome */ 69 | #define KV_CMD_BYE 2 /* Client to server say goodbye */ 70 | #define KV_CMD_CQUERY 3 /* Client to server query another client address */ 71 | #define KV_CMD_CRESPOND 4 /* Server to client respond client query */ 72 | #define KV_CMD_HPQUERY 5 /* Client to client query hole punching */ 73 | #define KV_CMD_HPRESPOND 6 /* Client to client respond hole punching query */ 74 | #define KV_CMD_ERR 255 75 | 76 | /* error */ 77 | #define KV_ERR_NONE 0 78 | #define KV_ERR_MTU 1 79 | 80 | /* INPUT packet */ 81 | struct kv_input_hdr { 82 | UINT8 cmd; 83 | } __attribute__((packed)); 84 | 85 | /* HELLO packet */ 86 | struct kv_hello_hdr { 87 | UINT8 cmd; 88 | UINT8 cmd_len; 89 | UINT8 hwaddr[ETH_ALEN]; 90 | UINT32 magic; 91 | UINT32 snum; 92 | UINT16 mtu; 93 | UINT8 pad[KV_AES_BLK_LEN]; /* for aes encode decode */ 94 | } __attribute__((packed)); 95 | 96 | #define KV_HELLO_LEN 18 97 | 98 | /* WELCOME packet */ 99 | struct kv_welcome_hdr { 100 | UINT8 cmd; 101 | UINT8 cmd_len; 102 | UINT8 hwaddr[ETH_ALEN]; 103 | UINT32 magic; 104 | UINT32 snum; 105 | UINT8 pad[KV_AES_BLK_LEN]; /* for aes encode decode */ 106 | } __attribute__((packed)); 107 | 108 | #define KV_WELCOME_LEN 16 109 | 110 | /* BYE packet */ 111 | struct kv_bye_hdr { 112 | UINT8 cmd; 113 | UINT8 cmd_len; 114 | UINT8 pad[2]; 115 | UINT8 magic[4]; 116 | UINT8 pad2[16]; /* for aes encode decode */ 117 | } __attribute__((packed)); 118 | 119 | #define KV_BYE_LEN 8 120 | 121 | /* CQUERY packet */ 122 | struct kv_cquery_hdr { 123 | UINT8 cmd; 124 | UINT8 cmd_len; 125 | UINT8 hwaddr[ETH_ALEN]; 126 | UINT32 magic; 127 | UINT8 pad[KV_AES_BLK_LEN]; /* for aes encode decode */ 128 | } __attribute__((packed)); 129 | 130 | #define KV_CQUERY_LEN 12 131 | 132 | /* CRESPOND packet */ 133 | struct kv_crespond_hdr { 134 | UINT8 cmd; 135 | UINT8 cmd_len; 136 | UINT8 hwaddr[ETH_ALEN]; 137 | UINT32 magic; 138 | UINT32 cliaddr; 139 | UINT16 cliport; 140 | UINT8 pad[KV_AES_BLK_LEN]; /* for aes encode decode */ 141 | } __attribute__((packed)); 142 | 143 | #define KV_CRESPOND_LEN 18 144 | 145 | /* HPQUERY packet */ 146 | struct kv_hpquery_hdr { 147 | UINT8 cmd; 148 | UINT8 cmd_len; 149 | UINT8 hwaddr[ETH_ALEN]; 150 | UINT32 magic; 151 | UINT8 pad[KV_AES_BLK_LEN]; /* for aes encode decode */ 152 | } __attribute__((packed)); 153 | 154 | #define KV_HPQUERY_LEN 12 155 | 156 | /* HPRESPOND packet */ 157 | struct kv_hprespond_hdr { 158 | UINT8 cmd; 159 | UINT8 cmd_len; 160 | UINT8 hwaddr[ETH_ALEN]; 161 | UINT32 magic; 162 | UINT8 pad[KV_AES_BLK_LEN]; /* for aes encode decode */ 163 | } __attribute__((packed)); 164 | 165 | #define KV_HPRESPOND_LEN 12 166 | 167 | /* ERR packet */ 168 | struct kv_err_hdr { 169 | UINT8 cmd; 170 | UINT8 cmd_len; 171 | UINT8 pad[2]; /* not compatible with 0.9.1 and earlier */ 172 | UINT32 magic; 173 | UINT16 err; 174 | UINT16 code; 175 | UINT8 pad2[KV_AES_BLK_LEN]; /* for aes encode decode */ 176 | } __attribute__((packed)); 177 | 178 | #define KV_ERR_LEN 12 179 | 180 | /* KidVPN server start */ 181 | int kv_serv_start(int vnd_id, const char *tap_name, const unsigned char *key, unsigned int keybits, 182 | const char *local, unsigned int port, int mtu); 183 | 184 | #ifdef __cplusplus 185 | } 186 | #endif 187 | 188 | #endif /* __KV_SERV_H */ 189 | /* 190 | * end 191 | */ 192 | -------------------------------------------------------------------------------- /kv_lib.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * KidVPN library. 4 | * Verification using sylixos(tm) real-time operating system 5 | */ 6 | 7 | /* 8 | * Copyright (c) 2006-2018 SylixOS Group. 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. The name of the author may not be used to endorse or promote products 20 | * derived from this software without specific prior written permission. 21 | * 4. This code has been or is applying for intellectual property protection 22 | * and can only be used with acoinfo software products. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 25 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 27 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 29 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 32 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 33 | * OF SUCH DAMAGE. 34 | * 35 | * Author: Han.hui 36 | * 37 | */ 38 | 39 | #ifndef __KV_LIB_H 40 | #define __KV_LIB_H 41 | 42 | #define _GNU_SOURCE /* need some *np api */ 43 | 44 | #ifndef SYLIXOS 45 | typedef unsigned char UINT8; 46 | typedef unsigned short UINT16; 47 | typedef unsigned int UINT32; 48 | #endif /* !SYLIXOS */ 49 | 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | 64 | #ifdef SYLIXOS 65 | #include 66 | #include 67 | #else /* SYLIXOS */ 68 | #include 69 | #include 70 | #endif /* LINUX */ 71 | 72 | #ifdef USE_OPENSSL 73 | #include 74 | #include 75 | #else /* USE_OPENSSL */ 76 | #include 77 | #include 78 | #endif /* !USE_OPENSSL */ 79 | 80 | #ifdef __cplusplus 81 | extern "C" { 82 | #endif 83 | 84 | /* Voluntarily quit */ 85 | #ifndef KV_VOLUNTARILY_QUIT 86 | #ifdef SYLIXOS 87 | #define KV_VOLUNTARILY_QUIT 1 88 | #else 89 | #define KV_VOLUNTARILY_QUIT 0 90 | #endif 91 | #endif 92 | 93 | #if KV_VOLUNTARILY_QUIT 94 | #include 95 | #endif 96 | 97 | /* ROUND UP */ 98 | #ifndef ROUND_UP 99 | #define ROUND_UP(x, align) (size_t)(((size_t)(x) + (align - 1)) & ~(align - 1)) 100 | #endif 101 | 102 | /* AES block length */ 103 | #define KV_AES_BLK_LEN 16 104 | #define KV_AES_BLK_SHIFT 4 105 | 106 | /* Init vector length */ 107 | #define KV_CIPHER_IV_LEN 16 108 | 109 | /* KidVPN MTU (Try not to appear IP fragment) */ 110 | #define KV_VND_MIN_MTU 1280 111 | #define KV_VND_MAX_MTU (ETH_DATA_LEN - 28) /* ETH_DATA_LEN - IP_HLEN - UDP_HLEN */ 112 | #define KV_VND_DEF_MTU (KV_VND_MAX_MTU - 8) /* KV_VND_MAX_MTU - PPPoE Header length */ 113 | 114 | #define KV_VND_FRAME_LEN(mtu) (mtu + 18) /* mtu + ETH_HLEN + VLAN_HLEN */ 115 | #define KV_VND_FRAME_MAX KV_VND_FRAME_LEN(KV_VND_MAX_MTU) 116 | #define KV_VND_FRAME_BSIZE (KV_VND_FRAME_MAX + KV_AES_BLK_LEN) /* KV_VND_FRAME_MAX + AES pad */ 117 | 118 | /* hello period (s) */ 119 | #define KV_CLI_HELLO_TIMEOUT 20 120 | #define KV_CLI_HELLO_PERIOD 5 121 | 122 | /* hole punching alive (s) */ 123 | #define KV_CLI_HOLE_PUNCHING_ALIVE 60 124 | 125 | /* packet mac address */ 126 | #define KV_PKT_MAC_DEST(packet) &packet[0] 127 | #define KV_PKT_MAC_SRC(packet) &packet[6] 128 | #define KV_PKY_MAC_BMC(packet) (packet[0] & 1) /* broadcast or multicast */ 129 | 130 | /* KidVPN core lib functions */ 131 | int kv_lib_init(int vnd_id, const char *tap_name, int *s_fd, int *v_fd, UINT8 hwaddr[], int mtu); 132 | void kv_lib_deinit(int s_fd, int v_fd); 133 | int kv_lib_setmtu(int s_fd, int mtu); 134 | 135 | int kv_lib_update_iv(const char *iv_file); 136 | #ifdef USE_OPENSSL 137 | void kv_lib_encode(UINT8 *out, UINT8 *in, int len, int *rlen, AES_KEY *aes_en); 138 | void kv_lib_decode(UINT8 *out, UINT8 *in, int len, int *rlen, AES_KEY *aes_de); 139 | 140 | #else /* USE_OPENSSL */ 141 | void kv_lib_encode(UINT8 *out, UINT8 *in, int len, int *rlen, mbedtls_aes_context *aes_en); 142 | void kv_lib_decode(UINT8 *out, UINT8 *in, int len, int *rlen, mbedtls_aes_context *aes_de); 143 | #endif /* !USE_OPENSSL */ 144 | 145 | int kv_lib_addr_is_same(struct sockaddr_in *addr1, struct sockaddr_in *addr2); 146 | 147 | /* KidVPN client node */ 148 | struct kv_cli_node { 149 | struct kv_cli_node *next; 150 | struct kv_cli_node *prev; 151 | struct sockaddr_in addr; 152 | UINT8 hwaddr[ETH_ALEN]; 153 | int alive; 154 | }; 155 | 156 | /* KidVPN client node hash table */ 157 | #define KV_CLI_HASH_SIZE 256 158 | #define KV_CLI_HASH_MASK (KV_CLI_HASH_SIZE - 1) 159 | 160 | /* KidVPN client node management */ 161 | int kv_lib_cli_hash(UINT8 hwaddr[]); 162 | void kv_lib_cli_add(struct kv_cli_node *cli, struct kv_cli_node *header[]); 163 | void kv_lib_cli_delete(struct kv_cli_node *cli, struct kv_cli_node *header[]); 164 | struct kv_cli_node *kv_lib_cli_find(UINT8 hwaddr[], struct kv_cli_node *header[]); 165 | 166 | /* Voluntarily quit */ 167 | #if KV_VOLUNTARILY_QUIT 168 | int kv_lib_signalfd(void); 169 | #endif 170 | 171 | #ifdef __cplusplus 172 | } 173 | #endif 174 | 175 | #endif /* __KV_LIB_H */ 176 | /* 177 | * end 178 | */ 179 | -------------------------------------------------------------------------------- /kv_cfg.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * KidVPN configure. 4 | * Verification using sylixos(tm) real-time operating system 5 | */ 6 | 7 | /* 8 | * Copyright (c) 2006-2018 SylixOS Group. 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. The name of the author may not be used to endorse or promote products 20 | * derived from this software without specific prior written permission. 21 | * 4. This code has been or is applying for intellectual property protection 22 | * and can only be used with acoinfo software products. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 25 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 27 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 29 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 32 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 33 | * OF SUCH DAMAGE. 34 | * 35 | * Author: Han.hui 36 | * 37 | */ 38 | 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | #ifndef PX_EOS 45 | #define PX_EOS '\0' 46 | #endif 47 | 48 | /* 49 | * ini file key=value 50 | */ 51 | typedef struct ini_key_value { 52 | struct ini_key_value *next; 53 | char *keyword; 54 | char *value; 55 | } ini_key_value_t; 56 | 57 | /* 58 | * ini file [sector] 59 | */ 60 | typedef struct { 61 | struct ini_key_value *list; 62 | } ini_sector_t; 63 | 64 | /* 65 | * load a sector 66 | */ 67 | static void ini_load_sector (ini_sector_t *sec, FILE *fp) 68 | { 69 | #define INI_BUF_SZ 256 70 | 71 | #define IS_WHITE(c) (c == ' ' || c == '\t' || c == '\r' || c == '\n') 72 | #define IS_END(c) (c == PX_EOS) 73 | #define SKIP_WHITE(str) while (IS_WHITE(*str)) { \ 74 | str++; \ 75 | } 76 | #define NEXT_WHITE(str) while (!IS_WHITE(*str) && !IS_END(*str)) { \ 77 | str++; \ 78 | } 79 | 80 | ini_key_value_t *pinikey; 81 | 82 | char buf[INI_BUF_SZ]; 83 | char *line; 84 | char *end; 85 | char *equ; 86 | 87 | char *key; 88 | size_t key_len; 89 | char *value; 90 | size_t value_len; 91 | 92 | for (;;) { 93 | line = fgets(buf, INI_BUF_SZ, fp); 94 | if (!line) { 95 | break; 96 | } 97 | 98 | SKIP_WHITE(line); 99 | if (IS_END(*line) || (*line == ';') || (*line == '#')) { 100 | continue; 101 | } 102 | 103 | if (*line == '[') { 104 | break; 105 | } 106 | 107 | equ = strchr(line, '='); 108 | if (!equ) { 109 | continue; 110 | } 111 | *equ = PX_EOS; 112 | 113 | end = line; 114 | NEXT_WHITE(end); 115 | *end = PX_EOS; 116 | key = line; 117 | 118 | line = ++equ; 119 | SKIP_WHITE(line); 120 | end = line; 121 | NEXT_WHITE(end); 122 | *end = PX_EOS; 123 | value = line; 124 | 125 | key_len = strlen(key); 126 | value_len = strlen(value); 127 | 128 | pinikey = (ini_key_value_t *)malloc(sizeof(ini_key_value_t) + key_len + value_len + 2); 129 | if (!pinikey) { 130 | fprintf(stderr, "[KidVPN] malloc error(%d): %s\n", errno, strerror(errno)); 131 | break; 132 | } 133 | 134 | pinikey->keyword = (char *)pinikey + sizeof(ini_key_value_t); 135 | strcpy(pinikey->keyword, key); 136 | 137 | pinikey->value = pinikey->keyword + key_len + 1; 138 | strcpy(pinikey->value, value); 139 | 140 | pinikey->next = sec->list; 141 | sec->list = pinikey; 142 | } 143 | } 144 | 145 | /* 146 | * load ini file 147 | */ 148 | static ini_sector_t *ini_load_file (const char *file, const char *sector) 149 | { 150 | ini_sector_t *pinisec; 151 | FILE *fp; 152 | char sec[INI_BUF_SZ]; 153 | char buf[INI_BUF_SZ]; 154 | char *line; 155 | char *end; 156 | 157 | if (strlen(sector) > (INI_BUF_SZ - 3)) { 158 | return (NULL); 159 | } 160 | 161 | pinisec = (ini_sector_t *)malloc(sizeof(ini_sector_t)); 162 | if (!pinisec) { 163 | return (NULL); 164 | } 165 | bzero(pinisec, sizeof(ini_sector_t)); 166 | 167 | fp = fopen(file, "r"); 168 | if (!fp) { 169 | free(pinisec); 170 | return (NULL); 171 | } 172 | 173 | snprintf(sec, INI_BUF_SZ, "[%s]", sector); 174 | 175 | for (;;) { 176 | line = fgets(buf, INI_BUF_SZ, fp); 177 | if (!line) { 178 | goto error; 179 | } 180 | 181 | SKIP_WHITE(line); 182 | if (IS_END(*line) || (*line == ';') || (*line == '#')) { 183 | continue; 184 | } 185 | 186 | end = line; 187 | NEXT_WHITE(end); 188 | *end = PX_EOS; 189 | 190 | if (strcmp(sec, line)) { 191 | continue; 192 | } else { 193 | break; 194 | } 195 | } 196 | 197 | ini_load_sector(pinisec, fp); 198 | fclose(fp); 199 | 200 | return (pinisec); 201 | 202 | error: 203 | fclose(fp); 204 | free(pinisec); 205 | return (NULL); 206 | } 207 | 208 | /* 209 | * free sector 210 | */ 211 | static void ini_unload_sector (ini_sector_t *pinisec) 212 | { 213 | ini_key_value_t *pinikey; 214 | 215 | while (pinisec->list) { 216 | pinikey = pinisec->list; 217 | pinisec->list = pinikey->next; 218 | free(pinikey); 219 | } 220 | 221 | free(pinisec); 222 | } 223 | 224 | /* 225 | * get a integer 226 | */ 227 | static int ini_get_integer (ini_sector_t *pinisec, const char *keyword, int def) 228 | { 229 | ini_key_value_t *pinikey; 230 | int ret = def; 231 | 232 | for (pinikey = pinisec->list; pinikey != NULL; pinikey = pinikey->next) { 233 | if (strcmp(pinikey->keyword, keyword) == 0) { 234 | ret = atoi(pinikey->value); 235 | break; 236 | } 237 | } 238 | 239 | return (ret); 240 | } 241 | 242 | /* 243 | * get a string 244 | */ 245 | static const char *ini_get_string (ini_sector_t *pinisec, const char *keyword, const char *def) 246 | { 247 | ini_key_value_t *pinikey; 248 | const char *ret = def; 249 | 250 | for (pinikey = pinisec->list; pinikey != NULL; pinikey = pinikey->next) { 251 | if (strcmp(pinikey->keyword, keyword) == 0) { 252 | ret = pinikey->value; 253 | break; 254 | } 255 | } 256 | 257 | return (ret); 258 | } 259 | 260 | /* 261 | * config load 262 | */ 263 | void *kv_cfg_load (const char *file, const char *sector) 264 | { 265 | ini_sector_t *pinisec; 266 | 267 | if (!file) { 268 | return (NULL); 269 | } 270 | 271 | pinisec = ini_load_file(file, sector); 272 | if (!pinisec) { 273 | fprintf(stderr, "[KidVPN] No configure for [%s] from %s\n", sector, file); 274 | return (NULL); 275 | } 276 | 277 | return ((void *)pinisec); 278 | } 279 | 280 | /* 281 | * config unload 282 | */ 283 | void kv_cfg_unload (void *loadret) 284 | { 285 | ini_sector_t *pinisec = (ini_sector_t *)loadret; 286 | 287 | if (!pinisec) { 288 | return; 289 | } 290 | 291 | ini_unload_sector(pinisec); 292 | } 293 | 294 | /* 295 | * config get integer 296 | */ 297 | int kv_cfg_getint (void *loadret, const char *keyword, int def) 298 | { 299 | ini_sector_t *pinisec = (ini_sector_t *)loadret; 300 | 301 | if (!pinisec || !keyword) { 302 | return (def); 303 | } 304 | 305 | return (ini_get_integer(pinisec, keyword, def)); 306 | } 307 | 308 | /* 309 | * config get string 310 | */ 311 | const char *kv_cfg_getstring (void *loadret, const char *keyword, const char *def) 312 | { 313 | ini_sector_t *pinisec = (ini_sector_t *)loadret; 314 | 315 | if (!pinisec || !keyword) { 316 | return (def); 317 | } 318 | 319 | return (ini_get_string(pinisec, keyword, def)); 320 | } 321 | 322 | /* 323 | * config get boolean 324 | */ 325 | int kv_cfg_getboolean (void *loadret, const char *keyword, int def) 326 | { 327 | ini_sector_t *pinisec = (ini_sector_t *)loadret; 328 | char *str; 329 | 330 | if (!pinisec || !keyword) { 331 | return (def); 332 | } 333 | 334 | str = (char *)ini_get_string(pinisec, keyword, def ? "true" : "false"); 335 | if (strcasecmp(str, "true") == 0 || strcasecmp(str, "yes") == 0) { 336 | return (1); 337 | } else { 338 | return (0); 339 | } 340 | } 341 | 342 | /* 343 | * end 344 | */ 345 | -------------------------------------------------------------------------------- /kv_lib.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * KidVPN library. 4 | * Verification using sylixos(tm) real-time operating system 5 | */ 6 | 7 | /* 8 | * Copyright (c) 2006-2018 SylixOS Group. 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. The name of the author may not be used to endorse or promote products 20 | * derived from this software without specific prior written permission. 21 | * 4. This code has been or is applying for intellectual property protection 22 | * and can only be used with acoinfo software products. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 25 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 27 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 29 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 32 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 33 | * OF SUCH DAMAGE. 34 | * 35 | * Author: Han.hui 36 | * 37 | */ 38 | 39 | #include "kv_lib.h" 40 | 41 | /* CBC enable */ 42 | int kv_cbc_en = 0; 43 | 44 | /* CBC iv */ 45 | static unsigned char kv_cbc_iv[KV_CIPHER_IV_LEN]; 46 | 47 | /* CBC iv file */ 48 | static char *kv_cbc_iv_file = NULL; 49 | 50 | /* vnd/tap if name */ 51 | static char kv_vnd_ifname[IFNAMSIZ]; 52 | 53 | /* 54 | * init vnd device 55 | */ 56 | int kv_lib_init (int vnd_id, const char *tap_name, int *s_fd, int *v_fd, UINT8 hwaddr[], int mtu) 57 | { 58 | int i, so_fd = -1, vnd_fd = -1; 59 | struct ifreq req; 60 | #ifdef SYLIXOS 61 | struct ifvnd vnd; 62 | #endif /* SYLIXOS */ 63 | 64 | so_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 65 | if (so_fd < 0) { 66 | fprintf(stderr, "[KidVPN] Can not open socket error(%d): %s\n", errno, strerror(errno)); 67 | goto error; 68 | } 69 | 70 | #ifdef SYLIXOS 71 | vnd_fd = open(IF_VND_PATH, O_RDWR); 72 | if (vnd_fd < 0) { 73 | fprintf(stderr, "[KidVPN] Can not open %s error(%d): %s\n", IF_VND_PATH, errno, strerror(errno)); 74 | goto error; 75 | } 76 | 77 | vnd.ifvnd_id = vnd_id; 78 | if (ioctl(vnd_fd, SIOCVNDSEL, &vnd)) { 79 | fprintf(stderr, "[KidVPN] Command 'SIOCVNDSEL' error(%d): %s\n", errno, strerror(errno)); 80 | goto error; 81 | } 82 | 83 | if (vnd.ifvnd_type != IF_VND_TYPE_ETHERNET) { 84 | fprintf(stderr, "[KidVPN] Virtual net device MUST a ethernet type.\n"); 85 | goto error; 86 | } 87 | 88 | strcpy(req.ifr_name, vnd.ifvnd_ifname); 89 | 90 | #else /* SYLIXOS */ 91 | vnd_fd = open("/dev/net/tun", O_RDWR); 92 | if (vnd_fd < 0) { 93 | fprintf(stderr, "[KidVPN] Can not open %s error(%d): %s\n", "/dev/net/tun", errno, strerror(errno)); 94 | goto error; 95 | } 96 | 97 | bzero(&req, sizeof(req)); 98 | if (tap_name && vnd_id < 0) { 99 | strncpy(req.ifr_name, tap_name, IFNAMSIZ); 100 | req.ifr_name[IFNAMSIZ - 1] = '\0'; 101 | } else { 102 | snprintf(req.ifr_name, IFNAMSIZ, "tap%d", vnd_id); 103 | } 104 | 105 | req.ifr_flags = IFF_TAP | IFF_NO_PI; 106 | if (ioctl(vnd_fd, TUNSETIFF, (void *)&req)) { 107 | fprintf(stderr, "[KidVPN] Command 'TUNSETIFF' error(%d): %s\n", errno, strerror(errno)); 108 | goto error; 109 | } 110 | #endif /* !SYLIXOS */ 111 | 112 | printf("[KidVPN] We use virtual net device: %s for VPN connect.\n", req.ifr_name); 113 | 114 | if (ioctl(so_fd, SIOCGIFHWADDR, &req)) { 115 | fprintf(stderr, "[KidVPN] Command 'SIOCGIFHWADDR' error(%d): %s\n", errno, strerror(errno)); 116 | goto error; 117 | } 118 | 119 | for (i = 0; i < ETH_ALEN; i++) { 120 | hwaddr[i] = req.ifr_hwaddr.sa_data[i]; 121 | } 122 | 123 | if ((hwaddr[0] == 0) && (hwaddr[1] == 0) && (hwaddr[2] == 0) && 124 | (hwaddr[3] == 0) && (hwaddr[4] == 0) && (hwaddr[5] == 0)) { 125 | fprintf(stderr, "[KidVPN] Virtual net device hwaddr error.\n"); 126 | goto error; 127 | } 128 | 129 | req.ifr_mtu = mtu; 130 | if (ioctl(so_fd, SIOCSIFMTU, &req)) { 131 | fprintf(stderr, "[KidVPN] Command 'SIOCSIFMTU' (%d) error(%d): %s\n", mtu, errno, strerror(errno)); 132 | goto error; 133 | } 134 | 135 | strcpy(kv_vnd_ifname, req.ifr_name); 136 | 137 | if (s_fd) { 138 | *s_fd = so_fd; 139 | } 140 | if (v_fd) { 141 | *v_fd = vnd_fd; 142 | } 143 | return (0); 144 | 145 | error: 146 | if (so_fd >= 0) { 147 | close(so_fd); 148 | } 149 | if (vnd_fd >= 0) { 150 | close(vnd_fd); 151 | } 152 | return (-1); 153 | } 154 | 155 | /* 156 | * deinit vnd device 157 | */ 158 | void kv_lib_deinit (int s_fd, int v_fd) 159 | { 160 | if (s_fd >= 0) { 161 | close(s_fd); 162 | } 163 | if (v_fd >= 0) { 164 | close(v_fd); 165 | } 166 | } 167 | 168 | /* 169 | * KidVPN set MTU 170 | */ 171 | int kv_lib_setmtu (int s_fd, int mtu) 172 | { 173 | struct ifreq req; 174 | 175 | strcpy(req.ifr_name, kv_vnd_ifname); 176 | 177 | if (ioctl(s_fd, SIOCGIFMTU, &req)) { 178 | fprintf(stderr, "[KidVPN] Command 'SIOCGIFMTU' (%d) error(%d): %s\n", mtu, errno, strerror(errno)); 179 | return (-1); 180 | } 181 | 182 | if (mtu == req.ifr_mtu) { 183 | return (0); 184 | } 185 | 186 | req.ifr_mtu = mtu; 187 | if (ioctl(s_fd, SIOCSIFMTU, &req)) { 188 | fprintf(stderr, "[KidVPN] Command 'SIOCSIFMTU' (%d) error(%d): %s\n", mtu, errno, strerror(errno)); 189 | return (-1); 190 | } 191 | 192 | return (0); 193 | } 194 | 195 | /* 196 | * KidVPN update iv buffer 197 | */ 198 | int kv_lib_update_iv (const char *iv_file) 199 | { 200 | FILE *fp; 201 | char buf[256]; 202 | 203 | if (iv_file) { 204 | kv_cbc_iv_file = strdup(iv_file); 205 | if (!kv_cbc_iv_file) { 206 | fprintf(stderr, "[KidVPN] Not enough memory.\n"); 207 | return (-1); 208 | } 209 | 210 | } else if (!kv_cbc_iv_file) { 211 | fprintf(stderr, "[KidVPN] No IV file specified.\n"); 212 | return (-1); 213 | } 214 | 215 | fp = fopen(kv_cbc_iv_file, "r"); 216 | if (!fp) { 217 | fprintf(stderr, "[KidVPN] Open %s error(%d): %s\n", kv_cbc_iv_file, errno, strerror(errno)); 218 | return (-1); 219 | } 220 | 221 | if (!fgets(buf, sizeof(buf), fp)) { /* read iv */ 222 | fprintf(stderr, "[KidVPN] IV file %s error(%d): %s\n", kv_cbc_iv_file, errno, strerror(errno)); 223 | fclose(fp); 224 | return (-1); 225 | } 226 | 227 | buf[sizeof(buf) - 1] = '\0'; 228 | fclose(fp); 229 | 230 | #ifdef USE_OPENSSL 231 | MD5((unsigned char *)buf, strlen(buf), kv_cbc_iv); 232 | #else /* USE_OPENSSL */ 233 | mbedtls_md5((unsigned char *)buf, strlen(buf), kv_cbc_iv); 234 | #endif /* !USE_OPENSSL */ 235 | 236 | kv_cbc_en = 1; 237 | return (0); 238 | } 239 | 240 | /* 241 | * KidVPN encode 242 | */ 243 | #ifdef USE_OPENSSL 244 | void kv_lib_encode (UINT8 *out, UINT8 *in, int len, int *rlen, AES_KEY *aes_en) 245 | #else /* USE_OPENSSL */ 246 | void kv_lib_encode (UINT8 *out, UINT8 *in, int len, int *rlen, mbedtls_aes_context *aes_en) 247 | #endif /* !USE_OPENSSL */ 248 | { 249 | int aes_len = ROUND_UP(len, KV_AES_BLK_LEN); 250 | int spare; 251 | int i, times; 252 | unsigned char *iv; 253 | 254 | if (rlen) { 255 | *rlen = aes_len; 256 | } 257 | 258 | if (aes_len > len) { 259 | spare = aes_len - len; 260 | bzero(out + len, spare); 261 | bzero(in + len, spare); 262 | } 263 | 264 | times = aes_len >> KV_AES_BLK_SHIFT; /* aes_len / 16 */ 265 | 266 | if (kv_cbc_en) { /* CBC */ 267 | int j; 268 | 269 | iv = kv_cbc_iv; 270 | 271 | for (i = 0; i < times; i++) { 272 | for (j = 0; j < KV_CIPHER_IV_LEN; j++) { 273 | out[j] = (unsigned char)(in[j] ^ iv[j]); 274 | } 275 | 276 | #ifdef USE_OPENSSL 277 | AES_encrypt(out, out, aes_en); 278 | #else /* USE_OPENSSL */ 279 | mbedtls_aes_crypt_ecb(aes_en, MBEDTLS_AES_ENCRYPT, out, out); 280 | #endif /* !USE_OPENSSL */ 281 | 282 | iv = out; 283 | in += KV_AES_BLK_LEN; 284 | out += KV_AES_BLK_LEN; 285 | } 286 | 287 | } else { /* ECB */ 288 | for (i = 0; i < times; i++) { 289 | #ifdef USE_OPENSSL 290 | AES_encrypt(in, out, aes_en); 291 | #else /* USE_OPENSSL */ 292 | mbedtls_aes_crypt_ecb(aes_en, MBEDTLS_AES_ENCRYPT, in, out); 293 | #endif /* !USE_OPENSSL */ 294 | 295 | in += KV_AES_BLK_LEN; 296 | out += KV_AES_BLK_LEN; 297 | } 298 | } 299 | } 300 | 301 | /* 302 | * KidVPN decode 303 | */ 304 | #ifdef USE_OPENSSL 305 | void kv_lib_decode (UINT8 *out, UINT8 *in, int len, int *rlen, AES_KEY *aes_de) 306 | #else /* USE_OPENSSL */ 307 | void kv_lib_decode (UINT8 *out, UINT8 *in, int len, int *rlen, mbedtls_aes_context *aes_de) 308 | #endif /* !USE_OPENSSL */ 309 | { 310 | int aes_len = ROUND_UP(len, KV_AES_BLK_LEN); 311 | int spare; 312 | int i, times; 313 | unsigned char *iv; 314 | 315 | if (rlen) { 316 | *rlen = aes_len; 317 | } 318 | 319 | if (aes_len > len) { 320 | spare = aes_len - len; 321 | bzero(out + len, spare); 322 | bzero(in + len, spare); 323 | } 324 | 325 | times = aes_len >> KV_AES_BLK_SHIFT; /* aes_len / 16 */ 326 | 327 | if (kv_cbc_en) { /* CBC */ 328 | int j; 329 | 330 | iv = kv_cbc_iv; 331 | 332 | for (i = 0; i < times; i++) { 333 | #ifdef USE_OPENSSL 334 | AES_decrypt(in, out, aes_de); 335 | #else /* USE_OPENSSL */ 336 | mbedtls_aes_crypt_ecb(aes_de, MBEDTLS_AES_DECRYPT, in, out); 337 | #endif /* !USE_OPENSSL */ 338 | 339 | for (j = 0; j < KV_CIPHER_IV_LEN; j++) { 340 | out[j] = (unsigned char)(out[j] ^ iv[j]); 341 | } 342 | 343 | iv = in; 344 | in += KV_AES_BLK_LEN; 345 | out += KV_AES_BLK_LEN; 346 | } 347 | 348 | } else { /* ECB */ 349 | for (i = 0; i < times; i++) { 350 | #ifdef USE_OPENSSL 351 | AES_decrypt(in, out, aes_de); 352 | #else /* USE_OPENSSL */ 353 | mbedtls_aes_crypt_ecb(aes_de, MBEDTLS_AES_DECRYPT, in, out); 354 | #endif /* !USE_OPENSSL */ 355 | 356 | in += KV_AES_BLK_LEN; 357 | out += KV_AES_BLK_LEN; 358 | } 359 | } 360 | } 361 | 362 | /* 363 | * KidVPN address is same 364 | */ 365 | int kv_lib_addr_is_same (struct sockaddr_in *addr1, struct sockaddr_in *addr2) 366 | { 367 | if ((addr1->sin_port == addr2->sin_port) && 368 | (addr1->sin_addr.s_addr == addr2->sin_addr.s_addr)) { 369 | return (1); 370 | } 371 | 372 | return (0); 373 | } 374 | 375 | /* 376 | * KidVPN client hash 377 | */ 378 | int kv_lib_cli_hash (UINT8 hwaddr[]) 379 | { 380 | int hash; 381 | 382 | hash = hwaddr[0] 383 | + hwaddr[1] 384 | + hwaddr[2] 385 | + hwaddr[3] 386 | + hwaddr[4] 387 | + hwaddr[5]; 388 | 389 | return (hash & KV_CLI_HASH_MASK); 390 | } 391 | 392 | /* 393 | * KidVPN add a new client into list 394 | */ 395 | void kv_lib_cli_add (struct kv_cli_node *cli, struct kv_cli_node *header[]) 396 | { 397 | int hash = kv_lib_cli_hash(cli->hwaddr); 398 | 399 | cli->next = header[hash]; 400 | cli->prev = NULL; 401 | if (header[hash]) { 402 | header[hash]->prev = cli; 403 | } 404 | header[hash] = cli; 405 | } 406 | 407 | /* 408 | * KidVPN delete a client from list 409 | */ 410 | void kv_lib_cli_delete (struct kv_cli_node *cli, struct kv_cli_node *header[]) 411 | { 412 | int hash = kv_lib_cli_hash(cli->hwaddr); 413 | 414 | if (header[hash] == cli) { 415 | header[hash] = cli->next; 416 | } 417 | if (cli->next) { 418 | cli->next->prev = cli->prev; 419 | } 420 | if (cli->prev) { 421 | cli->prev->next = cli->next; 422 | } 423 | } 424 | 425 | /* 426 | * KidVPN find client from list 427 | */ 428 | struct kv_cli_node *kv_lib_cli_find (UINT8 hwaddr[], struct kv_cli_node *header[]) 429 | { 430 | struct kv_cli_node *cli; 431 | int hash = kv_lib_cli_hash(hwaddr); 432 | 433 | for (cli = header[hash]; cli != NULL; cli = cli->next) { 434 | if (!memcmp(cli->hwaddr, hwaddr, ETH_ALEN)) { 435 | return (cli); 436 | } 437 | } 438 | 439 | return (NULL); 440 | } 441 | 442 | #if KV_VOLUNTARILY_QUIT 443 | /* 444 | * signalfd init 445 | */ 446 | int kv_lib_signalfd (void) 447 | { 448 | int sigfd; 449 | sigset_t mask; 450 | 451 | sigemptyset(&mask); 452 | sigaddset(&mask, SIGTERM); 453 | sigaddset(&mask, SIGUSR1); 454 | sigprocmask(SIG_BLOCK, &mask, NULL); 455 | 456 | sigfd = signalfd(-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK); 457 | if (sigfd < 0) { 458 | fprintf(stderr, "[KidVPN] Can not open signalfd, error(%d): %s\n", errno, strerror(errno)); 459 | return (-1); 460 | } 461 | 462 | return (sigfd); 463 | } 464 | #endif /* KV_VOLUNTARILY_QUIT */ 465 | 466 | /* 467 | * end 468 | */ 469 | -------------------------------------------------------------------------------- /kv_main.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * KidVPN main. 4 | * Verification using sylixos(tm) real-time operating system 5 | */ 6 | 7 | /* 8 | * Copyright (c) 2006-2018 SylixOS Group. 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. The name of the author may not be used to endorse or promote products 20 | * derived from this software without specific prior written permission. 21 | * 4. This code has been or is applying for intellectual property protection 22 | * and can only be used with acoinfo software products. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 25 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 27 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 29 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 32 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 33 | * OF SUCH DAMAGE. 34 | * 35 | * Author: Han.hui 36 | * 37 | */ 38 | 39 | #include "kv_lib.h" 40 | #include "kv_cfg.h" 41 | #include "kv_serv.h" 42 | #include "kv_client.h" 43 | 44 | /* version */ 45 | #define KV_VERSION "1.0.0" 46 | 47 | /* 48 | * key code change function 49 | */ 50 | static int key_code_change (unsigned char *key, unsigned int *keybits, const char *keyascii) 51 | { 52 | int ascii_len = strlen(keyascii); 53 | int i, loop; 54 | unsigned char tmp; 55 | 56 | if ((ascii_len >= 32) && (ascii_len <= 48)) { 57 | *keybits = 128; 58 | loop = 16; 59 | 60 | } else if ((ascii_len >= 48) && (ascii_len <= 64)) { 61 | *keybits = 192; 62 | loop = 24; 63 | 64 | } else if (ascii_len >= 64) { 65 | *keybits = 256; 66 | loop = 32; 67 | 68 | } else { 69 | fprintf(stderr, "[KidVPN] Key length error.\n"); 70 | return (-1); 71 | } 72 | 73 | for (i = 0; i < loop; i++) { 74 | if ((keyascii[0] >= '0') && (keyascii[0] <= '9')) { 75 | tmp = ((keyascii[0] - '0') << 4); 76 | 77 | } else if ((keyascii[0] >= 'a') && (keyascii[0] <= 'f')) { 78 | tmp = ((keyascii[0] - 'a' + 10) << 4); 79 | 80 | } else if ((keyascii[0] >= 'A') && (keyascii[0] <= 'F')) { 81 | tmp = ((keyascii[0] - 'A' + 10) << 4); 82 | 83 | } else { 84 | fprintf(stderr, "[KidVPN] Key format error.\n"); 85 | return (-1); 86 | } 87 | 88 | if ((keyascii[1] >= '0') && (keyascii[1] <= '9')) { 89 | tmp |= (keyascii[1] - '0'); 90 | 91 | } else if ((keyascii[1] >= 'a') && (keyascii[1] <= 'f')) { 92 | tmp |= (keyascii[1] - 'a' + 10); 93 | 94 | } else if ((keyascii[1] >= 'A') && (keyascii[1] <= 'F')) { 95 | tmp |= (keyascii[1] - 'A' + 10); 96 | 97 | } else { 98 | fprintf(stderr, "[KidVPN] Key format error.\n"); 99 | return (-1); 100 | } 101 | 102 | *key = tmp; 103 | key++; 104 | keyascii += 2; 105 | } 106 | 107 | return (0); 108 | } 109 | 110 | /* 111 | * key code add password function 112 | */ 113 | static void key_code_xpw (unsigned char *keycode, unsigned int keybits, const char *password) 114 | { 115 | int i, loop; 116 | const char *p = password; 117 | 118 | loop = keybits / 8; 119 | 120 | for (i = 0; i < loop; i++) { 121 | keycode[i] = keycode[i] ^ *p; 122 | p++; 123 | if (*p == '\0') { 124 | p = password; 125 | } 126 | } 127 | } 128 | 129 | #if !KV_VOLUNTARILY_QUIT 130 | /* 131 | * IV update sigaction 132 | */ 133 | static void iv_update_handle (int signo) 134 | { 135 | kv_lib_update_iv(NULL); 136 | } 137 | 138 | /* 139 | * IV update sigaction init 140 | */ 141 | static void iv_update_handle_init (void) 142 | { 143 | struct sigaction action; 144 | 145 | bzero(&action, sizeof(action)); 146 | sigaddset(&action.sa_mask, SIGUSR1); 147 | action.sa_flags = SA_RESTART; 148 | action.sa_handler = iv_update_handle; 149 | 150 | sigaction(SIGUSR1, &action, NULL); 151 | } 152 | #endif /* !KV_VOLUNTARILY_QUIT */ 153 | 154 | /* 155 | * main function 156 | */ 157 | int main (int argc, char *argv[]) 158 | { 159 | FILE *fkey; 160 | int hole_punching; 161 | int i, vnd_id, rand_fd, is_serv, mtu = KV_VND_DEF_MTU; 162 | unsigned int port; 163 | void *cfg; 164 | const char *file; 165 | const char *ipaddr; 166 | const char *mode; 167 | char *straddr; 168 | char keyascii[65]; 169 | unsigned char keycode[32]; 170 | unsigned int keybits; 171 | 172 | #ifndef SYLIXOS 173 | const char *tap; 174 | #endif /* !SYLIXOS */ 175 | char *tapname = NULL; 176 | 177 | if (argc < 3) { 178 | usage: 179 | printf("USAGE: kidvpn [config file *.ini] [sector] [password]\n" 180 | " config file like this:\n" 181 | " [server_0]\n" 182 | " mode=server # Run as server mode\n" 183 | " key_file=serv.key # AES key file\n" 184 | " iv_file=serv.iv # CBC IV file (Optional default use ECB)\n" 185 | " vnd_id=0 # Virtual network device ID (For SylixOS)\n" 186 | " tap_name=tap0 # Virtual network device name (For Linux & Windows)\n" 187 | " mtu=1464 # 1280 ~ 1472 (Optional default: 1464)\n" 188 | " local_ip=192.168.0.1 # Local IP address in this system\n" 189 | " port=10088 # Local port (Optional default: 10088)\n\n" 190 | " [client_0]\n" 191 | " mode=client # Run as client mode\n" 192 | " key_file=cli.key # AES key file\n" 193 | " iv_file=cli.iv # CBC IV file (Optional default use ECB)\n" 194 | " vnd_id=0 # Virtual network device ID (For SylixOS)\n" 195 | " tap_name=tap0 # Virtual network device name (For Linux & Windows)\n" 196 | " mtu=1464 # 1280 ~ 1472 must same as server (Optional default: 1464)\n" 197 | " server=123.123.123.123 # KidVPN Server address\n" 198 | " port=10088 # Server port (Optional default: 10088)\n" 199 | " hole_punching=0 # UDP hole punching enable (Optional default: 0)\n\n" 200 | " kidvpn -genkey 128 (Generate a AES-128 key)\n" 201 | " eg. kidvpn -genkey 128\n" 202 | " kidvpn -genkey 192\n" 203 | " kidvpn -genkey 256\n" 204 | " kidvpn -genkey 192 >keyfile\n\n" 205 | "[KidVPN] Current Version: %s\n", KV_VERSION); 206 | return (0); 207 | } 208 | 209 | if (argc == 3) { 210 | if (!strcmp(argv[1], "-genkey")) { 211 | rand_fd = open("/dev/random", O_RDONLY); 212 | if (rand_fd < 0) { 213 | fprintf(stderr, "[KidVPN] Can not open /dev/random file, error(%d): %s\n", errno, strerror(errno)); 214 | return (-1); 215 | } 216 | 217 | keybits = atoi(argv[2]); 218 | switch (keybits) { 219 | 220 | case 128: 221 | read(rand_fd, keycode, 16); 222 | close(rand_fd); 223 | break; 224 | 225 | case 192: 226 | read(rand_fd, keycode, 24); 227 | close(rand_fd); 228 | break; 229 | 230 | case 256: 231 | read(rand_fd, keycode, 32); 232 | close(rand_fd); 233 | break; 234 | 235 | default: 236 | close(rand_fd); 237 | fprintf(stderr, "[KidVPN] Key bits only support: 128, 192, 256\n"); 238 | return (-1); 239 | } 240 | 241 | for (i = 0; i < (keybits >> 3); i++) { 242 | printf("%02x", keycode[i]); 243 | } 244 | printf("\n"); 245 | return (0); 246 | 247 | } else { 248 | goto usage; 249 | } 250 | 251 | } else if (argc == 4) { 252 | cfg = kv_cfg_load(argv[1], argv[2]); 253 | if (!cfg) { 254 | fprintf(stderr, "[KidVPN] Can't load configure file %s error(%d): %s\n", 255 | argv[1], errno, strerror(errno)); 256 | return (-1); 257 | } 258 | 259 | mode = kv_cfg_getstring(cfg, "mode", NULL); 260 | if (!mode) { 261 | kv_cfg_unload(cfg); 262 | fprintf(stderr, "[KidVPN] Can't found mode setting\n"); 263 | return (-1); 264 | } 265 | 266 | is_serv = (*mode == 's') ? 1 : 0; 267 | 268 | file = kv_cfg_getstring(cfg, "key_file", NULL); 269 | if (!file) { 270 | kv_cfg_unload(cfg); 271 | fprintf(stderr, "[KidVPN] Can't found key file setting\n"); 272 | return (-1); 273 | } 274 | 275 | #ifdef SYLIXOS 276 | vnd_id = kv_cfg_getint(cfg, "vnd_id", -1); 277 | if (vnd_id < 0) { 278 | kv_cfg_unload(cfg); 279 | fprintf(stderr, "[KidVPN] Can't found virtual network device ID setting\n"); 280 | return (-1); 281 | } 282 | 283 | #else /* SYLIXOS */ 284 | vnd_id = -1; 285 | tap = kv_cfg_getstring(cfg, "tap_name", NULL); 286 | if (tap) { 287 | tapname = strdup(tap); 288 | 289 | } else { 290 | tapname = strdup(""); /* Auto create tap interface */ 291 | } 292 | 293 | if (!tapname) { 294 | kv_cfg_unload(cfg); 295 | fprintf(stderr, "[KidVPN] strdup() error(%d): %s\n", errno, strerror(errno)); 296 | return (-1); 297 | } 298 | #endif /* !SYLIXOS */ 299 | 300 | mtu = kv_cfg_getint(cfg, "mtu", KV_VND_DEF_MTU); 301 | if ((mtu > KV_VND_MAX_MTU) || (mtu < KV_VND_MIN_MTU)) { 302 | kv_cfg_unload(cfg); 303 | fprintf(stderr, "[KidVPN] MTU must in %d ~ %d\n", KV_VND_MIN_MTU, KV_VND_MAX_MTU); 304 | return (-1); 305 | } 306 | 307 | port = (unsigned short)kv_cfg_getint(cfg, "port", KV_SERV_PORT); 308 | if (!port) { 309 | kv_cfg_unload(cfg); 310 | fprintf(stderr, "[KidVPN] Port error\n"); 311 | return (-1); 312 | } 313 | 314 | if (is_serv) { 315 | ipaddr = kv_cfg_getstring(cfg, "local_ip", NULL); 316 | } else { 317 | ipaddr = kv_cfg_getstring(cfg, "server", NULL); 318 | } 319 | 320 | if (!ipaddr) { 321 | kv_cfg_unload(cfg); 322 | fprintf(stderr, "[KidVPN] Can't found address setting\n"); 323 | return (-1); 324 | } 325 | 326 | straddr = strdup(ipaddr); 327 | if (!straddr) { 328 | kv_cfg_unload(cfg); 329 | fprintf(stderr, "[KidVPN] strdup() error(%d): %s\n", errno, strerror(errno)); 330 | return (-1); 331 | } 332 | 333 | fkey = fopen(file, "r"); /* open key file */ 334 | if (!fkey) { 335 | kv_cfg_unload(cfg); 336 | fprintf(stderr, "[KidVPN] Open %s error(%d): %s\n", file, errno, strerror(errno)); 337 | return (-1); 338 | } 339 | 340 | if (!fgets(keyascii, 65, fkey)) { /* read aes key */ 341 | fprintf(stderr, "[KidVPN] Key file %s error(%d): %s\n", file, errno, strerror(errno)); 342 | fclose(fkey); 343 | kv_cfg_unload(cfg); 344 | return (-1); 345 | } 346 | fclose(fkey); 347 | 348 | if (key_code_change(keycode, &keybits, keyascii)) { /* get aes key */ 349 | kv_cfg_unload(cfg); 350 | return (-1); 351 | } 352 | 353 | key_code_xpw(keycode, keybits, argv[3]); 354 | 355 | file = kv_cfg_getstring(cfg, "iv_file", NULL); 356 | if (file) { 357 | if (kv_lib_update_iv(file)) { /* Set IV */ 358 | kv_cfg_unload(cfg); 359 | return (-1); 360 | } 361 | 362 | #if !KV_VOLUNTARILY_QUIT 363 | iv_update_handle_init(); /* Handle Update IV signal */ 364 | #endif 365 | } 366 | 367 | hole_punching = kv_cfg_getint(cfg, "hole_punching", 0); /* UDP hole punching enable/disable */ 368 | 369 | if (!kv_cfg_getboolean(cfg, "no_daemon", 0)) { 370 | daemon(1, 1); /* make this process to a daemon mode */ 371 | } 372 | 373 | kv_cfg_unload(cfg); 374 | 375 | if (is_serv) { 376 | return (kv_serv_start(vnd_id, tapname, keycode, keybits, straddr, port, mtu)); 377 | } else { 378 | return (kv_cli_start(vnd_id, tapname, keycode, keybits, straddr, port, mtu, hole_punching)); 379 | } 380 | 381 | } else { 382 | goto usage; 383 | } 384 | } 385 | 386 | /* 387 | * end 388 | */ 389 | -------------------------------------------------------------------------------- /kv_serv.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * KidVPN client. 4 | * Verification using sylixos(tm) real-time operating system 5 | */ 6 | 7 | /* 8 | * Copyright (c) 2006-2018 SylixOS Group. 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. The name of the author may not be used to endorse or promote products 20 | * derived from this software without specific prior written permission. 21 | * 4. This code has been or is applying for intellectual property protection 22 | * and can only be used with acoinfo software products. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 25 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 27 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 29 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 32 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 33 | * OF SUCH DAMAGE. 34 | * 35 | * Author: Han.hui 36 | * 37 | */ 38 | 39 | #include "kv_lib.h" 40 | #include "kv_serv.h" 41 | 42 | /* KidVPN CBC enable */ 43 | extern int kv_cbc_en; 44 | 45 | /* KidVPN exit flag */ 46 | #if KV_VOLUNTARILY_QUIT 47 | static int serv_exit = 0; 48 | #endif 49 | 50 | /* KidVPN server fd */ 51 | static int serv_fd = -1; 52 | 53 | /* KidVPN virtual net device fd */ 54 | static int vnd_fd = -1; 55 | 56 | /* KidVPN virtual net MTU */ 57 | static int vnd_mtu = KV_VND_DEF_MTU; 58 | 59 | /* KidVPN server addr */ 60 | static struct sockaddr_in serv_addr; 61 | 62 | /* KidVPN server aes key */ 63 | #ifdef USE_OPENSSL 64 | static AES_KEY ase_enc, ase_dec; 65 | #else /* USE_OPENSSL */ 66 | static mbedtls_aes_context ase_enc, ase_dec; 67 | #endif /* !USE_OPENSSL */ 68 | 69 | /* KidVPN server mac */ 70 | static UINT8 serv_hwaddr[ETH_ALEN]; 71 | 72 | /* KidVPN hello thread handle */ 73 | static pthread_t t_hello; 74 | 75 | /* KidVPN client node list */ 76 | static struct kv_cli_node *cli_header[KV_CLI_HASH_SIZE]; 77 | 78 | /* KidVPN server lock */ 79 | static pthread_mutex_t serv_mutex = PTHREAD_MUTEX_INITIALIZER; 80 | 81 | #define KV_SERV_LOCK() pthread_mutex_lock(&serv_mutex) 82 | #define KV_SERV_UNLOCK() pthread_mutex_unlock(&serv_mutex) 83 | 84 | /* KidVPN server send packet */ 85 | struct kv_welcome_hdr welcome_hdr __attribute__((aligned(KV_PACK_ALIGN))); /* must aligned */ 86 | struct kv_crespond_hdr crespond_hdr __attribute__((aligned(KV_PACK_ALIGN))); 87 | struct kv_err_hdr err_hdr __attribute__((aligned(KV_PACK_ALIGN))); 88 | 89 | /* 90 | * KidVPN init packet header 91 | */ 92 | static void kv_serv_init_hdr (void) 93 | { 94 | int i; 95 | 96 | /* init welcome packet */ 97 | welcome_hdr.cmd = KV_CMD_WELCOME; 98 | welcome_hdr.cmd_len = KV_WELCOME_LEN; 99 | welcome_hdr.magic = KV_CMD_MAGIC; 100 | 101 | for (i = 0; i < ETH_ALEN; i++) { 102 | welcome_hdr.hwaddr[i] = serv_hwaddr[i]; 103 | } 104 | 105 | /* init client query respend packet */ 106 | crespond_hdr.cmd = KV_CMD_CRESPOND; 107 | crespond_hdr.cmd_len = KV_CRESPOND_LEN; 108 | crespond_hdr.magic = KV_CMD_MAGIC; 109 | 110 | /* init error packet */ 111 | err_hdr.cmd = KV_CMD_ERR; 112 | err_hdr.cmd_len = KV_ERR_LEN; 113 | err_hdr.magic = KV_CMD_MAGIC; 114 | } 115 | 116 | /* 117 | * KidVPN server hello thread 118 | */ 119 | static int kv_serv_loop (void) 120 | { 121 | #if KV_VOLUNTARILY_QUIT 122 | int sigfd; 123 | struct signalfd_siginfo fdsi; 124 | #endif 125 | 126 | int i, aes_len, width, to_me; 127 | ssize_t num; 128 | UINT32 snum = 0; 129 | struct sockaddr_in addr_in; 130 | struct kv_cli_node *cli, *dest; 131 | socklen_t slen = sizeof(struct sockaddr_in); 132 | fd_set fdset; 133 | 134 | UINT32 packet_buf_en[(KV_VND_FRAME_BSIZE >> 2) + 1]; /* need 4 bytes aligned */ 135 | UINT32 packet_buf_in[(KV_VND_FRAME_BSIZE >> 2) + 1]; 136 | 137 | UINT8 *packet_en = (UINT8 *)packet_buf_en; /* encrypt packet */ 138 | UINT8 *packet_in = (UINT8 *)packet_buf_in; /* decrypt packet */ 139 | 140 | struct kv_input_hdr *ihdr = (struct kv_input_hdr *)packet_in; 141 | 142 | kv_serv_init_hdr(); 143 | 144 | FD_ZERO(&fdset); 145 | width = (serv_fd > vnd_fd) ? (serv_fd + 1) : (vnd_fd + 1); 146 | 147 | #if KV_VOLUNTARILY_QUIT 148 | sigfd = kv_lib_signalfd(); 149 | if (sigfd < 0) { 150 | return (-1); 151 | } else if (sigfd >= width) { 152 | width = sigfd + 1; 153 | } 154 | #endif /* KV_VOLUNTARILY_QUIT */ 155 | 156 | printf("[KidVPN] Server working.\n"); 157 | 158 | for (;;) { 159 | FD_SET(serv_fd, &fdset); 160 | FD_SET(vnd_fd, &fdset); 161 | 162 | #if KV_VOLUNTARILY_QUIT 163 | FD_SET(sigfd, &fdset); 164 | #endif /* KV_VOLUNTARILY_QUIT */ 165 | 166 | if (select(width, &fdset, NULL, NULL, NULL) <= 0) { /* wait for read */ 167 | break; /* an error occur, exit! */ 168 | } 169 | 170 | #if KV_VOLUNTARILY_QUIT 171 | if (FD_ISSET(sigfd, &fdset)) { /* The specified signal arrives */ 172 | num = read(sigfd, &fdsi, sizeof(struct signalfd_siginfo)); 173 | if (num >= sizeof(struct signalfd_siginfo)) { 174 | if (fdsi.ssi_signo == SIGUSR1) { 175 | kv_lib_update_iv(NULL); 176 | 177 | } else if (fdsi.ssi_signo == SIGTERM) { 178 | serv_exit = 1; 179 | pthread_kill(t_hello, SIGUSR1); 180 | break; 181 | } 182 | } 183 | } 184 | #endif /* KV_VOLUNTARILY_QUIT */ 185 | 186 | if (FD_ISSET(serv_fd, &fdset)) { 187 | num = recvfrom(serv_fd, packet_en, KV_VND_FRAME_BSIZE, 0, 188 | (struct sockaddr *)&addr_in, &slen); 189 | if (num <= 0) { 190 | fprintf(stderr, "[KidVPN] Socket recvfrom() error(%d): %s!\n", errno, strerror(errno)); 191 | break; /* an error occur, exit! */ 192 | } 193 | 194 | if (num < ETH_ZLEN) { /* control packet */ 195 | kv_lib_decode(packet_in, packet_en, (int)num, &aes_len, &ase_dec); /* decode */ 196 | 197 | if (ihdr->cmd == KV_CMD_HELLO) { /* hello packet */ 198 | struct kv_hello_hdr *hhdr = (struct kv_hello_hdr *)packet_in; 199 | 200 | if ((hhdr->cmd_len == KV_HELLO_LEN) && 201 | (hhdr->magic == KV_CMD_MAGIC)) { 202 | UINT16 mtu = ntohs(hhdr->mtu); 203 | 204 | if (mtu != vnd_mtu) { /* MTU not fixed */ 205 | err_hdr.err = htons(KV_ERR_MTU); 206 | err_hdr.code = htons(vnd_mtu); 207 | printf("[KidVPN] Client error: KV_ERR_MTU %d (server: %d)\n", mtu, vnd_mtu); 208 | 209 | kv_lib_encode(packet_en, (UINT8 *)&err_hdr, KV_ERR_LEN, &aes_len, &ase_enc); 210 | 211 | if (sendto(serv_fd, packet_en, aes_len, 0, 212 | (struct sockaddr *)&addr_in, slen) != aes_len) { /* send server welcome */ 213 | fprintf(stderr, "[KidVPN] Socket sendto() error(%d): %s!\n", errno, strerror(errno)); 214 | break; /* an error occur, exit! */ 215 | } 216 | 217 | } else { 218 | KV_SERV_LOCK(); 219 | cli = kv_lib_cli_find(hhdr->hwaddr, cli_header); 220 | if (cli) { 221 | if (!kv_lib_addr_is_same(&cli->addr, &addr_in)) { 222 | cli->addr = addr_in; /* save new address */ 223 | printf("[KidVPN] Client changed: %s [%02x:%02x:%02x:%02x:%02x:%02x]\n", 224 | inet_ntoa(cli->addr.sin_addr), cli->hwaddr[0], cli->hwaddr[1], 225 | cli->hwaddr[2], cli->hwaddr[3], cli->hwaddr[4], cli->hwaddr[5]); 226 | } 227 | cli->alive = KV_CLI_HELLO_TIMEOUT; /* refresh client alive */ 228 | 229 | } else { 230 | cli = (struct kv_cli_node *)malloc(sizeof(struct kv_cli_node)); /* new client */ 231 | if (cli) { 232 | cli->alive = KV_CLI_HELLO_TIMEOUT; 233 | cli->addr = addr_in; 234 | memcpy(cli->hwaddr, hhdr->hwaddr, ETH_ALEN); /* set client mac */ 235 | kv_lib_cli_add(cli, cli_header); /* add to client list */ 236 | printf("[KidVPN] Client add: %s [%02x:%02x:%02x:%02x:%02x:%02x]\n", 237 | inet_ntoa(cli->addr.sin_addr), cli->hwaddr[0], cli->hwaddr[1], 238 | cli->hwaddr[2], cli->hwaddr[3], cli->hwaddr[4], cli->hwaddr[5]); 239 | } 240 | } 241 | KV_SERV_UNLOCK(); 242 | 243 | if (cli) { 244 | /* respond client keep alive */ 245 | snum++; 246 | welcome_hdr.snum = htonl(snum); 247 | 248 | kv_lib_encode(packet_en, (UINT8 *)&welcome_hdr, KV_WELCOME_LEN, &aes_len, &ase_enc); 249 | 250 | if (sendto(serv_fd, packet_en, aes_len, 0, 251 | (struct sockaddr *)&addr_in, slen) != aes_len) { /* send server welcome */ 252 | fprintf(stderr, "[KidVPN] Socket sendto() error(%d): %s!\n", errno, strerror(errno)); 253 | break; /* an error occur, exit! */ 254 | } 255 | } 256 | } 257 | } 258 | 259 | } else if (ihdr->cmd == KV_CMD_CQUERY) { /* client query packet */ 260 | struct kv_cquery_hdr *cqhdr = (struct kv_cquery_hdr *)packet_in; 261 | 262 | if ((cqhdr->cmd_len == KV_CQUERY_LEN) && 263 | (cqhdr->magic == KV_CMD_MAGIC)) { 264 | KV_SERV_LOCK(); 265 | cli = kv_lib_cli_find(cqhdr->hwaddr, cli_header); 266 | if (cli) { 267 | memcpy(crespond_hdr.hwaddr, cli->hwaddr, ETH_ALEN); 268 | crespond_hdr.cliaddr = cli->addr.sin_addr.s_addr; 269 | crespond_hdr.cliport = cli->addr.sin_port; 270 | } 271 | KV_SERV_UNLOCK(); 272 | 273 | if (cli) { 274 | kv_lib_encode(packet_en, (UINT8 *)&crespond_hdr, KV_CRESPOND_LEN, &aes_len, &ase_enc); 275 | 276 | if (sendto(serv_fd, packet_en, aes_len, 0, 277 | (struct sockaddr *)&addr_in, slen) != aes_len) { /* send server welcome */ 278 | fprintf(stderr, "[KidVPN] Socket sendto() error(%d): %s!\n", errno, strerror(errno)); 279 | break; /* an error occur, exit! */ 280 | } 281 | } 282 | } 283 | } 284 | 285 | } else { /* normal packet */ 286 | to_me = 0; 287 | 288 | /* Only decode 16 byte first */ 289 | kv_lib_decode(packet_in, packet_en, KV_AES_BLK_LEN, &aes_len, &ase_dec); /* decode */ 290 | 291 | KV_SERV_LOCK(); 292 | cli = kv_lib_cli_find(KV_PKT_MAC_SRC(packet_in), cli_header); /* sender client must alive */ 293 | if (cli && kv_lib_addr_is_same(&cli->addr, &addr_in)) { /* address compare */ 294 | if (KV_PKY_MAC_BMC(packet_in)) { /* broadcast? */ 295 | for (i = 0; i < KV_CLI_HASH_SIZE; i++) { 296 | for (dest = cli_header[i]; dest != NULL; dest = dest->next) { 297 | if (dest != cli) { 298 | sendto(serv_fd, packet_en, num, 0, 299 | (struct sockaddr *)&dest->addr, slen); /* forward to all client */ 300 | } 301 | } 302 | } 303 | to_me = 1; 304 | 305 | } else { /* uncast */ 306 | dest = kv_lib_cli_find(KV_PKT_MAC_DEST(packet_in), cli_header); 307 | if (dest) { 308 | sendto(serv_fd, packet_en, num, 0, 309 | (struct sockaddr *)&dest->addr, slen); /* forward to client */ 310 | 311 | } else if (!memcmp(KV_PKT_MAC_DEST(packet_in), serv_hwaddr, ETH_ALEN)) { 312 | to_me = 1; 313 | } 314 | } 315 | } 316 | KV_SERV_UNLOCK(); 317 | 318 | if (to_me) { 319 | if (kv_cbc_en) { 320 | kv_lib_decode(packet_in, packet_en, num, &aes_len, &ase_dec); /* decode all */ 321 | } else { 322 | kv_lib_decode(&packet_in[KV_AES_BLK_LEN], &packet_en[KV_AES_BLK_LEN], 323 | (int)num - KV_AES_BLK_LEN, &aes_len, &ase_dec); /* decode remaining */ 324 | } 325 | 326 | if (num > KV_VND_FRAME_LEN(vnd_mtu)) { 327 | num = KV_VND_FRAME_LEN(vnd_mtu); /* Cut tail (The tail is AES 16Bytes align add) */ 328 | } 329 | write(vnd_fd, packet_in, num); /* virtual net device recv */ 330 | } 331 | } 332 | } 333 | 334 | if (FD_ISSET(vnd_fd, &fdset)) { /* vitural net device send a message to other */ 335 | num = read(vnd_fd, packet_in, KV_VND_FRAME_BSIZE); 336 | if (num <= 0) { 337 | fprintf(stderr, "[KidVPN] Read virtual net device error(%d): %s!\n", errno, strerror(errno)); 338 | break; /* an error occur, exit! */ 339 | } 340 | 341 | if (num < ETH_ZLEN) { 342 | num = ETH_ZLEN; /* ethernet shortest length */ 343 | } 344 | 345 | kv_lib_encode(packet_en, packet_in, (int)num, &aes_len, &ase_enc); 346 | 347 | KV_SERV_LOCK(); 348 | if (KV_PKY_MAC_BMC(packet_in)) { /* broadcast? */ 349 | for (i = 0; i < KV_CLI_HASH_SIZE; i++) { 350 | for (dest = cli_header[i]; dest != NULL; dest = dest->next) { 351 | sendto(serv_fd, packet_en, aes_len, 0, 352 | (struct sockaddr *)&dest->addr, slen); /* NOTICE: send a 'aes_len' packet to other */ 353 | } 354 | } 355 | 356 | } else { /* uncast */ 357 | dest = kv_lib_cli_find(KV_PKT_MAC_DEST(packet_in), cli_header); 358 | if (dest) { 359 | sendto(serv_fd, packet_en, aes_len, 0, 360 | (struct sockaddr *)&dest->addr, slen); /* NOTICE: send a 'aes_len' packet to other */ 361 | } 362 | } 363 | KV_SERV_UNLOCK(); 364 | } 365 | } 366 | 367 | return (0); /* exit! */ 368 | } 369 | 370 | /* 371 | * KidVPN server hello thread 372 | */ 373 | static void kv_serv_hello (void) 374 | { 375 | int i; 376 | struct kv_cli_node *cli, *del; 377 | 378 | for (;;) { 379 | KV_SERV_LOCK(); 380 | for (i = 0; i < KV_CLI_HASH_SIZE; i++) { 381 | cli = cli_header[i]; 382 | while (cli) { 383 | if (cli->alive >= KV_CLI_HELLO_PERIOD) { 384 | cli->alive -= KV_CLI_HELLO_PERIOD; 385 | } else { 386 | cli->alive = 0; 387 | } 388 | 389 | if (cli->alive <= 0) { /* client dead! */ 390 | del = cli; 391 | cli = cli->next; 392 | kv_lib_cli_delete(del, cli_header); /* delete client from list */ 393 | printf("[KidVPN] Client lost: %s [%02x:%02x:%02x:%02x:%02x:%02x]\n", 394 | inet_ntoa(del->addr.sin_addr), del->hwaddr[0], del->hwaddr[1], 395 | del->hwaddr[2], del->hwaddr[3], del->hwaddr[4], del->hwaddr[5]); 396 | free(del); 397 | 398 | } else { 399 | cli = cli->next; 400 | } 401 | } 402 | } 403 | KV_SERV_UNLOCK(); 404 | 405 | #if KV_VOLUNTARILY_QUIT 406 | if (serv_exit) { 407 | break; 408 | } 409 | #endif /* KV_VOLUNTARILY_QUIT */ 410 | 411 | sleep(KV_CLI_HELLO_PERIOD); 412 | } 413 | } 414 | 415 | /* 416 | * start KidVPN server 417 | */ 418 | int kv_serv_start (int vnd_id, const char *tap_name, const unsigned char *key, unsigned int keybits, 419 | const char *local, unsigned int port, int mtu) 420 | { 421 | if ((keybits != 128) && (keybits != 192) && (keybits != 256)) { 422 | fprintf(stderr, "[KidVPN] AES key bits error!\n"); 423 | return (-1); 424 | } 425 | 426 | #ifdef USE_OPENSSL 427 | if (AES_set_encrypt_key(key, keybits, &ase_enc)) { 428 | fprintf(stderr, "[KidVPN] Set AES encode key fail!\n"); 429 | return (-1); 430 | } 431 | 432 | if (AES_set_decrypt_key(key, keybits, &ase_dec)) { 433 | fprintf(stderr, "[KidVPN] Set AES decode key fail!\n"); 434 | return (-1); 435 | } 436 | 437 | #else /* USE_OPENSSL */ 438 | if (mbedtls_aes_setkey_enc(&ase_enc, key, keybits)) { 439 | fprintf(stderr, "[KidVPN] Set AES encode key fail!\n"); 440 | return (-1); 441 | } 442 | 443 | if (mbedtls_aes_setkey_dec(&ase_dec, key, keybits)) { 444 | fprintf(stderr, "[KidVPN] Set AES decode key fail!\n"); 445 | return (-1); 446 | } 447 | #endif /* !USE_OPENSSL */ 448 | 449 | #ifdef SYLIXOS 450 | serv_addr.sin_len = sizeof(struct sockaddr_in); 451 | #endif /* SYLIXOS */ 452 | 453 | serv_addr.sin_family = AF_INET; 454 | serv_addr.sin_port = htons(port); 455 | 456 | if (!inet_aton(local, &serv_addr.sin_addr)) { 457 | fprintf(stderr, "[KidVPN] Local IP error.\n"); 458 | return (-1); 459 | } 460 | 461 | vnd_mtu = mtu; 462 | if (kv_lib_init(vnd_id, tap_name, &serv_fd, &vnd_fd, serv_hwaddr, mtu)) { /* init server */ 463 | return (-1); 464 | } 465 | 466 | if (bind(serv_fd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr_in))) { /* bind local port */ 467 | fprintf(stderr, "[KidVPN] Socket bind() call fail(%d): %s!\n", errno, strerror(errno)); 468 | kv_lib_deinit(serv_fd, vnd_fd); 469 | return (-1); 470 | } 471 | 472 | if (pthread_create(&t_hello, NULL, (void *(*)(void *))kv_serv_hello, NULL)) { 473 | fprintf(stderr, "[KidVPN] Can not create hello thread error(%d): %s.\n", errno, strerror(errno)); 474 | kv_lib_deinit(serv_fd, vnd_fd); 475 | return (-1); 476 | } 477 | 478 | pthread_detach(t_hello); 479 | pthread_setname_np(t_hello, "kvs_hello"); 480 | 481 | if (kv_serv_loop()) { /* server main loop */ 482 | kv_lib_deinit(serv_fd, vnd_fd); 483 | return (-1); 484 | } 485 | 486 | return (0); 487 | } 488 | 489 | /* 490 | * end 491 | */ 492 | -------------------------------------------------------------------------------- /kv_client.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file 3 | * KidVPN client. 4 | * Verification using sylixos(tm) real-time operating system 5 | */ 6 | 7 | /* 8 | * Copyright (c) 2006-2018 SylixOS Group. 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without modification, 12 | * are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 3. The name of the author may not be used to endorse or promote products 20 | * derived from this software without specific prior written permission. 21 | * 4. This code has been or is applying for intellectual property protection 22 | * and can only be used with acoinfo software products. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 25 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 27 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 29 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 32 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 33 | * OF SUCH DAMAGE. 34 | * 35 | * Author: Han.hui 36 | * 37 | */ 38 | 39 | #include "kv_lib.h" 40 | #include "kv_serv.h" 41 | 42 | /* KidVPN client hole punching */ 43 | struct kv_cli_hp { 44 | struct kv_cli_node cli; 45 | int stat; /* hole punching state machine */ 46 | #define KV_CLI_HPSTAT_CLOSE 0 47 | #define KV_CLI_HPSTAT_CQUERY 1 48 | #define KV_CLI_HPSTAT_HPQUERY 2 49 | #define KV_CLI_HPSTAT_HPRESPOND 3 50 | }; 51 | 52 | /* KidVPN exit flag */ 53 | #if KV_VOLUNTARILY_QUIT 54 | static int cli_exit = 0; 55 | #endif 56 | 57 | /* KidVPN client fd */ 58 | static int cli_fd = -1; 59 | 60 | /* KidVPN virtual net device fd */ 61 | static int vnd_fd = -1; 62 | 63 | /* KidVPN virtual net MTU */ 64 | static int vnd_mtu = KV_VND_DEF_MTU; 65 | 66 | /* KidVPN hello thread handle */ 67 | static pthread_t t_hello; 68 | 69 | /* KidVPN virtual net device hwaddr */ 70 | static struct kv_hello_hdr hello_hdr; 71 | 72 | /* KidVPN server addr */ 73 | static struct sockaddr_in serv_addr; 74 | 75 | /* KidVPN server mac */ 76 | static UINT8 serv_hwaddr[ETH_ALEN]; 77 | 78 | /* KidVPN client aes key */ 79 | #ifdef USE_OPENSSL 80 | static AES_KEY ase_enc, ase_dec; 81 | #else /* USE_OPENSSL */ 82 | static mbedtls_aes_context ase_enc, ase_dec; 83 | #endif /* !USE_OPENSSL */ 84 | 85 | /* KidVPN client alive */ 86 | static int cli_alive; 87 | 88 | /* KidVPN client node list */ 89 | static struct kv_cli_node *cli_header[KV_CLI_HASH_SIZE]; 90 | 91 | /* KidVPN mutex */ 92 | static pthread_mutex_t cli_mutex = PTHREAD_MUTEX_INITIALIZER; 93 | 94 | #define KV_CLI_LOCK() pthread_mutex_lock(&cli_mutex) 95 | #define KV_CLI_UNLOCK() pthread_mutex_unlock(&cli_mutex) 96 | 97 | /* KidVPN server send packet */ 98 | struct kv_cquery_hdr cquery_hdr __attribute__((aligned(KV_PACK_ALIGN))); /* must aligned */ 99 | struct kv_hpquery_hdr hpquery_hdr __attribute__((aligned(KV_PACK_ALIGN))); 100 | struct kv_hprespond_hdr hprespond_hdr __attribute__((aligned(KV_PACK_ALIGN))); 101 | 102 | /* 103 | * KidVPN init packet header 104 | */ 105 | static void kv_cli_init_hdr (void) 106 | { 107 | /* init cquery packet */ 108 | cquery_hdr.cmd = KV_CMD_CQUERY; 109 | cquery_hdr.cmd_len = KV_CQUERY_LEN; 110 | cquery_hdr.magic = KV_CMD_MAGIC; 111 | 112 | /* init hpquery packet */ 113 | hpquery_hdr.cmd = KV_CMD_HPQUERY; 114 | hpquery_hdr.cmd_len = KV_HPQUERY_LEN; 115 | hpquery_hdr.magic = KV_CMD_MAGIC; 116 | 117 | /* init hprespond packet */ 118 | hprespond_hdr.cmd = KV_CMD_HPRESPOND; 119 | hprespond_hdr.cmd_len = KV_HPRESPOND_LEN; 120 | hprespond_hdr.magic = KV_CMD_MAGIC; 121 | 122 | memcpy(hprespond_hdr.hwaddr, hello_hdr.hwaddr, ETH_ALEN); 123 | } 124 | 125 | /* 126 | * KidVPN client loop 127 | */ 128 | static int kv_cli_loop (int hole_punching) 129 | { 130 | #if KV_VOLUNTARILY_QUIT 131 | int sigfd; 132 | struct signalfd_siginfo fdsi; 133 | #endif 134 | 135 | int width, aes_len, to_me, cq_req, hp_req, to_serv; 136 | int mtu; 137 | ssize_t num; 138 | struct sockaddr_in addr_in; 139 | struct kv_cli_node *cli; 140 | struct kv_cli_hp *clihp; 141 | socklen_t slen = sizeof(struct sockaddr_in); 142 | fd_set fdset; 143 | 144 | UINT32 packet_buf_en[(KV_VND_FRAME_BSIZE >> 2) + 1]; /* need 4 bytes aligned */ 145 | UINT32 packet_buf_in[(KV_VND_FRAME_BSIZE >> 2) + 1]; 146 | 147 | UINT8 *packet_en = (UINT8 *)packet_buf_en; /* encrypt packet */ 148 | UINT8 *packet_in = (UINT8 *)packet_buf_in; /* decrypt packet */ 149 | 150 | struct kv_input_hdr *ihdr = (struct kv_input_hdr *)packet_in; 151 | 152 | kv_cli_init_hdr(); 153 | 154 | FD_ZERO(&fdset); 155 | width = (cli_fd > vnd_fd) ? (cli_fd + 1) : (vnd_fd + 1); 156 | 157 | #if KV_VOLUNTARILY_QUIT 158 | sigfd = kv_lib_signalfd(); 159 | if (sigfd < 0) { 160 | return (-1); 161 | } else if (sigfd >= width) { 162 | width = sigfd + 1; 163 | } 164 | #endif /* KV_VOLUNTARILY_QUIT */ 165 | 166 | printf("[KidVPN] Client working.\n"); 167 | 168 | for (;;) { 169 | FD_SET(cli_fd, &fdset); 170 | FD_SET(vnd_fd, &fdset); 171 | 172 | #if KV_VOLUNTARILY_QUIT 173 | FD_SET(sigfd, &fdset); 174 | #endif /* KV_VOLUNTARILY_QUIT */ 175 | 176 | if (select(width, &fdset, NULL, NULL, NULL) <= 0) { /* wait for read */ 177 | break; /* an error occur, exit! */ 178 | } 179 | 180 | #if KV_VOLUNTARILY_QUIT 181 | if (FD_ISSET(sigfd, &fdset)) { /* The specified signal arrives */ 182 | num = read(sigfd, &fdsi, sizeof(struct signalfd_siginfo)); 183 | if (num >= sizeof(struct signalfd_siginfo)) { 184 | if (fdsi.ssi_signo == SIGUSR1) { 185 | kv_lib_update_iv(NULL); 186 | 187 | } else if (fdsi.ssi_signo == SIGTERM) { 188 | cli_exit = 1; 189 | pthread_kill(t_hello, SIGUSR1); 190 | break; 191 | } 192 | } 193 | } 194 | #endif /* KV_VOLUNTARILY_QUIT */ 195 | 196 | if (FD_ISSET(cli_fd, &fdset)) { /* server send a message to me */ 197 | num = recvfrom(cli_fd, packet_en, KV_VND_FRAME_BSIZE, 0, 198 | (struct sockaddr *)&addr_in, &slen); 199 | if (num <= 0) { 200 | fprintf(stderr, "[KidVPN] Socket recvfrom() error(%d): %s!\n", errno, strerror(errno)); 201 | break; /* an error occur, exit! */ 202 | } 203 | 204 | if (!hole_punching) { /* no hole punching support */ 205 | if (addr_in.sin_addr.s_addr != serv_addr.sin_addr.s_addr) { /* not server paceket, drop! */ 206 | continue; 207 | } 208 | } 209 | 210 | kv_lib_decode(packet_in, packet_en, (int)num, &aes_len, &ase_dec); /* decode */ 211 | 212 | if (num < ETH_ZLEN) { /* control packet */ 213 | if (ihdr->cmd == KV_CMD_WELCOME) { /* server welcome */ 214 | struct kv_welcome_hdr *whdr = (struct kv_welcome_hdr *)packet_in; 215 | 216 | if ((whdr->cmd_len == KV_WELCOME_LEN) && 217 | (whdr->magic == KV_CMD_MAGIC)) { 218 | KV_CLI_LOCK(); 219 | if (cli_alive == 0) { 220 | printf("[KidVPN] Server connected %s [%02x:%02x:%02x:%02x:%02x:%02x]\n", 221 | inet_ntoa(addr_in.sin_addr), whdr->hwaddr[0], whdr->hwaddr[1], 222 | whdr->hwaddr[2], whdr->hwaddr[3], whdr->hwaddr[4], whdr->hwaddr[5]); 223 | } 224 | cli_alive = KV_CLI_HELLO_TIMEOUT; /* keep alive */ 225 | KV_CLI_UNLOCK(); 226 | memcpy(serv_hwaddr, whdr->hwaddr, ETH_ALEN); /* save server hwaddr */ 227 | } 228 | 229 | } else if (ihdr->cmd == KV_CMD_ERR) { /* connect error */ 230 | struct kv_err_hdr *ehdr = (struct kv_err_hdr *)packet_in; 231 | 232 | if ((ehdr->cmd_len == KV_ERR_LEN) && 233 | (ehdr->magic == KV_CMD_MAGIC)) { 234 | if (ntohs(ehdr->err) == KV_ERR_MTU) { /* server client mtu not same */ 235 | mtu = ntohs(ehdr->code); 236 | if (kv_lib_setmtu(cli_fd, mtu)) { 237 | fprintf(stderr, "[KidVPN] Set virtual net interface MTU error!\n"); 238 | break; /* an error occur, exit! */ 239 | } 240 | KV_CLI_LOCK(); 241 | vnd_mtu = mtu; /* save new MTU */ 242 | KV_CLI_UNLOCK(); 243 | 244 | } else { 245 | printf("[KidVPN] Connected error: %d (%d)\n", ntohs(ehdr->err), ntohs(ehdr->code)); 246 | } 247 | } 248 | 249 | } else if ((ihdr->cmd == KV_CMD_CRESPOND) && hole_punching) { /* server to client respond client query */ 250 | struct kv_crespond_hdr *crpdhdr = (struct kv_crespond_hdr *)packet_in; 251 | 252 | if ((crpdhdr->cmd_len == KV_CRESPOND_LEN) && 253 | (crpdhdr->magic == KV_CMD_MAGIC)) { 254 | hp_req = 0; 255 | 256 | KV_CLI_LOCK(); 257 | cli = kv_lib_cli_find(crpdhdr->hwaddr, cli_header); 258 | if (cli) { 259 | clihp = (struct kv_cli_hp *)cli; 260 | if (clihp->stat == KV_CLI_HPSTAT_CQUERY) { /* client query state */ 261 | cli->addr.sin_family = AF_INET; 262 | #ifdef SYLIXOS 263 | cli->addr.sin_len = sizeof(struct sockaddr_in); 264 | #endif /* SYLIXOS */ 265 | cli->addr.sin_addr.s_addr = crpdhdr->cliaddr; 266 | cli->addr.sin_port = crpdhdr->cliport; 267 | cli->alive = KV_CLI_HOLE_PUNCHING_ALIVE; 268 | 269 | clihp->stat = KV_CLI_HPSTAT_HPQUERY; 270 | memcpy(hpquery_hdr.hwaddr, cli->hwaddr, ETH_ALEN); 271 | hp_req = 1; /* try hole punching */ 272 | } 273 | } 274 | KV_CLI_UNLOCK(); 275 | 276 | if (hp_req) { 277 | kv_lib_encode(packet_en, (UINT8 *)&hpquery_hdr, KV_HPQUERY_LEN, &aes_len, &ase_enc); 278 | 279 | /* We use 'cli' without lock, because there no delete in client list */ 280 | if (sendto(cli_fd, packet_en, aes_len, 0, 281 | (struct sockaddr *)&cli->addr, slen) != aes_len) { /* send to client try hole punching */ 282 | fprintf(stderr, "[KidVPN] Socket sendto() error(%d): %s!\n", errno, strerror(errno)); 283 | break; /* an error occur, exit! */ 284 | } 285 | } 286 | } 287 | 288 | } else if ((ihdr->cmd == KV_CMD_HPQUERY) && hole_punching) { /* client hole punching query */ 289 | struct kv_hpquery_hdr *hpqueryhdr = (struct kv_hpquery_hdr *)packet_in; 290 | 291 | if ((hpqueryhdr->cmd_len == KV_HPQUERY_LEN) && 292 | (hpqueryhdr->magic == KV_CMD_MAGIC)) { 293 | if (!memcmp(hpqueryhdr->hwaddr, hprespond_hdr.hwaddr, ETH_ALEN)) { /* create hole punching with me? */ 294 | kv_lib_encode(packet_en, (UINT8 *)&hprespond_hdr, KV_HPRESPOND_LEN, &aes_len, &ase_enc); 295 | 296 | if (sendto(cli_fd, packet_en, aes_len, 0, 297 | (struct sockaddr *)&addr_in, slen) != aes_len) { /* send to client */ 298 | fprintf(stderr, "[KidVPN] Socket sendto() error(%d): %s!\n", errno, strerror(errno)); 299 | break; /* an error occur, exit! */ 300 | } 301 | } 302 | } 303 | 304 | } else if ((ihdr->cmd == KV_CMD_HPRESPOND) && hole_punching) { /* client hole punching respond */ 305 | struct kv_hprespond_hdr *hprpdhdr = (struct kv_hprespond_hdr *)packet_in; 306 | 307 | if ((hprpdhdr->cmd_len == KV_HPRESPOND_LEN) && 308 | (hprpdhdr->magic == KV_CMD_MAGIC)) { 309 | KV_CLI_LOCK(); 310 | cli = kv_lib_cli_find(hprpdhdr->hwaddr, cli_header); 311 | if (cli && kv_lib_addr_is_same(&cli->addr, &addr_in)) { 312 | clihp = (struct kv_cli_hp *)cli; 313 | if (clihp->stat == KV_CLI_HPSTAT_HPQUERY) { 314 | clihp->stat = KV_CLI_HPSTAT_HPRESPOND; /* punching respond success */ 315 | cli->alive = KV_CLI_HOLE_PUNCHING_ALIVE; 316 | } 317 | } 318 | KV_CLI_UNLOCK(); 319 | } 320 | } 321 | 322 | } else { /* normal packet */ 323 | if (num > KV_VND_FRAME_LEN(vnd_mtu)) { 324 | num = KV_VND_FRAME_LEN(vnd_mtu); /* Cut tail (The tail is AES 16Bytes align add) */ 325 | } 326 | 327 | if (!hole_punching) { /* no hole punching */ 328 | write(vnd_fd, packet_in, num); /* virtual net device recv */ 329 | 330 | } else { /* hole punching enable */ 331 | to_me = 0; 332 | 333 | if (addr_in.sin_addr.s_addr == serv_addr.sin_addr.s_addr) { /* trust server */ 334 | to_me = 1; 335 | 336 | } else { 337 | KV_CLI_LOCK(); 338 | cli = kv_lib_cli_find(KV_PKT_MAC_SRC(packet_in), cli_header); /* must in our client list */ 339 | if (cli && kv_lib_addr_is_same(&cli->addr, &addr_in)) { 340 | to_me = 1; /* find neibor client */ 341 | } 342 | KV_CLI_UNLOCK(); 343 | } 344 | 345 | if (to_me) { 346 | write(vnd_fd, packet_in, num); /* virtual net device recv */ 347 | } 348 | } 349 | } 350 | } 351 | 352 | if (FD_ISSET(vnd_fd, &fdset)) { /* vitural net device send a message to server or client */ 353 | num = read(vnd_fd, packet_in, KV_VND_FRAME_BSIZE); 354 | if (num <= 0) { 355 | fprintf(stderr, "[KidVPN] Read virtual net device error(%d): %s!\n", errno, strerror(errno)); 356 | break; /* an error occur, exit! */ 357 | } 358 | 359 | if (num < ETH_ZLEN) { 360 | num = ETH_ZLEN; /* ethernet shortest length */ 361 | } 362 | 363 | if (!hole_punching || KV_PKY_MAC_BMC(packet_in)) { /* no hole punching or broadcast? */ 364 | kv_lib_encode(packet_en, packet_in, (int)num, &aes_len, &ase_enc); 365 | 366 | sendto(cli_fd, packet_en, aes_len, 0, 367 | (struct sockaddr *)&serv_addr, slen); /* NOTICE: send a 'aes_len' packet to server */ 368 | 369 | } else { /* unicast */ 370 | if (!hole_punching || !memcmp(serv_hwaddr, KV_PKT_MAC_DEST(packet_in), ETH_ALEN)) { /* to server */ 371 | kv_lib_encode(packet_en, packet_in, (int)num, &aes_len, &ase_enc); 372 | 373 | sendto(cli_fd, packet_en, aes_len, 0, 374 | (struct sockaddr *)&serv_addr, slen); 375 | 376 | } else { /* to other client */ 377 | cq_req = 0; 378 | to_serv = 0; 379 | 380 | KV_CLI_LOCK(); 381 | cli = kv_lib_cli_find(KV_PKT_MAC_DEST(packet_in), cli_header); /* find dest client */ 382 | if (!cli) { 383 | clihp = (struct kv_cli_hp *)malloc(sizeof(struct kv_cli_hp)); 384 | if (clihp) { 385 | clihp->stat = KV_CLI_HPSTAT_CLOSE; /* new client */ 386 | cli = &clihp->cli; 387 | bzero(&cli->addr, sizeof(struct sockaddr_in)); 388 | memcpy(cli->hwaddr, KV_PKT_MAC_DEST(packet_in), ETH_ALEN); 389 | kv_lib_cli_add(cli, cli_header); /* add to client list */ 390 | } 391 | 392 | } else { 393 | clihp = (struct kv_cli_hp *)cli; 394 | } 395 | 396 | if (clihp) { 397 | switch (clihp->stat) { 398 | 399 | case KV_CLI_HPSTAT_CLOSE: 400 | clihp->stat = KV_CLI_HPSTAT_CQUERY; 401 | cli->alive = KV_CLI_HOLE_PUNCHING_ALIVE; 402 | cq_req = 1; /* send cquery packet */ 403 | to_serv = 1; /* send packet to server */ 404 | break; 405 | 406 | case KV_CLI_HPSTAT_CQUERY: /* in query state */ 407 | case KV_CLI_HPSTAT_HPQUERY: 408 | to_serv = 1; /* send packet to server */ 409 | break; 410 | 411 | case KV_CLI_HPSTAT_HPRESPOND: /* there is a hole punching */ 412 | break; 413 | 414 | default: 415 | to_serv = 1; /* send packet to server */ 416 | break; 417 | } 418 | 419 | } else { 420 | to_serv = 1; /* send packet to server */ 421 | } 422 | KV_CLI_UNLOCK(); 423 | 424 | if (cq_req) { 425 | memcpy(cquery_hdr.hwaddr, KV_PKT_MAC_DEST(packet_in), ETH_ALEN); 426 | 427 | kv_lib_encode(packet_en, (UINT8 *)&cquery_hdr, KV_CQUERY_LEN, &aes_len, &ase_enc); 428 | 429 | if (sendto(cli_fd, packet_en, aes_len, 0, 430 | (struct sockaddr *)&serv_addr, slen) != aes_len) { /* send to server cquery */ 431 | fprintf(stderr, "[KidVPN] Socket sendto() error(%d): %s!\n", errno, strerror(errno)); 432 | break; /* an error occur, exit! */ 433 | } 434 | } 435 | 436 | kv_lib_encode(packet_en, packet_in, (int)num, &aes_len, &ase_enc); 437 | 438 | if (to_serv) { 439 | sendto(cli_fd, packet_en, aes_len, 0, 440 | (struct sockaddr *)&serv_addr, slen); /* NOTICE: send a 'aes_len' packet to server */ 441 | } else { 442 | sendto(cli_fd, packet_en, aes_len, 0, 443 | (struct sockaddr *)&cli->addr, slen); /* NOTICE: send a 'aes_len' packet to client */ 444 | } 445 | } 446 | } 447 | } 448 | } 449 | 450 | return (0); /* exit! */ 451 | } 452 | 453 | /* 454 | * KidVPN client hello thread 455 | */ 456 | static void kv_cli_hello (void) 457 | { 458 | int i; 459 | UINT32 snum = 0; 460 | int con_cnt = 0; 461 | int aes_len; 462 | struct kv_cli_node *cli; 463 | struct kv_cli_hp *clihp; 464 | 465 | UINT32 packet_buf_en[32 >> 2]; /* need 4 bytes aligned */ 466 | UINT8 *packet_en = (UINT8 *)packet_buf_en; /* encrypt packet */ 467 | 468 | hello_hdr.cmd = KV_CMD_HELLO; 469 | hello_hdr.cmd_len = KV_HELLO_LEN; 470 | hello_hdr.magic = KV_CMD_MAGIC; 471 | 472 | for (;;) { 473 | KV_CLI_LOCK(); 474 | if (cli_alive) { 475 | if (cli_alive > KV_CLI_HELLO_PERIOD) { 476 | cli_alive -= KV_CLI_HELLO_PERIOD; 477 | } else { 478 | cli_alive = 0; 479 | con_cnt = 0; 480 | printf("[KidVPN] Server lost, re-connecting...!\n"); 481 | } 482 | 483 | } else { 484 | con_cnt++; 485 | printf("[KidVPN] Try connect server <%d times>...!\n", con_cnt); 486 | } 487 | 488 | hello_hdr.mtu = htons(vnd_mtu); 489 | KV_CLI_UNLOCK(); 490 | 491 | snum++; 492 | hello_hdr.snum = htonl(snum); 493 | 494 | kv_lib_encode(packet_en, (UINT8 *)&hello_hdr, KV_HELLO_LEN, &aes_len, &ase_enc); 495 | 496 | if (sendto(cli_fd, packet_en, aes_len, 0, 497 | (struct sockaddr *)&serv_addr, sizeof(struct sockaddr_in)) != aes_len) { /* send client hello period */ 498 | fprintf(stderr, "[KidVPN] Socket sendto() error(%d): %s!\n", errno, strerror(errno)); 499 | } 500 | 501 | KV_CLI_LOCK(); 502 | for (i = 0; i < KV_CLI_HASH_SIZE; i++) { 503 | cli = cli_header[i]; 504 | while (cli) { 505 | if (cli->alive >= KV_CLI_HELLO_PERIOD) { 506 | cli->alive -= KV_CLI_HELLO_PERIOD; 507 | if (cli->alive <= 0) { /* client timeout! */ 508 | clihp = (struct kv_cli_hp *)cli; 509 | clihp->stat = KV_CLI_HPSTAT_CLOSE; 510 | } 511 | } 512 | cli = cli->next; 513 | } 514 | } 515 | KV_CLI_UNLOCK(); 516 | 517 | #if KV_VOLUNTARILY_QUIT 518 | if (cli_exit) { 519 | break; 520 | } 521 | #endif /* KV_VOLUNTARILY_QUIT */ 522 | 523 | sleep(KV_CLI_HELLO_PERIOD); 524 | } 525 | } 526 | 527 | /* 528 | * start KidVPN client 529 | */ 530 | int kv_cli_start (int vnd_id, const char *tap_name, const unsigned char *key, unsigned int keybits, 531 | const char *server, unsigned int port, int mtu, int hole_punching) 532 | { 533 | struct addrinfo hints; 534 | struct addrinfo *phints; 535 | 536 | if (!key || !server) { 537 | return (-1); 538 | } 539 | 540 | if ((keybits != 128) && (keybits != 192) && (keybits != 256)) { 541 | fprintf(stderr, "[KidVPN] AES key bits error!\n"); 542 | return (-1); 543 | } 544 | 545 | #ifdef USE_OPENSSL 546 | if (AES_set_encrypt_key(key, keybits, &ase_enc)) { 547 | fprintf(stderr, "[KidVPN] Set AES encode key fail!\n"); 548 | return (-1); 549 | } 550 | 551 | if (AES_set_decrypt_key(key, keybits, &ase_dec)) { 552 | fprintf(stderr, "[KidVPN] Set AES decode key fail!\n"); 553 | return (-1); 554 | } 555 | 556 | #else /* USE_OPENSSL */ 557 | if (mbedtls_aes_setkey_enc(&ase_enc, key, keybits)) { 558 | fprintf(stderr, "[KidVPN] Set AES encode key fail!\n"); 559 | return (-1); 560 | } 561 | 562 | if (mbedtls_aes_setkey_dec(&ase_dec, key, keybits)) { 563 | fprintf(stderr, "[KidVPN] Set AES decode key fail!\n"); 564 | return (-1); 565 | } 566 | #endif /* !USE_OPENSSL */ 567 | 568 | #ifdef SYLIXOS 569 | serv_addr.sin_len = sizeof(struct sockaddr_in); 570 | #endif /* SYLIXOS */ 571 | 572 | serv_addr.sin_family = AF_INET; 573 | serv_addr.sin_port = htons(port); 574 | 575 | if (!inet_aton(server, &serv_addr.sin_addr)) { 576 | printf("[KidVPN] Execute a DNS query...\n"); 577 | 578 | hints.ai_family = AF_INET; 579 | hints.ai_flags = AI_CANONNAME; 580 | getaddrinfo(server, NULL, &hints, &phints); 581 | if (phints == NULL) { 582 | fprintf(stderr, "[KidVPN] Request could not find host %s ." 583 | "Please check the name and try again.\n", server); 584 | return (-1); 585 | 586 | } else { 587 | if (phints->ai_addr->sa_family == AF_INET) { 588 | serv_addr.sin_addr = ((struct sockaddr_in *)(phints->ai_addr))->sin_addr; 589 | freeaddrinfo(phints); 590 | 591 | } else { 592 | freeaddrinfo(phints); 593 | fprintf(stderr, "[KidVPN] Only support AF_INET domain!\n"); 594 | return (-1); 595 | } 596 | } 597 | } 598 | 599 | vnd_mtu = mtu; 600 | if (kv_lib_init(vnd_id, tap_name, &cli_fd, &vnd_fd, hello_hdr.hwaddr, mtu)) { /* init client */ 601 | return (-1); 602 | } 603 | 604 | if (!hole_punching) { 605 | if (connect(cli_fd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr_in))) { /* connect to server */ 606 | fprintf(stderr, "[KidVPN] Client connect() call fail(%d): %s!\n", errno, strerror(errno)); 607 | kv_lib_deinit(cli_fd, vnd_fd); 608 | return (-1); 609 | } 610 | } 611 | 612 | if (pthread_create(&t_hello, NULL, (void *(*)(void *))kv_cli_hello, NULL)) { 613 | fprintf(stderr, "[KidVPN] Can not create hello thread error(%d): %s.\n", errno, strerror(errno)); 614 | kv_lib_deinit(cli_fd, vnd_fd); 615 | return (-1); 616 | } 617 | 618 | pthread_detach(t_hello); 619 | pthread_setname_np(t_hello, "kvc_hello"); 620 | 621 | if (kv_cli_loop(hole_punching)) { /* client main loop */ 622 | kv_lib_deinit(cli_fd, vnd_fd); 623 | return (-1); 624 | } 625 | 626 | return (0); 627 | } 628 | 629 | /* 630 | * end 631 | */ 632 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | --------------------------------------------------------------------------------