├── .gitignore
├── .gitmodules
├── .travis.yml
├── CHANGES
├── COPYING
├── Makefile.am
├── README.md
├── autogen.sh
├── configure.ac
├── debian
├── README.Debian
├── changelog
├── compat
├── control
├── copyright
├── docs
├── rules
├── shadowvpn.8
├── shadowvpn.default
├── shadowvpn.init
├── shadowvpn.install
└── shadowvpn.manpages
├── dist-build
├── android-arm.sh
├── android-armv7.sh
├── android-build.sh
├── android-mips.sh
└── android-x86.sh
├── openwrt
├── Makefile
└── files
│ └── shadowvpn.init
├── packaging
├── release.sh
└── upload_openwrt.sh
├── samples
├── 30-shadowvpn
├── Makefile.am
├── chnroutes.sh
├── client.conf
├── client_down.sh
├── client_up.sh
├── darwin
│ ├── darwin_client_down.sh
│ └── darwin_client_up.sh
├── foreigh.sh
├── freebsd
│ ├── freebsd_server_down.sh
│ ├── freebsd_server_up.sh
│ └── pf.conf
├── server.conf
├── server_down.sh
├── server_up.sh
└── windows
│ ├── client.conf
│ ├── client_down.bat
│ └── client_up.bat
├── src
├── Makefile.am
├── args.c
├── args.h
├── crypto.c
├── crypto.h
├── crypto_secretbox_salsa208poly1305.c
├── crypto_secretbox_salsa208poly1305.h
├── daemon.c
├── daemon.h
├── log.c
├── log.h
├── main.c
├── nat.c
├── nat.h
├── portable_endian.h
├── shadowvpn.h
├── shell.c
├── shell.h
├── uthash.h
├── vpn.c
├── vpn.h
├── win32.c
└── win32.h
├── tests
└── concurrency.sh
└── tools
├── chnroute.txt
├── chnroutes.sh
├── foreign.sh
├── foreign.txt
├── gen_chnroutes.sh
├── gen_foreign.sh
├── gen_foreign_sh.py
├── negate_network.py
└── private.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | *.cmake
2 | *.dSYM
3 | *.exp
4 | *.la
5 | *.lo
6 | *.log
7 | *.o
8 | *.plist
9 | *.scan
10 | *.sdf
11 | *.status
12 | *.tar.*
13 | *~
14 | *.exe
15 | .DS_Store
16 | .deps
17 | .dirstamp
18 | .done
19 | .libs
20 | Build
21 | Makefile
22 | Makefile.in
23 | aclocal.m4
24 | autom4te.cache
25 | build
26 | compile
27 | confdefs.h
28 | config.*
29 | configure
30 | depcomp
31 | dist
32 | android-toolchain
33 | install-sh
34 | libtool
35 | ltmain.sh
36 | m4/argz.m4
37 | m4/libtool.m4
38 | m4/ltoptions.m4
39 | m4/ltsugar.m4
40 | m4/ltversion.m4
41 | m4/lt~obsolete.m4
42 | src/shadowvpn
43 | src/crypto-perf
44 | missing
45 | stamp-h1
46 | tags
47 | test-driver
48 | shadowvpn-android-*
49 | android-toolchain-*
50 | debian/shadowvpn.postinst.debhelper
51 | debian/shadowvpn.postrm.debhelper
52 | debian/shadowvpn.prerm.debhelper
53 | debian/shadowvpn.substvars
54 | debian/shadowvpn/
55 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "libsodium"]
2 | path = libsodium
3 | url = https://github.com/jedisct1/libsodium.git
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: c
2 |
3 | compiler:
4 | - clang
5 | - gcc
6 |
7 | before_script:
8 | - sudo apt-get install clang
9 | - git submodule init
10 | - git submodule update
11 | - ./autogen.sh
12 |
13 | script:
14 | - ./configure && make
15 | - make clean && scan-build ./configure && scan-build make
16 |
17 | env:
18 | global:
19 | - secure: "e1gTMxjeb31lbNlntCqKuc0UhXefSElcZOnAECOfm92IprOfOA8jRwlu/opXtpHJohldqag1Ujj0mzq7fy3F7vd8cLJxHVqb8x8g1l3HDa+hrydKzxkgku/V3t/ISFHdjI0L/RCNvdjUIFmVkuYTzETl/jl7RbYXMNPSdsZ8NzU="
20 |
21 |
--------------------------------------------------------------------------------
/CHANGES:
--------------------------------------------------------------------------------
1 | 0.2.1 2018-04-06
2 | - Update dependences
3 | - Use default random generator
4 |
5 | 0.2.0 2015-08-16
6 | - Add NAT support on server side
7 |
8 | 0.1.7 2015-08-06
9 | - Update configurations
10 |
11 | 0.1.6 2015-01-25
12 | - Call setsid and ignore SIGHUP in daemon mode
13 |
14 | 0.1.5 2014-12-08
15 | - Fix select: Invalid argument
16 |
17 | 0.1.4 2014-11-23
18 | - Support connecting server with multiple local ports
19 | - Minor fixes to scripts
20 |
21 | 0.1.3 2014-10-14
22 | - Support FreeBSD, OS X and Windows.
23 | - Fix some issues in example scripts.
24 |
25 | 0.1.2 2014-10-06
26 | - Support building for Android.
27 | - Fix some issues in example scripts.
28 |
29 | 0.1.1 2014-10-05
30 | - Support hotplug feature of OpenWRT
31 |
32 | 0.1.0 2014-10-03
33 | - initial version
34 |
--------------------------------------------------------------------------------
/COPYING:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/Makefile.am:
--------------------------------------------------------------------------------
1 | EXTRA_DIST = \
2 | autogen.sh \
3 | README.md \
4 | COPYING
5 |
6 | SUBDIRS = src samples
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ShadowVPN
2 | =========
3 |
4 | [![Build Status]][Travis CI]
5 |
6 | [中文说明][Chinese Readme]
7 |
8 | ShadowVPN is a fast, safe VPN based on libsodium. Designed for low end
9 | devices, i.e. OpenWRT routers.
10 |
11 | For more details, [check here][Compare].
12 |
13 | ShadowVPN is currently beta and have much work to do. If you want a stable version,
14 | please come by here a few months later.
15 |
16 | Install
17 | -------
18 |
19 | #### Debian & Ubuntu
20 |
21 | For Debian 7 and Ubuntu 12+, add the following line to `/etc/apt/sources.list`
22 |
23 | deb http://shadowvpn.org/debian wheezy main
24 |
25 | Then
26 |
27 | apt-get update && apt-get install shadowvpn
28 | service shadowvpn restart
29 |
30 | #### Unix
31 |
32 | Currently Linux, FreeBSD and OS X are supported.
33 | Download a [release] and build. Do not clone the repo, since it's not stable.
34 | Make sure to set `--sysconfdir=/etc`. You'll find conf files under `/etc`.
35 |
36 | # For Debian-based Linux
37 | sudo apt-get update
38 | sudo apt-get install build-essential automake libtool git -y
39 | ./configure --enable-static --sysconfdir=/etc
40 | make && sudo make install
41 |
42 | #### OpenWRT
43 |
44 | Download bundled [ShadowVPN with LuCI], or just [download ShadowVPN] itself,
45 |
46 | Or build ShadowVPN yourself: cd into [SDK] root, then
47 |
48 | pushd package
49 | git clone https://github.com/clowwindy/ShadowVPN.git
50 | popd
51 | make menuconfig # select Network/ShadowVPN
52 | make V=s
53 | scp bin/xxx/ShadowVPN-xxx-xxx.ipk root@192.168.1.1
54 | # then log in your box and use opkg to install that ipk file
55 |
56 | #### iOS
57 |
58 | See [iOS]
59 |
60 | #### Android
61 |
62 | See [Android]
63 |
64 | #### Windows
65 |
66 | See [Build for Windows].
67 |
68 | Configuration
69 | -------------
70 |
71 | - You can find all the conf files under `/etc/shadowvpn`.
72 | - For the client, edit `client.conf`.
73 | - For the server, edit `server.conf`.
74 | - Update `server` and `password` in those files.
75 | - The script file specified by `up` will be executed after VPN is up.
76 | - The script file specified by `down` will be executed after VPN is down.
77 | - If you need to specify routing rules, modify those scripts. You'll see a
78 | placeholder at the end of those scripts.
79 | - If you are using Windows, the IP address of TUN/TAP device `tunip` is
80 | required to be specified in the conf file.
81 | - You can [configure multiple users](https://github.com/clowwindy/ShadowVPN/wiki/Configure-Multiple-Users)
82 |
83 |
84 | Usage
85 | -----
86 |
87 | Server:
88 |
89 | sudo shadowvpn -c /etc/shadowvpn/server.conf -s start
90 | sudo shadowvpn -c /etc/shadowvpn/server.conf -s stop
91 |
92 | If you installed using apt-get, you can use `sudo service shadowvpn start` instead.
93 |
94 | Client:
95 |
96 | sudo shadowvpn -c /etc/shadowvpn/client.conf -s start
97 | sudo shadowvpn -c /etc/shadowvpn/client.conf -s stop
98 |
99 | Client(OpenWRT):
100 |
101 | /etc/init.d/shadowvpn start
102 | /etc/init.d/shadowvpn stop
103 |
104 | You can also read [LuCI Configuration].
105 |
106 | Wiki
107 | ----
108 |
109 | You can find all the documentation in the wiki:
110 | https://github.com/clowwindy/ShadowVPN/wiki
111 |
112 | License
113 | -------
114 |
115 | Copyright (C) 2015 clowwindy
116 |
117 | This program is free software: you can redistribute it and/or modify
118 | it under the terms of the GNU General Public License as published by
119 | the Free Software Foundation, either version 3 of the License, or
120 | (at your option) any later version.
121 |
122 | This program is distributed in the hope that it will be useful,
123 | but WITHOUT ANY WARRANTY; without even the implied warranty of
124 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
125 | GNU General Public License for more details.
126 |
127 | You should have received a copy of the GNU General Public License
128 | along with this program. If not, see .
129 |
130 | Bugs and Issues
131 | ----------------
132 |
133 | - [FAQ]
134 | - [Issue Tracker]
135 | - [Mailing list]
136 |
137 |
138 | [Android]: https://github.com/clowwindy/ShadowVPNAndroid
139 | [Build Status]: https://travis-ci.org/clowwindy/ShadowVPN.svg?branch=master
140 | [Build deb Package]: https://github.com/clowwindy/ShadowVPN/wiki/Building-deb-Package
141 | [Build for Windows]: https://github.com/clowwindy/ShadowVPN/wiki/Build-for-Windows
142 | [Compare]: https://github.com/clowwindy/ShadowVPN/wiki/Compared-to-Shadowsocks-and-OpenVPN
143 | [Chinese Readme]: https://github.com/clowwindy/ShadowVPN/wiki/ShadowVPN-%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E
144 | [download ShadowVPN]: https://github.com/clowwindy/ShadowVPN/releases
145 | [FAQ]: https://github.com/clowwindy/ShadowVPN/wiki/FAQ
146 | [iOS]: https://github.com/clowwindy/ShadowVPNiOS
147 | [Issue Tracker]: https://github.com/clowwindy/ShadowVPN/issues?state=open
148 | [LuCI Configuration]: https://github.com/clowwindy/ShadowVPN/wiki/Configure-Via-LuCI-on-OpenWRT
149 | [Mailing list]: http://groups.google.com/group/shadowsocks
150 | [release]: https://github.com/clowwindy/ShadowVPN/releases
151 | [SDK]: http://wiki.openwrt.org/doc/howto/obtain.firmware.sdk
152 | [ShadowVPN with LuCI]: https://github.com/aa65535/openwrt-shadowvpn
153 | [Travis CI]: https://travis-ci.org/clowwindy/ShadowVPN
154 |
--------------------------------------------------------------------------------
/autogen.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | if [ -x "`which autoreconf 2>/dev/null`" ] ; then
4 | exec autoreconf -ivf
5 | fi
6 |
7 | if glibtoolize --version > /dev/null 2>&1; then
8 | LIBTOOLIZE='glibtoolize'
9 | else
10 | LIBTOOLIZE='libtoolize'
11 | fi
12 |
13 | $LIBTOOLIZE && \
14 | aclocal && \
15 | automake --add-missing --force-missing --include-deps && \
16 | autoconf
17 |
--------------------------------------------------------------------------------
/configure.ac:
--------------------------------------------------------------------------------
1 | # -*- Autoconf -*-
2 | # Process this file with autoconf to produce a configure script.
3 |
4 | AC_PREREQ([2.65])
5 | AC_INIT([shadowvpn],[0.2.1],[clowwindy42@gmail.com])
6 | AC_CONFIG_AUX_DIR([.])
7 |
8 | AC_CONFIG_SRCDIR([src/main.c])
9 | AC_CONFIG_HEADERS([config.h])
10 |
11 | AM_INIT_AUTOMAKE([1.11 dist-bzip2 tar-ustar foreign subdir-objects])
12 |
13 | # Checks for programs.
14 | AC_PROG_CC
15 | AC_PROG_CXX
16 | AC_PROG_RANLIB
17 | AC_PROG_INSTALL
18 | LT_INIT
19 |
20 | # Checks for header files.
21 | AC_HEADER_RESOLV
22 | AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h stdlib.h string.h sys/socket.h unistd.h])
23 |
24 | # from OpenVPN configure.ac
25 | case "$host" in
26 | *-*-linux*)
27 | AC_DEFINE([TARGET_LINUX], [1], [Are we running on Linux?])
28 | AC_CHECK_HEADER([linux/if_tun.h],[],[AC_MSG_ERROR([linux/if_tun.h not found.])],[])
29 | ;;
30 | *-*-darwin*)
31 | AC_DEFINE([TARGET_DARWIN], [1], [Are we running on Mac OS X?])
32 | AC_CHECK_HEADER([net/if_utun.h],[],[AC_MSG_ERROR([Mac OS X net/if_utun.h not found.])],[])
33 | ;;
34 | *-*-freebsd*)
35 | AC_DEFINE([TARGET_FREEBSD], [1], [Are we running on FreeBSD?])
36 | AC_CHECK_HEADER([net/if_tun.h],[],[AC_MSG_ERROR([FreeBSD net/if_tun.h not found.])],[])
37 | ;;
38 | *-mingw*)
39 | AC_DEFINE([TARGET_WIN32], [1], [Are we running on Windows?])
40 | WIN32=yes
41 | LIBS="${LIBS} -lgdi32 -lws2_32"
42 | AC_CHECK_HEADERS([windows.h winsock2.h ws2tcpip.h],[],[AC_MSG_ERROR([Windows headers not found.])],[])
43 | ;;
44 | *)
45 | AC_DEFINE([TARGET_UNKNOWN], [1], [Unknown platform ?])
46 | esac
47 |
48 | AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"])
49 | AC_CHECK_HEADER([android/log.h],[CFLAGS="$CFLAGS -DHAVE_ANDROID_LOG"; LDFLAGS="$LDFLAGS -llog"],[],[])
50 |
51 | # Checks for typedefs, structures, and compiler characteristics.
52 | AC_TYPE_SIZE_T
53 | AC_TYPE_SSIZE_T
54 | AC_TYPE_UINT16_T
55 |
56 | # Checks for library functions.
57 | # To fix rpl_malloc undefined error in mips cross-compile enviroment.
58 | AC_CHECK_FUNCS([malloc realloc])
59 | AC_CHECK_FUNCS([inet_ntoa memset select socket strchr strdup strrchr])
60 |
61 | AC_ARG_ENABLE([debug],
62 | [ --enable-debug build with additional debugging code],
63 | [CFLAGS="$CFLAGS -g -DDEBUG"])
64 |
65 | AM_CONDITIONAL(DEBUG, test x"$debug" = x"true")
66 |
67 | # Add a option to force static link the target.
68 | AC_ARG_ENABLE([static],
69 | [ --enable-static build with static linking],
70 | [LDFLAGS="$LDFLAGS -static"])
71 |
72 | AC_ARG_ENABLE([profile],
73 | [ --enable-profile build with profile],
74 | [CFLAGS="$CFLAGS -pg"])
75 |
76 | AC_ARG_ENABLE([analyze],
77 | [ --enable-analyze build with analyze],
78 | [CC="clang --analyze"])
79 |
80 | AM_CONDITIONAL(STATIC, test x"$static" = x"true")
81 |
82 | AC_CONFIG_FILES([Makefile src/Makefile samples/Makefile])
83 | AC_CONFIG_SUBDIRS([libsodium])
84 | AC_OUTPUT
85 |
--------------------------------------------------------------------------------
/debian/README.Debian:
--------------------------------------------------------------------------------
1 | shadowvpn for Debian
2 | --------------------
3 |
4 |
5 |
6 | -- mark Thu, 16 Oct 2014 10:38:53 -0500
7 |
--------------------------------------------------------------------------------
/debian/changelog:
--------------------------------------------------------------------------------
1 | shadowvpn (0.2.1-1) unstable; urgency=low
2 |
3 | * Update dependences
4 | * Use default random generator
5 |
6 | -- pexcn Fri, 06 Apr 2018 16:08:24 +0800
7 |
8 | shadowvpn (0.2.0-1) unstable; urgency=low
9 |
10 | * Add NAT support on server side
11 |
12 | -- clowwindy Mon, 17 Aug 2015 09:51:30 +0800
13 |
14 | shadowvpn (0.1.7-1) unstable; urgency=low
15 |
16 | * Update configurations
17 |
18 | -- clowwindy Sat, 08 Aug 2015 16:24:00 +0800
19 |
20 | shadowvpn (0.1.6-1) unstable; urgency=low
21 |
22 | * Call setsid and ignore SIGHUP in daemon mode
23 |
24 | -- clowwindy Sun, 25 Jan 2015 21:46:22 +0800
25 |
26 | shadowvpn (0.1.5-1) unstable; urgency=low
27 |
28 | * Fix select: Invalid argument
29 |
30 | -- clowwindy Mon, 08 Dec 2014 11:43:00 +0800
31 |
32 | shadowvpn (0.1.4-1) unstable; urgency=low
33 |
34 | * Support connecting server with multiple local ports
35 | * Minor fixes to scripts
36 |
37 | -- clowwindy Tue, 25 Nov 2014 10:41:00 +0800
38 |
39 | shadowvpn (0.1.3-1) unstable; urgency=low
40 |
41 | * Initial release
42 |
43 | -- clowwindy Thu, 18 Oct 2014 12:31:00 +0800
44 |
--------------------------------------------------------------------------------
/debian/compat:
--------------------------------------------------------------------------------
1 | 7
2 |
--------------------------------------------------------------------------------
/debian/control:
--------------------------------------------------------------------------------
1 | Source: shadowvpn
2 | Section: net
3 | Priority: extra
4 | Maintainer: clowwindy
5 | Build-Depends: debhelper (>= 8.0.0), autotools-dev, mime-support, gawk
6 | Standards-Version: 3.9.3
7 | Homepage: https://github.com/clowwindy/ShadowVPN
8 | Vcs-Git: git://github.com/clowwindy/ShadowVPN.git
9 | Vcs-Browser: https://github.com/clowwindy/ShadowVPN
10 |
11 | Package: shadowvpn
12 | Architecture: any
13 | Depends: ${shlibs:Depends}, ${misc:Depends}, iproute, iptables
14 | Description: A fast, safe VPN based on libsodium
15 |
--------------------------------------------------------------------------------
/debian/copyright:
--------------------------------------------------------------------------------
1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
2 | Upstream-Name: shadowvpn
3 | Source: https://github.com/clowwindy/ShadowVPN
4 |
5 | Files: *
6 | Copyright: 2015 clowwindy
7 | License: GPLv3
8 |
--------------------------------------------------------------------------------
/debian/docs:
--------------------------------------------------------------------------------
1 | README.md
2 |
--------------------------------------------------------------------------------
/debian/rules:
--------------------------------------------------------------------------------
1 | #!/usr/bin/make -f
2 | # -*- makefile -*-
3 | # Sample debian/rules that uses debhelper.
4 | # This file was originally written by Joey Hess and Craig Small.
5 | # As a special exception, when this file is copied by dh-make into a
6 | # dh-make output file, you may use that output file without restriction.
7 | # This special exception was added by Craig Small in version 0.37 of dh-make.
8 |
9 | # Uncomment this to turn on verbose mode.
10 | export DH_VERBOSE=1
11 |
12 | %:
13 | dh $@
14 | override_dh_auto_configure:
15 | dh_auto_configure -- --enable-static
16 |
17 | override_dh_auto_install:
18 |
--------------------------------------------------------------------------------
/debian/shadowvpn.8:
--------------------------------------------------------------------------------
1 | .\" Hey, EMACS: -*- nroff -*-
2 | .\" (C) Copyright 2014 mark ,
3 | .\"
4 | .\" First parameter, NAME, should be all caps
5 | .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
6 | .\" other parameters are allowed: see man(7), man(1)
7 | .TH SHADOWVPN 8 "October 16, 2014"
8 | .\" Please adjust this date whenever revising the manpage.
9 | .\"
10 | .\" Some roff macros, for reference:
11 | .\" .nh disable hyphenation
12 | .\" .hy enable hyphenation
13 | .\" .ad l left justify
14 | .\" .ad b justify to both left and right margins
15 | .\" .nf disable filling
16 | .\" .fi enable filling
17 | .\" .br insert line break
18 | .\" .sp insert n+1 empty lines
19 | .\" for manpage-specific macros, see man(7)
20 | .SH NAME
21 | shadowvpn \- A fast, safe VPN based on libsodium
22 | .SH SYNOPSIS
23 | .B shadowvpn
24 | \-c config_file [\-s start/stop/restart] [\-v]
25 | .br
26 | .SH DESCRIPTION
27 | .B shadowvpn
28 | is a fast, safe VPN based on libsodium. Designed for low end devices, i.e. OpenWRT routers.
29 | .SH OPTIONS
30 | .TP
31 | .B \-h, \-\-help
32 | show this help message and exit
33 | .TP
34 | .B \-s, start/stop/restart
35 | control shadowvpn process. if omitted, will run in foreground
36 | .TP
37 | .B \-c config_file
38 | path to config file
39 | .TP
40 | .B \-v
41 | verbose logging
42 | .SH SEE ALSO
43 | .br
44 | The programs are documented fully by
45 | .IR "Clowwindy "
46 | .br
47 | You can find all the documentation in the wiki: https://github.com/clowwindy/ShadowVPN/wiki
48 |
49 |
--------------------------------------------------------------------------------
/debian/shadowvpn.default:
--------------------------------------------------------------------------------
1 | # Defaults for shadowvpn initscript
2 | # sourced by /etc/init.d/shadowvpn
3 | # installed at /etc/default/shadowvpn by the maintainer scripts
4 |
5 | #
6 | # This is a POSIX shell fragment
7 | #
8 |
9 | # Additional options that are passed to the Daemon.
10 | DAEMON_OPTS=""
11 |
12 | # Server configuration file
13 | CONFFILE="/etc/shadowvpn/server.conf"
14 |
--------------------------------------------------------------------------------
/debian/shadowvpn.init:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | ### BEGIN INIT INFO
3 | # Provides: shadowvpn
4 | # Required-Start: $network $local_fs
5 | # Required-Stop:
6 | # Default-Start: 2 3 4 5
7 | # Default-Stop: 0 1 6
8 | # Short-Description:
9 | # Description:
10 | # <...>
11 | # <...>
12 | ### END INIT INFO
13 |
14 | # Author: mark
15 |
16 | # PATH should only include /usr/* if it runs after the mountnfs.sh script
17 | PATH=/sbin:/usr/sbin:/bin:/usr/bin
18 | DESC=shadowvpn # Introduce a short description here
19 | NAME=shadowvpn # Introduce the short server's name here
20 | DAEMON=/usr/bin/shadowvpn # Introduce the server's location here
21 | DAEMON_ARGS=start # Arguments to run the daemon with
22 | PIDFILE=/var/run/$NAME.pid
23 | SCRIPTNAME=/etc/init.d/$NAME
24 |
25 | # Exit if the package is not installed
26 | [ -x $DAEMON ] || exit 0
27 |
28 | # Read configuration variable file if it is present
29 | [ -r /etc/default/$NAME ] && . /etc/default/$NAME
30 |
31 | # Load the VERBOSE setting and other rcS variables
32 | . /lib/init/vars.sh
33 |
34 | # Define LSB log_* functions.
35 | # Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
36 | . /lib/lsb/init-functions
37 |
38 | #
39 | # Function that starts the daemon/service
40 | #
41 | do_start()
42 | {
43 | # Return
44 | # 0 if daemon has been started
45 | # 1 if daemon was already running
46 | # 2 if daemon could not be started
47 | start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
48 | || return 1
49 | start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
50 | -c $CONFFILE -s $DAEMON_ARGS \
51 | || return 2
52 | # Add code here, if necessary, that waits for the process to be ready
53 | # to handle requests from services started subsequently which depend
54 | # on this one. As a last resort, sleep for some time.
55 | }
56 |
57 | #
58 | # Function that stops the daemon/service
59 | #
60 | do_stop()
61 | {
62 | start-stop-daemon --stop --quiet --retry=TERM/30 --pidfile $PIDFILE --name $NAME
63 | RETVAL="$?"
64 | [ "$RETVAL" = 2 ] && return 2
65 | start-stop-daemon --stop --quiet --oknodo --retry=KILL/5 --exec $DAEMON
66 | [ "$?" = 2 ] && return 2
67 | # Many daemons don't delete their pidfiles when they exit.
68 | rm -f $PIDFILE
69 | return "$RETVAL"
70 | }
71 |
72 | #
73 | # Function that sends a SIGHUP to the daemon/service
74 | #
75 | do_reload() {
76 | #
77 | # If the daemon can reload its configuration without
78 | # restarting (for example, when it is sent a SIGHUP),
79 | # then implement that here.
80 | #
81 | start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
82 | return 0
83 | }
84 |
85 | case "$1" in
86 | start)
87 | [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
88 | do_start
89 | case "$?" in
90 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
91 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
92 | esac
93 | ;;
94 | stop)
95 | [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
96 | do_stop
97 | case "$?" in
98 | 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
99 | 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
100 | esac
101 | ;;
102 | status)
103 | status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
104 | ;;
105 | #reload|force-reload)
106 | #
107 | # If do_reload() is not implemented then leave this commented out
108 | # and leave 'force-reload' as an alias for 'restart'.
109 | #
110 | #log_daemon_msg "Reloading $DESC" "$NAME"
111 | #do_reload
112 | #log_end_msg $?
113 | #;;
114 | restart)
115 | #
116 | # If the "reload" option is implemented then remove the
117 | # 'force-reload' alias
118 | #
119 | log_daemon_msg "Restarting $DESC" "$NAME"
120 | do_stop
121 | case "$?" in
122 | 0|1)
123 | do_start
124 | case "$?" in
125 | 0) log_end_msg 0 ;;
126 | 1) log_end_msg 1 ;; # Old process is still running
127 | *) log_end_msg 1 ;; # Failed to start
128 | esac
129 | ;;
130 | *)
131 | # Failed to stop
132 | log_end_msg 1
133 | ;;
134 | esac
135 | ;;
136 | *)
137 | #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
138 | echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
139 | exit 3
140 | ;;
141 | esac
142 |
143 | :
144 |
--------------------------------------------------------------------------------
/debian/shadowvpn.install:
--------------------------------------------------------------------------------
1 | src/shadowvpn usr/bin/
2 | samples/server.conf etc/shadowvpn/
3 | samples/server_up.sh etc/shadowvpn/
4 | samples/server_down.sh etc/shadowvpn/
5 | samples/client.conf etc/shadowvpn/
6 | samples/client_up.sh etc/shadowvpn/
7 | samples/client_down.sh etc/shadowvpn/
8 |
--------------------------------------------------------------------------------
/debian/shadowvpn.manpages:
--------------------------------------------------------------------------------
1 | debian/shadowvpn.8
2 |
--------------------------------------------------------------------------------
/dist-build/android-arm.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | export CFLAGS="-Os -mthumb -marm -march=armv6"
3 | TARGET_ARCH=arm HOST_COMPILER=arm-linux-androideabi "$(dirname "$0")/android-build.sh"
4 |
--------------------------------------------------------------------------------
/dist-build/android-armv7.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | export CFLAGS="-Os -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -marm -march=armv7-a"
3 | TARGET_ARCH=armv7 HOST_COMPILER=arm-linux-androideabi "$(dirname "$0")/android-build.sh"
4 |
--------------------------------------------------------------------------------
/dist-build/android-build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # this script is based on build script of
3 | # libsodium
4 |
5 | if [ -z "$ANDROID_NDK_HOME" ]; then
6 | echo "You should probably set ANDROID_NDK_HOME to the directory containing"
7 | echo "the Android NDK"
8 | exit
9 | fi
10 |
11 | if [ ! -f ./configure ]; then
12 | echo "Can't find ./configure. Wrong directory or haven't run autogen.sh?"
13 | exit 1
14 | fi
15 |
16 | if [ "x$TARGET_ARCH" = 'x' ] || [ "x$HOST_COMPILER" = 'x' ]; then
17 | echo "You shouldn't use android-build.sh directly, use android-[arch].sh instead"
18 | exit 1
19 | fi
20 |
21 | export MAKE_TOOLCHAIN="${ANDROID_NDK_HOME}/build/tools/make-standalone-toolchain.sh"
22 |
23 | export PREFIX="$(pwd)/shadowvpn-android-${TARGET_ARCH}"
24 | export TOOLCHAIN_DIR="$(pwd)/android-toolchain-${TARGET_ARCH}"
25 | export PATH="${PATH}:${TOOLCHAIN_DIR}/bin"
26 |
27 | # Clean up before build
28 | rm -rf "${TOOLCHAIN_DIR}" "${PREFIX}"
29 |
30 | $MAKE_TOOLCHAIN --platform="${NDK_PLATFORM:-android-14}" \
31 | --arch="$TARGET_ARCH" \
32 | --install-dir="$TOOLCHAIN_DIR" && \
33 | ./configure --host="${HOST_COMPILER}" \
34 | --with-sysroot="${TOOLCHAIN_DIR}/sysroot" \
35 | --prefix="${PREFIX}" \
36 | --disable-soname-versions && \
37 | make clean && \
38 | make -j3 install && \
39 | echo "shadowvpn has been installed into $PREFIX"
40 |
--------------------------------------------------------------------------------
/dist-build/android-mips.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | export CFLAGS="-Os"
3 | TARGET_ARCH=mips HOST_COMPILER=mipsel-linux-android "$(dirname "$0")/android-build.sh"
4 |
--------------------------------------------------------------------------------
/dist-build/android-x86.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | export CFLAGS="-Os"
3 | TARGET_ARCH=x86 HOST_COMPILER=i686-linux-android "$(dirname "$0")/android-build.sh"
4 |
--------------------------------------------------------------------------------
/openwrt/Makefile:
--------------------------------------------------------------------------------
1 | include $(TOPDIR)/rules.mk
2 |
3 | PKG_NAME:=ShadowVPN
4 | PKG_VERSION:=0.2.1
5 | PKG_RELEASE=$(PKG_SOURCE_VERSION)
6 |
7 | PKG_SOURCE_URL:=https://github.com/clowwindy/ShadowVPN/releases/download/$(PKG_VERSION)
8 | PKG_SOURCE:=shadowvpn-$(PKG_VERSION).tar.gz
9 |
10 | PKG_MAINTAINER:=clowwindy
11 | PKG_LICENSE:=MIT
12 | PKG_LICENSE_FILES:=LICENSE
13 |
14 | PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/shadowvpn-$(PKG_VERSION)
15 |
16 | PKG_INSTALL:=1
17 | PKG_FIXUP:=autoreconf
18 | PKG_USE_MIPS16:=0
19 | PKG_BUILD_PARALLEL:=1
20 |
21 | include $(INCLUDE_DIR)/package.mk
22 |
23 | define Package/ShadowVPN/Default
24 | SECTION:=net
25 | CATEGORY:=Network
26 | TITLE:=ShadowVPN
27 | DEPENDS:=+kmod-tun +ip
28 | URL:=https://github.com/clowwindy/ShadowVPN
29 | endef
30 |
31 | define Package/ShadowVPN
32 | $(call Package/ShadowVPN/Default)
33 | endef
34 |
35 | define Package/ShadowVPN/description
36 | A fast, safe VPN based on libsodium
37 | endef
38 |
39 | define Package/ShadowVPN/conffiles
40 | /etc/shadowvpn/client.conf
41 | /etc/shadowvpn/client_up.sh
42 | /etc/shadowvpn/client_down.sh
43 | endef
44 |
45 | define Package/ShadowVPN/install
46 | $(INSTALL_DIR) $(1)/etc/init.d
47 | $(INSTALL_DIR) $(1)/etc/shadowvpn
48 | $(INSTALL_DIR) $(1)/etc/hotplug.d/iface
49 | $(INSTALL_CONF) $(PKG_BUILD_DIR)/samples/client.conf $(1)/etc/shadowvpn/client.conf
50 | $(INSTALL_CONF) $(PKG_BUILD_DIR)/samples/client_up.sh $(1)/etc/shadowvpn/client_up.sh
51 | $(INSTALL_CONF) $(PKG_BUILD_DIR)/samples/client_down.sh $(1)/etc/shadowvpn/client_down.sh
52 | $(INSTALL_CONF) $(PKG_BUILD_DIR)/samples/30-shadowvpn $(1)/etc/hotplug.d/iface/30-shadowvpn
53 | $(INSTALL_BIN) ./files/shadowvpn.init $(1)/etc/init.d/shadowvpn
54 | $(INSTALL_DIR) $(1)/usr/bin
55 | $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/shadowvpn $(1)/usr/bin
56 | endef
57 |
58 | $(eval $(call BuildPackage,ShadowVPN))
59 |
--------------------------------------------------------------------------------
/openwrt/files/shadowvpn.init:
--------------------------------------------------------------------------------
1 | #!/bin/sh /etc/rc.common
2 | # shadowvpn init script
3 |
4 | START=90
5 | STOP=15
6 | EXTRA_COMMANDS="restart"
7 |
8 | start()
9 | {
10 | shadowvpn \
11 | -c /etc/shadowvpn/client.conf \
12 | -s start
13 | }
14 |
15 | boot()
16 | {
17 | if [ ! -c "/dev/net/tun" ]; then
18 | mkdir -p /dev/net
19 | mknod /dev/net/tun c 10 200
20 | chmod 0666 /dev/net/tun
21 | fi
22 | start
23 | }
24 |
25 | stop()
26 | {
27 | shadowvpn \
28 | -c /etc/shadowvpn/client.conf \
29 | -s stop
30 | }
31 |
32 | restart()
33 | {
34 | shadowvpn \
35 | -c /etc/shadowvpn/client.conf \
36 | -s restart
37 | }
38 |
--------------------------------------------------------------------------------
/packaging/release.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ $# -ne 1 ]; then
4 | echo usage: release.sh version
5 | exit 1
6 | fi
7 |
8 | VERSION=$1
9 |
10 | API_JSON=$(printf '{"tag_name": "%s","target_commitish": "master","name": "%s","body": "","draft": false,"prerelease": false}' $VERSION $VERSION)
11 | ID=`curl -v --data "$API_JSON" https://api.github.com/repos/clowwindy/ShadowVPN/releases?access_token=$GITHUB_TOKEN | python -c 'import json,sys;print json.load(sys.stdin)["id"]'`
12 |
13 | curl -v -H "Content-Type: application/x-tar" \
14 | -H "Authorization: token $GITHUB_TOKEN" \
15 | --data-binary "@shadowvpn-$VERSION.tar.gz" \
16 | https://uploads.github.com/repos/clowwindy/ShadowVPN/releases/$ID/assets?name=shadowvpn-$VERSION.tar.gz
17 |
18 |
--------------------------------------------------------------------------------
/packaging/upload_openwrt.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [ $# -ne 1 ]; then
4 | echo usage: release.sh version
5 | exit 1
6 | fi
7 |
8 | VERSION=$1
9 |
10 | ID=`curl -v https://api.github.com/repos/clowwindy/ShadowVPN/releases?access_token=$GITHUB_TOKEN | python -c "import json,sys
11 | for item in json.load(sys.stdin):
12 | if item['tag_name']=='$VERSION':
13 | print item['id']
14 | break"`
15 | echo $ID
16 |
17 | pushd dist
18 |
19 | for file in `ls *$VERSION*`; do
20 | curl -v -H "Content-Type: application/x-zip" \
21 | -H "Authorization: token $GITHUB_TOKEN" \
22 | --data-binary "@$file" \
23 | https://uploads.github.com/repos/clowwindy/ShadowVPN/releases/$ID/assets?name=$file
24 | done
25 |
26 | popd
27 |
--------------------------------------------------------------------------------
/samples/30-shadowvpn:
--------------------------------------------------------------------------------
1 | # hotplug.d for OpenWRT
2 |
3 | [ ifup = "$ACTION" ] && {
4 | [ wan = "$INTERFACE" ] && {
5 | /etc/init.d/shadowvpn start
6 | }
7 | }
8 | [ ifdown = "$ACTION" ] && {
9 | [ wan = "$INTERFACE" ] && {
10 | /etc/init.d/shadowvpn stop
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/samples/Makefile.am:
--------------------------------------------------------------------------------
1 | shadowvpnconfdir = $(sysconfdir)/shadowvpn
2 |
3 | shadowvpnconf_DATA = client.conf \
4 | client_down.sh \
5 | client_up.sh \
6 | server.conf \
7 | server_down.sh \
8 | server_up.sh
9 |
10 | EXTRA_DIST = $(shadowvpnconf_DATA) \
11 | 30-shadowvpn \
12 | freebsd/freebsd_server_down.sh \
13 | freebsd/freebsd_server_up.sh \
14 | freebsd/pf.conf \
15 | darwin/darwin_client_down.sh \
16 | darwin/darwin_client_up.sh
17 |
--------------------------------------------------------------------------------
/samples/chnroutes.sh:
--------------------------------------------------------------------------------
1 | ../tools/chnroutes.sh
--------------------------------------------------------------------------------
/samples/client.conf:
--------------------------------------------------------------------------------
1 | # ShadowVPN config example
2 |
3 | # Notice: do not put space before or after "="
4 |
5 | # Server listen address
6 | server=127.0.0.1
7 |
8 | # Server listen port
9 | port=1123
10 |
11 | # Identify a user. Must be HEX of 8 bytes. You can generate on by running:
12 | # xxd -l 8 -p /dev/random
13 | # See `net` for more information.
14 | # user_token=7e335d67f1dc2c01
15 |
16 | # Password to use to encrypt traffic. You can generate one by running:
17 | # dd if=/dev/urandom bs=64 count=1 | md5sum
18 | password=my_password
19 |
20 | # Server or client mode
21 | mode=client
22 |
23 | # Max source ports. Must be the SAME with server or VPN won't work properly.
24 | concurrency=1
25 |
26 | # MTU of VPN tunnel device. Use the following formula to calculate:
27 | # 1492 (Ethernet) - 20 (IPv4, or 40 for IPv6) - 8 (UDP) - 32 (ShadowVPN)
28 | mtu=1432
29 |
30 | # Tunnel device name. tunX for Linux or BSD, utunX for Darwin.
31 | intf=tun0
32 |
33 | # Local IP and subnet of the VPN tunnel.
34 | # If user_token is specified, NAT mode will be enabled on server side, and
35 | # the client does not need to have the same network with the server.
36 | net=10.7.0.2/24
37 |
38 | # Script to run after VPN is created. All key-value pairs (except password) in
39 | # this file will be passed to the script as environment variables. Use this
40 | # script to set up routes, turn on NAT, etc.
41 | up=/etc/shadowvpn/client_up.sh
42 |
43 | # Script to run before stopping VPN. All key-value pairs (except password) in
44 | # this file will be passed to the script as environment variables. Use this
45 | # script to restore routes, turn off NAT, etc.
46 | down=/etc/shadowvpn/client_down.sh
47 |
48 | # PID file path
49 | pidfile=/var/run/shadowvpn.pid
50 |
51 | # Log file path
52 | logfile=/var/log/shadowvpn.log
53 |
--------------------------------------------------------------------------------
/samples/client_down.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # This script will be executed when client is down. All key value pairs (except
4 | # password) in ShadowVPN config file will be passed to this script as
5 | # environment variables.
6 |
7 | # Turn off IP forwarding
8 | #sysctl -w net.ipv4.ip_forward=0
9 |
10 | # turn off NAT over VPN
11 | iptables -t nat -D POSTROUTING -o $intf -j MASQUERADE
12 | iptables -D FORWARD -i $intf -m state --state RELATED,ESTABLISHED -j ACCEPT
13 | iptables -D FORWARD -o $intf -j ACCEPT
14 |
15 | # Restore routing table
16 | ip route del $server
17 | ip route del 0/1
18 | ip route del 128/1
19 |
20 | echo $0 done
21 |
--------------------------------------------------------------------------------
/samples/client_up.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # This script will be executed when client is up. All key value pairs (except
4 | # password) in ShadowVPN config file will be passed to this script as
5 | # environment variables.
6 |
7 | # Turn on IP forwarding
8 | sysctl -w net.ipv4.ip_forward=1
9 |
10 | # Configure IP address and MTU of VPN interface
11 | ip addr add $net dev $intf
12 | ip link set $intf mtu $mtu
13 | ip link set $intf up
14 |
15 | # Turn on NAT over VPN
16 | iptables -t nat -A POSTROUTING -o $intf -j MASQUERADE
17 | iptables -I FORWARD 1 -i $intf -m state --state RELATED,ESTABLISHED -j ACCEPT
18 | iptables -I FORWARD 1 -o $intf -j ACCEPT
19 |
20 | # Direct route to VPN server's public IP via current gateway
21 | ip route add $server via $(ip route show 0/0 | sort -k 7 | head -n 1 | sed -e 's/.* via \([^ ]*\).*/\1/')
22 |
23 | # Shadow default route using two /1 subnets
24 | ip route add 0/1 dev $intf
25 | ip route add 128/1 dev $intf
26 |
27 | echo $0 done
28 |
--------------------------------------------------------------------------------
/samples/darwin/darwin_client_down.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # example client down script for darwin
4 | # will be executed when client is down
5 |
6 | # all key value pairs in ShadowVPN config file will be passed to this script
7 | # as environment variables, except password
8 |
9 | # user-defined variables
10 | remote_tun_ip=10.7.0.1
11 |
12 | # revert routing table
13 | echo reverting default route
14 | route delete -net 128.0.0.0 $remote_tun_ip -netmask 128.0.0.0
15 | route delete -net 0.0.0.0 $remote_tun_ip -netmask 128.0.0.0
16 | route delete -net $server
17 |
18 | # revert dns server
19 | networksetup -setdnsservers Wi-Fi empty
20 |
21 | echo $0 done
22 |
--------------------------------------------------------------------------------
/samples/darwin/darwin_client_up.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # example client up script for darwin
4 | # will be executed when client is up
5 |
6 | # all key value pairs in ShadowVPN config file will be passed to this script
7 | # as environment variables, except password
8 |
9 | # user-defined variables
10 | local_tun_ip=10.7.0.2
11 | remote_tun_ip=10.7.0.1
12 | dns_server=8.8.8.8
13 |
14 | # get current gateway
15 | orig_gw=$(netstat -nr | grep --color=never '^default' | grep -v 'utun' | sed 's/default *\([0-9\.]*\) .*/\1/' | head -1)
16 | route add -net $server $orig_gw
17 |
18 | # configure IP address and MTU of VPN interface
19 | ifconfig $intf $local_tun_ip $remote_tun_ip mtu $mtu netmask 255.255.255.0 up
20 |
21 | # change routing table
22 | echo changing default route
23 | route add -net 128.0.0.0 $remote_tun_ip -netmask 128.0.0.0
24 | route add -net 0.0.0.0 $remote_tun_ip -netmask 128.0.0.0
25 | route add -net $remote_tun_ip $orig_gw -netmask 255.255.255.255
26 | echo default route changed to $remote_tun_ip
27 |
28 | # change dns server
29 | networksetup -setdnsservers Wi-Fi $dns_server
30 |
31 | echo $0 done
32 |
--------------------------------------------------------------------------------
/samples/foreigh.sh:
--------------------------------------------------------------------------------
1 | ../tools/foreign.sh
--------------------------------------------------------------------------------
/samples/freebsd/freebsd_server_down.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # example server down script
4 | # will be executed when server is down
5 |
6 | ifconfig $intf down
7 |
8 | # stop pf nat
9 | #pfctl -d
10 |
11 | echo $0 done
12 |
--------------------------------------------------------------------------------
/samples/freebsd/freebsd_server_up.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -x
4 | # example server up script
5 | # will be executed when server is up
6 |
7 | # all key value pairs in ShadowVPN config file will be passed to this script
8 | # as environment variables, except password
9 |
10 | # turn on IP forwarding
11 | sysctl -w net.inet.ip.forwarding=1
12 |
13 | # configure IP address and MTU of VPN interface
14 | ifconfig $intf 10.7.0.1 10.7.0.1 netmask 255.255.255.0 mtu $mtu up
15 | route add -net 10.7.0.0/24 10.7.0.1
16 |
17 | # copy pf.conf to /etc
18 | # pfctl -F all -f /etc/pf.conf
19 | # pfctl -e
20 |
21 | echo $0 done
22 |
--------------------------------------------------------------------------------
/samples/freebsd/pf.conf:
--------------------------------------------------------------------------------
1 |
2 | int_if = "em0"
3 | tun_if = "tun0"
4 |
5 | # from http://www.openbsd.gr/faq/pf/scrub.html
6 | scrub in on $tun_if all fragment reassemble min-ttl 15 max-mss 1400
7 |
8 | nat on $int_if inet from !($int_if) to any -> ($int_if)
9 |
10 |
--------------------------------------------------------------------------------
/samples/server.conf:
--------------------------------------------------------------------------------
1 | # ShadowVPN config example
2 |
3 | # Notice: do not put space before or after "="
4 |
5 | # Server listen address
6 | server=0.0.0.0
7 |
8 | # Server listen port
9 | port=1123
10 |
11 | # Users allowed. Each must be HEX of 8 bytes. You can generate on by running:
12 | # xxd -l 8 -p /dev/random
13 | # See `net` for more information.
14 | # user_token=7e335d67f1dc2c01,ff593b9e6abeb2a5,e3c7b8db40a96105
15 |
16 | # Password to encrypt traffic. You can generate one by running:
17 | # dd if=/dev/urandom bs=64 count=1 | md5sum
18 | password=my_password
19 |
20 | # Server or client mode
21 | mode=server
22 |
23 | # Max source ports. Must be the SAME with client or it won't work properly.
24 | concurrency=1
25 |
26 | # MTU of VPN tunnel device. Use the following formula to calculate:
27 | # 1492 (Ethernet) - 20 (IPv4, or 40 for IPv6) - 8 (UDP) - 32 (ShadowVPN)
28 | mtu=1432
29 |
30 | # Tunnel device name. tunX for Linux or BSD, utunX for Darwin.
31 | intf=tun0
32 |
33 | # Local IP and subnet of the VPN tunnel.
34 | #
35 | # If user_token is specified, NAT mode will be enabled on server side, and
36 | # the client does not need to have the same network with the server.
37 | # In NAT mode, each user will be assigned an IP automatically.
38 | # for example:
39 | # tun0 is 10.7.0.1
40 | # client IPs will be 10.7.0.2, 10.7.0.3, 10.7.0.4, etc
41 | # You'll see them in the log when ShadowVPN starts with -v:
42 | # assigning 10.7.0.2 to user 7e335d67f1dc2c01
43 | # assigning 10.7.0.3 to user ff593b9e6abeb2a5
44 | # assigning 10.7.0.4 to user e3c7b8db40a96105
45 | # VPN started
46 |
47 | net=10.7.0.1/16
48 |
49 | # Script to run after VPN is created. All key-value pairs (except password) in
50 | # this file will be passed to the script as environment variables. Use this
51 | # script to set up routes, turn on NAT, etc.
52 | up=/etc/shadowvpn/server_up.sh
53 |
54 | # Script to run before stopping VPN. All key-value pairs (except password) in
55 | # this file will be passed to the script as environment variables. Use this
56 | # script to restore routes, turn off NAT, etc.
57 | down=/etc/shadowvpn/server_down.sh
58 |
59 | # PID file path
60 | pidfile=/var/run/shadowvpn.pid
61 |
62 | # Log file path
63 | logfile=/var/log/shadowvpn.log
64 |
--------------------------------------------------------------------------------
/samples/server_down.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # This script will be executed when server is down. All key value pairs (except
4 | # password) in ShadowVPN config file will be passed to this script as
5 | # environment variables.
6 |
7 | # Turn off IP forwarding
8 | #sysctl -w net.ipv4.ip_forward=0
9 |
10 | # Turn off NAT over VPN
11 | iptables -t nat -D POSTROUTING -s $net ! -d $net -m comment --comment "shadowvpn" -j MASQUERADE
12 | iptables -D FORWARD -s $net -m state --state RELATED,ESTABLISHED -j ACCEPT
13 | iptables -D FORWARD -d $net -j ACCEPT
14 |
15 | # Turn off MSS fix (MSS = MTU - TCP header - IP header)
16 | iptables -t mangle -D FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
17 |
18 | echo $0 done
19 |
--------------------------------------------------------------------------------
/samples/server_up.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # This script will be executed when server is up. All key value pairs (except
4 | # password) in ShadowVPN config file will be passed to this script as
5 | # environment variables.
6 |
7 | # Turn on IP forwarding
8 | sysctl -w net.ipv4.ip_forward=1
9 |
10 | # Configure IP address and MTU of VPN interface
11 | ip addr add $net dev $intf
12 | ip link set $intf mtu $mtu
13 | ip link set $intf up
14 |
15 | # turn on NAT over VPN
16 | if !(iptables-save -t nat | grep -q "shadowvpn"); then
17 | iptables -t nat -A POSTROUTING -s $net ! -d $net -m comment --comment "shadowvpn" -j MASQUERADE
18 | fi
19 | iptables -A FORWARD -s $net -m state --state RELATED,ESTABLISHED -j ACCEPT
20 | iptables -A FORWARD -d $net -j ACCEPT
21 |
22 | # Turn on MSS fix (MSS = MTU - TCP header - IP header)
23 | iptables -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
24 |
25 | echo $0 done
26 |
--------------------------------------------------------------------------------
/samples/windows/client.conf:
--------------------------------------------------------------------------------
1 | # ShadowVPN config example for windows
2 |
3 | # notice: do not put space before or after "="
4 |
5 | # server listen address
6 | server=127.0.0.1
7 |
8 | # server listen port
9 | port=1123
10 |
11 | # password to use
12 | password=my_password
13 |
14 | # server or client
15 | mode=client
16 |
17 | # local tunnel ip address (required)
18 | tunip=10.7.0.1
19 |
20 | # Max source ports. Must be the SAME with server or VPN won't work properly.
21 | concurrency=1
22 |
23 | # the MTU of VPN device
24 | # 1492(Ethernet) - 20(IPv4, or 40 for IPv6) - 8(UDP) - 24(ShadowVPN)
25 | mtu=1440
26 |
27 | # tun/tap interface name
28 | intf=Ethernet 2
29 |
30 | # the script to run after VPN is created
31 | # use this script to set up routes, NAT, etc
32 | # configuration in this file will be set as environment variables
33 | up=client_up.bat
34 |
35 | # the script to run before stopping VPN
36 | # use this script to restore routes, NAT, etc
37 | # configuration in this file will be set as environment variables
38 | down=client_down.bat
39 |
--------------------------------------------------------------------------------
/samples/windows/client_down.bat:
--------------------------------------------------------------------------------
1 | @ECHO off
2 | REM example client down script for windows
3 | REM will be executed when client is down
4 |
5 | REM all key value pairs in ShadowVPN config file will be passed to this script
6 | REM as environment variables, except password
7 |
8 | REM user-defined variables
9 | SET remote_tun_ip=10.7.0.0
10 | SET orig_intf="Ethernet"
11 |
12 | REM revert ip settings
13 | netsh interface ip set interface %orig_intf% ignoredefaultroutes=disabled > NUL
14 | netsh interface ip set address name="%intf%" dhcp > NUL
15 |
16 | REM revert routing table
17 | ECHO reverting default route
18 | route delete 0.0.0.0 mask 128.0.0.0 %remote_tun_ip% > NUL
19 | route delete 128.0.0.0 mask 128.0.0.0 %remote_tun_ip% > NUL
20 | route delete %server% > NUL
21 |
22 | REM revert dns server
23 | netsh interface ip set dns name="%intf%" source=dhcp > NUL
24 | netsh interface ip set dns name="%orig_intf%" source=dhcp > NUL
25 |
26 | ECHO %0 done
27 |
--------------------------------------------------------------------------------
/samples/windows/client_up.bat:
--------------------------------------------------------------------------------
1 | @ECHO off
2 | REM example client up script for windows
3 | REM will be executed when client is up
4 |
5 | REM all key value pairs in ShadowVPN config file will be passed to this script
6 | REM as environment variables, except password
7 |
8 | REM user-defined variables
9 | SET remote_tun_ip=10.7.0.0
10 | SET dns_server=8.8.8.8
11 | SET orig_intf="Ethernet"
12 |
13 | REM exclude remote server in routing table
14 | for /F "tokens=3" %%* in ('route print ^| findstr "\<0.0.0.0\>"') do set "orig_gw=%%*"
15 | route add %server% %orig_gw% metric 5 > NUL
16 |
17 | REM configure IP address and MTU of VPN interface
18 | netsh interface ip set interface %orig_intf% ignoredefaultroutes=enabled > NUL
19 | netsh interface ip set address name="%intf%" static %tunip% 255.255.255.0 > NUL
20 | netsh interface ipv4 set subinterface "%intf%" mtu=%mtu% > NUL
21 |
22 | REM change routing table
23 | ECHO changing default route
24 | REM checking if winxp
25 | ver | find "5.1" > NUL
26 | if %ERRORLEVEL%==0 (
27 | route add 128.0.0.0 mask 128.0.0.0 %remote_tun_ip% metric 6 > NUL
28 | route add 0.0.0.0 mask 128.0.0.0 %remote_tun_ip% metric 6 > NUL
29 | ) else (
30 | netsh interface ipv4 add route 128.0.0.0/1 "%intf%" %remote_tun_ip% metric=6 > NUL
31 | netsh interface ipv4 add route 0.0.0.0/1 "%intf%" %remote_tun_ip% metric=6 > NUL
32 | )
33 | ECHO default route changed to %remote_tun_ip%
34 |
35 | REM change dns server
36 | netsh interface ip set dns name="%intf%" static %dns_server% > NUL
37 | netsh interface ip set dns name="%orig_intf%" static %dns_server% > NUL
38 |
39 | ECHO %0 done
40 |
--------------------------------------------------------------------------------
/src/Makefile.am:
--------------------------------------------------------------------------------
1 | bin_PROGRAMS = shadowvpn
2 |
3 | lib_LTLIBRARIES = libshadowvpn.la
4 |
5 | SUBDIRS = ../libsodium
6 |
7 | AM_CFLAGS = -I$(srcdir)/../libsodium/src/libsodium/include
8 |
9 | libshadowvpn_la_SOURCES = log.c \
10 | log.h \
11 | crypto_secretbox_salsa208poly1305.h \
12 | crypto_secretbox_salsa208poly1305.c \
13 | crypto.h \
14 | crypto.c \
15 | shell.h \
16 | shell.c \
17 | nat.h \
18 | nat.c \
19 | vpn.h \
20 | vpn.c \
21 | args.h \
22 | args.c \
23 | daemon.h \
24 | daemon.c \
25 | shadowvpn.h \
26 | uthash.h \
27 | portable_endian.h
28 |
29 | if WIN32
30 | libshadowvpn_la_SOURCES += win32.c win32.h
31 | endif
32 |
33 | libshadowvpn_la_LIBADD = ../libsodium/src/libsodium/libsodium.la
34 |
35 | shadowvpn_SOURCES = main.c
36 |
37 | shadowvpn_LDADD = libshadowvpn.la
38 |
--------------------------------------------------------------------------------
/src/args.c:
--------------------------------------------------------------------------------
1 | /**
2 | args.c
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | #include "shadowvpn.h"
27 |
28 | #ifndef TARGET_WIN32
29 | #include
30 | #include
31 | #include
32 | #endif
33 |
34 |
35 | static const char *help_message =
36 | "usage: shadowvpn -c config_file [-s start/stop/restart] [-v]\n"
37 | "\n"
38 | " -h, --help show this help message and exit\n"
39 | " -s start/stop/restart control shadowvpn process. if omitted, will run\n"
40 | " in foreground\n"
41 | " -c config_file path to config file\n"
42 | " -v verbose logging\n"
43 | "\n"
44 | "Online help: \n";
45 |
46 | static void print_help() __attribute__ ((noreturn));
47 |
48 | static void load_default_args(shadowvpn_args_t *args);
49 |
50 | static int process_key_value(shadowvpn_args_t *args, const char *key,
51 | const char *value);
52 |
53 | static void print_help() {
54 | printf("%s", help_message);
55 | exit(1);
56 | }
57 |
58 | static int parse_config_file(shadowvpn_args_t *args, const char *filename) {
59 | char buf[512];
60 | char *line;
61 | FILE *fp;
62 | size_t len = sizeof(buf);
63 | int lineno = 0;
64 |
65 | fp = fopen(filename, "rb");
66 | if (fp == NULL) {
67 | err("fopen");
68 | errf("Can't open config file: %s", filename);
69 | return -1;
70 | }
71 | while ((line = fgets(buf, len, fp))) {
72 | char *sp_pos;
73 | lineno++;
74 | sp_pos = strchr(line, '\r');
75 | if (sp_pos) *sp_pos = '\n';
76 | sp_pos = strchr(line, '\n');
77 | if (sp_pos) {
78 | *sp_pos = 0;
79 | } else {
80 | errf("line %d too long in %s", lineno, filename);
81 | return -1;
82 | }
83 | if (*line == 0 || *line == '#')
84 | continue;
85 | sp_pos = strchr(line, '=');
86 | if (!sp_pos) {
87 | errf("%s:%d: \"=\" is not found in this line: %s", filename, lineno,
88 | line);
89 | return -1;
90 | }
91 | *sp_pos = 0;
92 | sp_pos++;
93 | // line points to key and sp_pos points to value
94 | if (0 != process_key_value(args, line, sp_pos))
95 | return 1;
96 | }
97 | // check if every required arg is set
98 | if (!args->mode) {
99 | errf("mode not set in config file");
100 | return -1;
101 | }
102 | if (!args->server) {
103 | errf("server not set in config file");
104 | return -1;
105 | }
106 | if (!args->port) {
107 | errf("port not set in config file");
108 | return -1;
109 | }
110 | if (!args->password) {
111 | errf("password not set in config file");
112 | return -1;
113 | }
114 | #ifdef TARGET_WIN32
115 | if (!args->tun_ip) {
116 | errf("tunip not set in config file");
117 | return -1;
118 | }
119 | #endif
120 | return 0;
121 | }
122 |
123 | static int parse_user_tokens(shadowvpn_args_t *args, char *value) {
124 | char *sp_pos;
125 | char *start = value;
126 | int len = 0, i = 0;
127 | if (value == NULL) {
128 | return 0;
129 | }
130 | len++;
131 | while (*value) {
132 | if (*value == ',') {
133 | len++;
134 | }
135 | value++;
136 | }
137 | args->user_tokens_len = len;
138 | args->user_tokens = calloc(len, 8);
139 | bzero(args->user_tokens, 8 * len);
140 | value = start;
141 | while (*value) {
142 | int has_next = 0;
143 | sp_pos = strchr(value, ',');
144 | if (sp_pos > 0) {
145 | has_next = 1;
146 | *sp_pos = 0;
147 | }
148 | int p = 0;
149 | while (*value && p < 8) {
150 | unsigned int temp;
151 | int r = sscanf(value, "%2x", &temp);
152 | if (r > 0) {
153 | args->user_tokens[i][p] = temp;
154 | value += 2;
155 | p ++;
156 | } else {
157 | break;
158 | }
159 | }
160 | i++;
161 | if (has_next) {
162 | value = sp_pos + 1;
163 | } else {
164 | break;
165 | }
166 | }
167 | free(start);
168 | return 0;
169 | }
170 |
171 | static int process_key_value(shadowvpn_args_t *args, const char *key,
172 | const char *value) {
173 | if (strcmp("password", key) != 0) {
174 | // set environment variables so that up/down script can
175 | // make use of these values
176 | if (-1 == setenv(key, value, 1)) {
177 | err("setenv");
178 | return -1;
179 | }
180 | }
181 | if (strcmp("server", key) == 0) {
182 | args->server = strdup(value);
183 | } else if (strcmp("port", key) == 0) {
184 | args->port = atol(value);
185 | } else if (strcmp("concurrency", key) == 0) {
186 | errf("warning: concurrency is temporarily disabled on this version, "
187 | "make sure to set concurrency=1 on the other side");
188 | args->concurrency = atol(value);
189 | if (args->concurrency == 0) {
190 | errf("concurrency should >= 1");
191 | return -1;
192 | }
193 | if (args->concurrency > 100) {
194 | errf("concurrency should <= 100");
195 | return -1;
196 | }
197 | } else if (strcmp("password", key) == 0) {
198 | args->password = strdup(value);
199 | } else if (strcmp("user_token", key) == 0) {
200 | parse_user_tokens(args, strdup(value));
201 | }
202 | #ifndef TARGET_WIN32
203 | else if (strcmp("net", key) == 0) {
204 | char *p = strchr(value, '/');
205 | if (p) *p = 0;
206 | in_addr_t addr = inet_addr(value);
207 | if (addr == INADDR_NONE) {
208 | errf("warning: invalid net IP in config file: %s", value);
209 | }
210 | args->netip = ntohl((uint32_t)addr);
211 | }
212 | #endif
213 | else if (strcmp("mode", key) == 0) {
214 | if (strcmp("server", value) == 0) {
215 | args->mode = SHADOWVPN_MODE_SERVER;
216 | } else if (strcmp("client", value) == 0) {
217 | args->mode = SHADOWVPN_MODE_CLIENT;
218 | } else {
219 | errf("warning: unknown mode in config file: %s", value);
220 | return -1;
221 | }
222 | } else if (strcmp("mtu", key) == 0) {
223 | long mtu = atol(value);
224 | // RFC 791
225 | // in order to wrap packet of length 68, MTU should be > 68 + overhead
226 | if (mtu < 68 + SHADOWVPN_OVERHEAD_LEN) {
227 | errf("MTU %ld is too small", mtu);
228 | return -1;
229 | }
230 | if (mtu > MAX_MTU) {
231 | errf("MTU %ld is too large", mtu);
232 | return -1;
233 | }
234 | args->mtu = mtu;
235 | } else if (strcmp("intf", key) == 0) {
236 | args->intf = strdup(value);
237 | } else if (strcmp("pidfile", key) == 0) {
238 | args->pid_file = strdup(value);
239 | } else if (strcmp("logfile", key) == 0) {
240 | args->log_file = strdup(value);
241 | } else if (strcmp("up", key) == 0) {
242 | args->up_script = strdup(value);
243 | } else if (strcmp("down", key) == 0) {
244 | args->down_script = strdup(value);
245 | }
246 | #ifdef TARGET_WIN32
247 | else if (strcmp("tunip", key) == 0) {
248 | args->tun_ip = strdup(value);
249 | } else if (strcmp("tunmask", key) == 0) {
250 | args->tun_mask = (int) atol(value);
251 | } else if (strcmp("tunport", key) == 0) {
252 | args->tun_port = (int) atol(value);
253 | }
254 | #endif
255 | else {
256 | errf("warning: config key %s not recognized by shadowvpn, will be "
257 | "passed to shell scripts anyway", key);
258 | }
259 | return 0;
260 | }
261 |
262 | static void load_default_args(shadowvpn_args_t *args) {
263 | #ifdef TARGET_DARWIN
264 | args->intf = "utun0";
265 | #else
266 | args->intf = "tun0";
267 | #endif
268 | args->mtu = 1440;
269 | args->pid_file = "/var/run/shadowvpn.pid";
270 | args->log_file = "/var/log/shadowvpn.log";
271 | args->concurrency = 1;
272 | #ifdef TARGET_WIN32
273 | args->tun_mask = 24;
274 | args->tun_port = TUN_DELEGATE_PORT;
275 | #endif
276 | }
277 |
278 | int args_parse(shadowvpn_args_t *args, int argc, char **argv) {
279 | int ch;
280 | bzero(args, sizeof(shadowvpn_args_t));
281 | while ((ch = getopt(argc, argv, "hs:c:v")) != -1) {
282 | switch (ch) {
283 | case 's':
284 | if (strcmp("start", optarg) == 0)
285 | args->cmd = SHADOWVPN_CMD_START;
286 | else if (strcmp("stop", optarg) == 0)
287 | args->cmd = SHADOWVPN_CMD_STOP;
288 | else if (strcmp("restart", optarg) == 0)
289 | args->cmd = SHADOWVPN_CMD_RESTART;
290 | else {
291 | errf("unknown command %s", optarg);
292 | print_help();
293 | }
294 | break;
295 | case 'c':
296 | args->conf_file = strdup(optarg);
297 | break;
298 | case 'v':
299 | verbose_mode = 1;
300 | break;
301 | default:
302 | print_help();
303 | }
304 | }
305 | if (!args->conf_file)
306 | print_help();
307 | load_default_args(args);
308 | return parse_config_file(args, args->conf_file);
309 | }
310 |
--------------------------------------------------------------------------------
/src/args.h:
--------------------------------------------------------------------------------
1 | /**
2 | args.h
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #ifndef ARGS_H
22 | #define ARGS_H
23 |
24 | #include
25 |
26 | #define MAX_MTU 9000
27 |
28 | typedef enum {
29 | SHADOWVPN_MODE_SERVER = 1,
30 | SHADOWVPN_MODE_CLIENT = 2
31 | } shadowvpn_mode;
32 |
33 | typedef enum {
34 | SHADOWVPN_CMD_NONE = 0,
35 | SHADOWVPN_CMD_START,
36 | SHADOWVPN_CMD_STOP,
37 | SHADOWVPN_CMD_RESTART
38 | } shadowvpn_cmd;
39 |
40 | typedef struct {
41 | shadowvpn_mode mode;
42 | shadowvpn_cmd cmd;
43 | const char *conf_file;
44 | const char *pid_file;
45 | const char *log_file;
46 | const char *intf;
47 | const char *password;
48 | const char *server;
49 | uint16_t port;
50 | uint16_t mtu;
51 | uint16_t concurrency;
52 |
53 | // the ip of the "net" configuration
54 | // in host order
55 | uint32_t netip;
56 | char (*user_tokens)[8];
57 | size_t user_tokens_len;
58 |
59 | const char *up_script;
60 | const char *down_script;
61 | #ifdef TARGET_WIN32
62 | const char *tun_ip;
63 | int tun_mask;
64 | int tun_port;
65 | #endif
66 | } shadowvpn_args_t;
67 |
68 | int args_parse(shadowvpn_args_t *args, int argc, char **argv);
69 |
70 | #endif
71 |
--------------------------------------------------------------------------------
/src/crypto.c:
--------------------------------------------------------------------------------
1 | /**
2 | crypto.c
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #include
22 | #include
23 | #include "crypto_secretbox_salsa208poly1305.h"
24 |
25 | // will not copy key any more
26 | static unsigned char key[32];
27 |
28 | int crypto_init() {
29 | // set implementation here if you want to use custom random generator
30 | // while it is not recommended
31 | // https://download.libsodium.org/doc/advanced/custom_rng.html
32 | // drawbacks:
33 | // 1. not thread-safe
34 | // 2. just a boilerplate for writing implementations for embedded operating systems
35 | // 3. should rekey after fork() call
36 | if (-1 == sodium_init())
37 | return 1;
38 | return 0;
39 | }
40 |
41 | int crypto_set_password(const char *password,
42 | unsigned long long password_len) {
43 | return crypto_generichash(key, sizeof key, (unsigned char *)password,
44 | password_len, NULL, 0);
45 | }
46 |
47 | int crypto_encrypt(unsigned char *c, unsigned char *m,
48 | unsigned long long mlen) {
49 | unsigned char nonce[8];
50 | randombytes_buf(nonce, 8);
51 | int r = crypto_secretbox_salsa208poly1305(c, m, mlen + 32, nonce, key);
52 | if (r != 0) return r;
53 | // copy nonce to the head
54 | memcpy(c + 8, nonce, 8);
55 | return 0;
56 | }
57 |
58 | int crypto_decrypt(unsigned char *m, unsigned char *c,
59 | unsigned long long clen) {
60 | unsigned char nonce[8];
61 | memcpy(nonce, c + 8, 8);
62 | int r = crypto_secretbox_salsa208poly1305_open(m, c, clen + 32, nonce, key);
63 | if (r != 0) return r;
64 | return 0;
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/src/crypto.h:
--------------------------------------------------------------------------------
1 | /**
2 | crypto.h
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #ifndef CRYPTO_H
22 | #define CRYPTO_H
23 |
24 | /* call once after start */
25 | int crypto_init();
26 |
27 | // TODO use a struct to hold context instead
28 | /* call when password changed */
29 | int crypto_set_password(const char *password,
30 | unsigned long long password_len);
31 |
32 | int crypto_encrypt(unsigned char *c, unsigned char *m,
33 | unsigned long long mlen);
34 |
35 | int crypto_decrypt(unsigned char *m, unsigned char *c,
36 | unsigned long long clen);
37 |
38 | #define SHADOWVPN_KEY_LEN 32
39 |
40 | /*
41 | buffer layout
42 |
43 | [SALSA20_RESERVED 8] [NONCE 8] [MAC 16] [OPTIONAL USERTOKEN 8] [PAYLOAD MTU]
44 |
45 | Buffer total size:
46 | SHADOWVPN_ZERO_BYTES + USERTOKEN + MTU
47 |
48 | TUN reads & writes at:
49 | SHADOWVPN_ZERO_BYTES + USERTOKEN
50 |
51 | UDP packet sendto & recvfrom at:
52 | SHADOWVPN_PACKET_OFFSET = SALSA20_RESERVED
53 |
54 | Plain text starts from in buffer:
55 | SHADOWVPN_ZERO_BYTES = SALSA20_RESERVED + NONCE + MAC
56 |
57 | Plain text starts from in UDP packet:
58 | SHADOWVPN_OVERHEAD_LEN = NONCE + MAC
59 |
60 | */
61 |
62 | #define SHADOWVPN_ZERO_BYTES 32
63 | #define SHADOWVPN_OVERHEAD_LEN 24
64 | #define SHADOWVPN_PACKET_OFFSET 8
65 | #define SHADOWVPN_USERTOKEN_LEN 8
66 |
67 | #endif
68 |
--------------------------------------------------------------------------------
/src/crypto_secretbox_salsa208poly1305.c:
--------------------------------------------------------------------------------
1 | /**
2 | crypto_secretbox_salsa208poly1305.c
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #include
22 |
23 | int crypto_secretbox_salsa208poly1305(
24 | unsigned char *c,
25 | const unsigned char *m,unsigned long long mlen,
26 | const unsigned char *n,
27 | const unsigned char *k
28 | )
29 | {
30 | int i;
31 | if (mlen < 32) return -1;
32 | crypto_stream_salsa208_xor(c,m,mlen,n,k);
33 | crypto_onetimeauth_poly1305(c + 16,c + 32,mlen - 32,c);
34 | for (i = 0;i < 16;++i) c[i] = 0;
35 | return 0;
36 | }
37 |
38 | int crypto_secretbox_salsa208poly1305_open(
39 | unsigned char *m,
40 | const unsigned char *c,unsigned long long clen,
41 | const unsigned char *n,
42 | const unsigned char *k
43 | )
44 | {
45 | int i;
46 | unsigned char subkey[32];
47 | if (clen < 32) return -1;
48 | crypto_stream_salsa208(subkey,32,n,k);
49 | if (crypto_onetimeauth_poly1305_verify(c + 16,c + 32,clen - 32,subkey) != 0) return -1;
50 | crypto_stream_salsa208_xor(m,c,clen,n,k);
51 | for (i = 0;i < 32;++i) m[i] = 0;
52 | return 0;
53 | }
54 |
--------------------------------------------------------------------------------
/src/crypto_secretbox_salsa208poly1305.h:
--------------------------------------------------------------------------------
1 | /**
2 | crypto_secretbox_salsa208poly1305.h
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #ifndef CRYPTO_SECRETBOX_SALSA208POLY1305_H
22 | #define CRYPTO_SECRETBOX_SALSA208POLY1305_H
23 |
24 | int crypto_secretbox_salsa208poly1305(
25 | unsigned char *c,
26 | const unsigned char *m,unsigned long long mlen,
27 | const unsigned char *n,
28 | const unsigned char *k
29 | );
30 |
31 | int crypto_secretbox_salsa208poly1305_open(
32 | unsigned char *m,
33 | const unsigned char *c,unsigned long long clen,
34 | const unsigned char *n,
35 | const unsigned char *k
36 | );
37 |
38 | #endif
39 |
--------------------------------------------------------------------------------
/src/daemon.c:
--------------------------------------------------------------------------------
1 | /**
2 | deamon.c
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #include "shadowvpn.h"
22 |
23 | #ifdef TARGET_WIN32
24 |
25 | /* TODO: support daemonize for Windows */
26 |
27 | int daemon_start(const shadowvpn_args_t *args) {
28 | errf("daemonize currently not supported, skipping");
29 | return 0;
30 | }
31 |
32 | int daemon_stop(const shadowvpn_args_t *args) {
33 | errf("daemonize currently not supported, skipping");
34 | return 0;
35 | }
36 |
37 | #else
38 |
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 | #include
45 | #include
46 |
47 | #define PID_BUF_SIZE 32
48 |
49 | static int write_pid_file(const char *filename, pid_t pid);
50 |
51 | static void sig_handler_exit(int signo) {
52 | exit(0);
53 | }
54 |
55 | int daemon_start(const shadowvpn_args_t *args) {
56 | pid_t pid = fork();
57 | if (pid == -1) {
58 | err("fork");
59 | return -1;
60 | }
61 | if (pid > 0) {
62 | // let the child print message to the console first
63 | signal(SIGINT, sig_handler_exit);
64 | sleep(5);
65 | exit(0);
66 | }
67 |
68 | pid_t ppid = getppid();
69 | pid = getpid();
70 | if (0 != write_pid_file(args->pid_file, pid)) {
71 | kill(ppid, SIGINT);
72 | return -1;
73 | }
74 |
75 | setsid();
76 | signal(SIGHUP, SIG_IGN);
77 |
78 | // print on console
79 | printf("started\n");
80 | kill(ppid, SIGINT);
81 |
82 | // then rediret stdout & stderr
83 | fclose(stdin);
84 | FILE *fp;
85 | fp = freopen(args->log_file, "a", stdout);
86 | if (fp == NULL) {
87 | err("freopen");
88 | return -1;
89 | }
90 | fp = freopen(args->log_file, "a", stderr);
91 | if (fp == NULL) {
92 | err("freopen");
93 | return -1;
94 | }
95 |
96 | return 0;
97 | }
98 |
99 | static int write_pid_file(const char *filename, pid_t pid) {
100 | char buf[PID_BUF_SIZE];
101 | int fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
102 | if (fd == -1) {
103 | errf("can not open %s", filename);
104 | err("open");
105 | return -1;
106 | }
107 | int flags = fcntl(fd, F_GETFD);
108 | if (flags == -1) {
109 | err("fcntl");
110 | return -1;
111 | }
112 |
113 | flags |= FD_CLOEXEC;
114 | if (-1 == fcntl(fd, F_SETFD, flags))
115 | err("fcntl");
116 |
117 | struct flock fl;
118 | fl.l_type = F_WRLCK;
119 | fl.l_whence = SEEK_SET;
120 | fl.l_start = 0;
121 | fl.l_len = 0;
122 | if (-1 == fcntl(fd, F_SETLK, &fl)) {
123 | ssize_t n = read(fd, buf, PID_BUF_SIZE - 1);
124 | if (n > 0) {
125 | buf[n] = 0;
126 | errf("already started at pid %ld", atol(buf));
127 | } else {
128 | errf("already started");
129 | }
130 | close(fd);
131 | return -1;
132 | }
133 | if (-1 == ftruncate(fd, 0)) {
134 | err("ftruncate");
135 | return -1;
136 | }
137 | snprintf(buf, PID_BUF_SIZE, "%ld\n", (long)getpid());
138 |
139 | if (write(fd, buf, strlen(buf)) != strlen(buf)) {
140 | err("write");
141 | return -1;
142 | }
143 | return 0;
144 | }
145 |
146 | int daemon_stop(const shadowvpn_args_t *args) {
147 | char buf[PID_BUF_SIZE];
148 | int status, i, stopped;
149 | FILE *fp = fopen(args->pid_file, "r");
150 | if (fp == NULL) {
151 | printf("not running\n");
152 | return 0;
153 | }
154 | char *line = fgets(buf, PID_BUF_SIZE, fp);
155 | fclose(fp);
156 | if (line == NULL) {
157 | err("fgets");
158 | return 0;
159 | }
160 | pid_t pid = (pid_t)atol(buf);
161 | if (pid > 0) {
162 | // make sure pid is not zero or negative
163 | if (0 != kill(pid, SIGTERM)){
164 | if (errno == ESRCH) {
165 | printf("not running\n");
166 | return 0;
167 | }
168 | err("kill");
169 | return -1;
170 | }
171 | stopped = 0;
172 | // wait for maximum 10s
173 | for (i = 0; i < 200; i++) {
174 | if (-1 == kill(pid, 0)) {
175 | if (errno == ESRCH) {
176 | stopped = 1;
177 | break;
178 | }
179 | }
180 | // sleep 0.05s
181 | usleep(50000);
182 | }
183 | if (!stopped) {
184 | errf("timed out when stopping pid %d", pid);
185 | return -1;
186 | }
187 | printf("stopped\n");
188 | if (0 != unlink(args->pid_file)) {
189 | err("unlink");
190 | return -1;
191 | }
192 | } else {
193 | errf("pid is not positive: %ld", (long)pid);
194 | return -1;
195 | }
196 | return 0;
197 | }
198 |
199 | #endif
200 |
--------------------------------------------------------------------------------
/src/daemon.h:
--------------------------------------------------------------------------------
1 | /**
2 | daemon.h
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #ifndef DAEMON_H
22 | #define DAEMON_H
23 |
24 | #include "args.h"
25 |
26 | /*
27 | return 0 if success and in child, will also redirect stdout and stderr
28 | not return if master
29 | return non-zero if error
30 | */
31 | int daemon_start(const shadowvpn_args_t *args);
32 |
33 | /*
34 | return 0 if success
35 | return non-zero if error
36 | */
37 | int daemon_stop(const shadowvpn_args_t *args);
38 |
39 | #endif
40 |
--------------------------------------------------------------------------------
/src/log.c:
--------------------------------------------------------------------------------
1 | /**
2 | vpn.c
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #include
22 | #include "shadowvpn.h"
23 |
24 | int verbose_mode;
25 |
26 | void log_timestamp(FILE *out) {
27 | time_t now;
28 | time(&now);
29 | char *time_str = ctime(&now);
30 | time_str[strlen(time_str) - 1] = '\0';
31 | fprintf(out, "%s ", time_str);
32 | }
33 |
34 | void perror_timestamp(const char *msg, const char *file, int line) {
35 | log_timestamp(stderr);
36 | fprintf(stderr, "%s:%d ", file, line);
37 | #ifdef TARGET_WIN32
38 | LPVOID *err_str = NULL;
39 | FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
40 | FORMAT_MESSAGE_IGNORE_INSERTS,
41 | NULL, WSAGetLastError(),
42 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
43 | (LPTSTR) &err_str, 0, NULL);
44 | if (err_str != NULL) {
45 | fprintf(stderr, "%s: %s\n", msg, (char *)err_str);
46 | LocalFree(err_str);
47 | }
48 | #else
49 | perror(msg);
50 | #endif
51 | }
52 |
53 | void print_hex_memory(void *mem, size_t len) {
54 | int i;
55 | unsigned char *p = (unsigned char *)mem;
56 | for (i = 0; i < len; i++) {
57 | printf("%02x ", p[i]);
58 | if (i % 16 == 15)
59 | printf("\n");
60 | }
61 | printf("\n");
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/src/log.h:
--------------------------------------------------------------------------------
1 | /**
2 | log.h
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #ifndef LOG_H
22 | #define LOG_H
23 |
24 | #include
25 | #include
26 | #include
27 |
28 | extern int verbose_mode;
29 |
30 | /*
31 | err: same as perror but with timestamp
32 | errf: same as printf to stderr with timestamp and \n
33 | logf: same as printf to stdout with timestamp and \n,
34 | and only enabled when verbose is on
35 | debugf: same as logf but only compiles with DEBUG flag
36 | */
37 |
38 | #define __LOG(o, not_stderr, s...) do { \
39 | if (not_stderr || verbose_mode) { \
40 | log_timestamp(o); \
41 | fprintf(o, s); \
42 | fprintf(o, "\n"); \
43 | fflush(o); \
44 | } \
45 | } while (0)
46 |
47 | #ifdef HAVE_ANDROID_LOG
48 | #include
49 | #define logf(s...) \
50 | __android_log_print(ANDROID_LOG_INFO, __FILE__, s)
51 |
52 | #define errf(s...) \
53 | __android_log_print(ANDROID_LOG_ERROR, __FILE__, s)
54 |
55 | #define err(s) \
56 | __android_log_print(ANDROID_LOG_ERROR, __FILE__, "%s: %s", s, strerror(errno))
57 |
58 | #else
59 |
60 | #define logf(s...) __LOG(stdout, 0, s)
61 | #define errf(s...) __LOG(stderr, 1, s)
62 | #define err(s) perror_timestamp(s, __FILE__, __LINE__)
63 |
64 | #endif
65 |
66 | #ifdef DEBUG
67 | #define debugf(s...) logf(s)
68 | #else
69 | #define debugf(s...)
70 | #endif
71 |
72 | void log_timestamp(FILE *out);
73 | void perror_timestamp(const char *msg, const char *file, int line);
74 | void print_hex_memory(void *mem, size_t len);
75 |
76 | #endif
77 |
--------------------------------------------------------------------------------
/src/main.c:
--------------------------------------------------------------------------------
1 | /**
2 | main.c
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include "shadowvpn.h"
26 |
27 | static vpn_ctx_t vpn_ctx;
28 |
29 | #ifdef TARGET_WIN32
30 | BOOL WINAPI sig_handler(DWORD signo)
31 | {
32 | switch (signo) {
33 | case CTRL_C_EVENT:
34 | case CTRL_BREAK_EVENT:
35 | case CTRL_CLOSE_EVENT:
36 | case CTRL_LOGOFF_EVENT:
37 | case CTRL_SHUTDOWN_EVENT:
38 | vpn_stop(&vpn_ctx);
39 | break;
40 | default:
41 | break;
42 | }
43 | return TRUE;
44 | }
45 | #else
46 | static void sig_handler(int signo) {
47 | if (signo == SIGINT)
48 | exit(1); // for gprof
49 | else
50 | vpn_stop(&vpn_ctx);
51 | }
52 | #endif
53 |
54 | int main(int argc, char **argv) {
55 | shadowvpn_args_t args;
56 | // parse args
57 | if (0 != args_parse(&args, argc, argv)) {
58 | errf("error when parsing args");
59 | return EXIT_FAILURE;
60 | }
61 | if (args.cmd == SHADOWVPN_CMD_START) {
62 | if (0 != daemon_start(&args)) {
63 | errf("can not start daemon");
64 | return EXIT_FAILURE;
65 | }
66 | } else if (args.cmd == SHADOWVPN_CMD_STOP) {
67 | if (0 != daemon_stop(&args)) {
68 | errf("can not stop daemon");
69 | return EXIT_FAILURE;
70 | }
71 | // always exit if we are exec stop cmd
72 | return 0;
73 | } else if (args.cmd == SHADOWVPN_CMD_RESTART) {
74 | if (0 != daemon_stop(&args)) {
75 | errf("can not stop daemon");
76 | return EXIT_FAILURE;
77 | }
78 | if (0 != daemon_start(&args)) {
79 | errf("can not start daemon");
80 | return EXIT_FAILURE;
81 | }
82 | }
83 |
84 | if (0 != crypto_init()) {
85 | errf("shadowvpn_crypto_init");
86 | return EXIT_FAILURE;
87 | }
88 |
89 | if (0 !=crypto_set_password(args.password, strlen(args.password))) {
90 | errf("can not set password");
91 | return EXIT_FAILURE;
92 | }
93 |
94 | #ifdef TARGET_WIN32
95 | if (0 == SetConsoleCtrlHandler((PHANDLER_ROUTINE) sig_handler, TRUE)) {
96 | errf("can not set control handler");
97 | return EXIT_FAILURE;
98 | }
99 | #else
100 | signal(SIGINT, sig_handler);
101 | signal(SIGTERM, sig_handler);
102 | #endif
103 |
104 | if (-1 == vpn_ctx_init(&vpn_ctx, &args)) {
105 | return EXIT_FAILURE;
106 | }
107 | return vpn_run(&vpn_ctx);
108 | }
109 |
--------------------------------------------------------------------------------
/src/nat.c:
--------------------------------------------------------------------------------
1 | /**
2 | nat.c
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #include "shadowvpn.h"
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include "portable_endian.h"
29 |
30 | #ifndef TARGET_WIN32
31 |
32 | #include
33 | #include
34 | #include
35 | #include
36 |
37 | int nat_init(nat_ctx_t *ctx, shadowvpn_args_t *args) {
38 | int i;
39 | bzero(ctx, sizeof(nat_ctx_t));
40 | for (i = 0; i < args->user_tokens_len; i++) {
41 | client_info_t *client = malloc(sizeof(client_info_t));
42 | bzero(client, sizeof(client_info_t));
43 |
44 | memcpy(client->user_token, args->user_tokens[i], SHADOWVPN_USERTOKEN_LEN);
45 |
46 | // assign IP based on tun IP and user tokens
47 | // for example:
48 | // tun IP is 10.7.0.1
49 | // client IPs will be 10.7.0.2, 10.7.0.3, 10.7.0.4, etc
50 | client->output_tun_ip = htonl(args->netip + i + 1);
51 |
52 | struct in_addr in;
53 | in.s_addr = client->output_tun_ip;
54 | logf("assigning %s to user %16llx",
55 | inet_ntoa(in),
56 | htobe64(*((uint64_t *)args->user_tokens[i])));
57 |
58 | // add to hash: ctx->token_to_clients[user_token] = client
59 | HASH_ADD(hh1, ctx->token_to_clients, user_token,
60 | SHADOWVPN_USERTOKEN_LEN, client);
61 |
62 | // add to hash: ctx->ip_to_clients[output_tun_ip] = client
63 | HASH_ADD(hh2, ctx->ip_to_clients, output_tun_ip, 4, client);
64 | }
65 | return 0;
66 | }
67 |
68 | /*
69 | RFC791
70 | 0 1 2 3
71 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
72 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73 | |Version| IHL |Type of Service| Total Length |
74 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75 | | Identification |Flags| Fragment Offset |
76 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77 | | Time to Live | Protocol | Header Checksum |
78 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
79 | | Source Address |
80 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
81 | | Destination Address |
82 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
83 | | Options | Padding |
84 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
85 | */
86 |
87 | typedef struct {
88 | uint8_t ver;
89 | uint8_t tos;
90 | uint16_t total_len;
91 | uint16_t id;
92 | uint16_t frag;
93 | uint8_t ttl;
94 | uint8_t proto;
95 | uint16_t checksum;
96 | uint32_t saddr;
97 | uint32_t daddr;
98 | } ipv4_hdr_t;
99 |
100 | typedef struct {
101 | uint16_t sport;
102 | uint16_t dport;
103 | uint32_t seq;
104 | uint32_t ack;
105 | uint32_t not_interested;
106 | uint16_t checksum;
107 | uint16_t upt;
108 | } tcp_hdr_t;
109 |
110 | typedef struct {
111 | uint16_t sport;
112 | uint16_t dport;
113 | uint16_t len;
114 | uint16_t checksum;
115 | } udp_hdr_t;
116 |
117 | // from OpenVPN
118 | // acc is the changes (+ old - new)
119 | // cksum is the checksum to adjust
120 | #define ADJUST_CHECKSUM(acc, cksum) { \
121 | int _acc = acc; \
122 | _acc += (cksum); \
123 | if (_acc < 0) { \
124 | _acc = -_acc; \
125 | _acc = (_acc >> 16) + (_acc & 0xffff); \
126 | _acc += _acc >> 16; \
127 | (cksum) = (uint16_t) ~_acc; \
128 | } else { \
129 | _acc = (_acc >> 16) + (_acc & 0xffff); \
130 | _acc += _acc >> 16; \
131 | (cksum) = (uint16_t) _acc; \
132 | } \
133 | }
134 |
135 | int nat_fix_upstream(nat_ctx_t *ctx, unsigned char *buf, size_t buflen,
136 | const struct sockaddr *addr, socklen_t addrlen) {
137 | uint8_t iphdr_len;
138 | if (buflen < SHADOWVPN_USERTOKEN_LEN + 20) {
139 | errf("nat: ip packet too short");
140 | return -1;
141 | }
142 | ipv4_hdr_t *iphdr = (ipv4_hdr_t *)(buf + SHADOWVPN_USERTOKEN_LEN);
143 | if ((iphdr->ver & 0xf0) != 0x40) {
144 | // check header, currently IPv4 only
145 | // bypass IPv6
146 | return 0;
147 | }
148 | iphdr_len = (iphdr->ver & 0x0f) * 4;
149 |
150 | // print_hex_memory(buf, SHADOWVPN_USERTOKEN_LEN);
151 | client_info_t *client = NULL;
152 | HASH_FIND(hh1, ctx->token_to_clients, buf, SHADOWVPN_USERTOKEN_LEN, client);
153 | if (client == NULL) {
154 | errf("nat: client not found for given user token");
155 | return -1;
156 | }
157 | // print_hex_memory(iphdr, buflen - SHADOWVPN_USERTOKEN_LEN);
158 |
159 | // save source address
160 | client->source_addr.addrlen = addrlen;
161 | memcpy(&client->source_addr.addr, addr, addrlen);
162 |
163 | int32_t acc = 0;
164 | // save tun input ip to client
165 | client->input_tun_ip = iphdr->saddr;
166 |
167 | // overwrite IP
168 | iphdr->saddr = client->output_tun_ip;
169 |
170 | // add old, sub new
171 | acc = client->input_tun_ip - iphdr->saddr;
172 | ADJUST_CHECKSUM(acc, iphdr->checksum);
173 |
174 | if (0 == (iphdr->frag & htons(0x1fff))) {
175 | // only adjust tcp & udp when frag offset == 0
176 | void *ip_payload = buf + SHADOWVPN_USERTOKEN_LEN + iphdr_len;
177 | if (iphdr->proto == IPPROTO_TCP) {
178 | if (buflen < iphdr_len + 20) {
179 | errf("nat: tcp packet too short");
180 | return -1;
181 | }
182 | tcp_hdr_t *tcphdr = ip_payload;
183 | ADJUST_CHECKSUM(acc, tcphdr->checksum);
184 | } else if (iphdr->proto == IPPROTO_UDP) {
185 | if (buflen < iphdr_len + 8) {
186 | errf("nat: udp packet too short");
187 | return -1;
188 | }
189 | udp_hdr_t *udphdr = ip_payload;
190 | ADJUST_CHECKSUM(acc, udphdr->checksum);
191 | }
192 | }
193 | return 0;
194 | }
195 |
196 | int nat_fix_downstream(nat_ctx_t *ctx, unsigned char *buf, size_t buflen,
197 | struct sockaddr *addr, socklen_t *addrlen) {
198 | uint8_t iphdr_len;
199 | if (buflen < SHADOWVPN_USERTOKEN_LEN + 20) {
200 | errf("nat: ip packet too short");
201 | return -1;
202 | }
203 | ipv4_hdr_t *iphdr = (ipv4_hdr_t *)(buf + SHADOWVPN_USERTOKEN_LEN);
204 | if ((iphdr->ver & 0xf0) != 0x40) {
205 | // check header, currently IPv4 only
206 | // bypass IPv6
207 | return 0;
208 | }
209 | iphdr_len = (iphdr->ver & 0x0f) * 4;
210 |
211 | client_info_t *client = NULL;
212 | // print_hex_memory(iphdr, buflen - SHADOWVPN_USERTOKEN_LEN);
213 |
214 | HASH_FIND(hh2, ctx->ip_to_clients, &iphdr->daddr, 4, client);
215 | if (client == NULL) {
216 | errf("nat: client not found for given user ip");
217 | return -1;
218 | }
219 |
220 | // print_hex_memory(client->user_token, SHADOWVPN_USERTOKEN_LEN);
221 |
222 | // update dest address
223 | *addrlen = client->source_addr.addrlen;
224 | memcpy(addr, &client->source_addr.addr, *addrlen);
225 |
226 | // copy usertoken back
227 | memcpy(buf, client->user_token, SHADOWVPN_USERTOKEN_LEN);
228 |
229 | int32_t acc = 0;
230 |
231 | // add old, sub new
232 | acc = iphdr->daddr - client->input_tun_ip;
233 |
234 | // overwrite IP
235 | iphdr->daddr = client->input_tun_ip;
236 |
237 | ADJUST_CHECKSUM(acc, iphdr->checksum);
238 |
239 | if (0 == (iphdr->frag & htons(0x1fff))) {
240 | // only adjust tcp & udp when frag offset == 0
241 | void *ip_payload = buf + SHADOWVPN_USERTOKEN_LEN + iphdr_len;
242 | if (iphdr->proto == IPPROTO_TCP) {
243 | if (buflen < iphdr_len + 20) {
244 | errf("nat: tcp packet too short");
245 | return -1;
246 | }
247 | tcp_hdr_t *tcphdr = ip_payload;
248 | ADJUST_CHECKSUM(acc, tcphdr->checksum);
249 | } else if (iphdr->proto == IPPROTO_UDP) {
250 | if (buflen < iphdr_len + 8) {
251 | errf("nat: udp packet too short");
252 | return -1;
253 | }
254 | udp_hdr_t *udphdr = ip_payload;
255 | ADJUST_CHECKSUM(acc, udphdr->checksum);
256 | }
257 | }
258 | return 0;
259 | }
260 |
261 | #else
262 |
263 | int nat_init(nat_ctx_t *ctx, shadowvpn_args_t *args) {
264 | errf("warning: NAT server is currently not supported on Windows");
265 | return 0;
266 | }
267 |
268 | int nat_fix_upstream(nat_ctx_t *ctx, unsigned char *buf, size_t buflen,
269 | const struct sockaddr *addr, socklen_t addrlen) {
270 | return 0;
271 | }
272 |
273 | int nat_fix_downstream(nat_ctx_t *ctx, unsigned char *buf, size_t buflen,
274 | struct sockaddr *addr, socklen_t *addrlen) {
275 | return 0;
276 | }
277 |
278 | #endif
279 |
280 |
--------------------------------------------------------------------------------
/src/nat.h:
--------------------------------------------------------------------------------
1 | /**
2 | nat.h
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #ifndef NAT_H
22 | #define NAT_H
23 |
24 | #ifdef TARGET_WIN32
25 | #include "win32.h"
26 | #else
27 | #include
28 | #include
29 | #include
30 | #include
31 | #endif
32 |
33 | #include "uthash.h"
34 |
35 | /**
36 | This module maps any IP from the client net to the server net
37 | based on user_token.
38 | */
39 |
40 | /* the structure to store known client addresses for the server */
41 | typedef struct {
42 | struct sockaddr_storage addr;
43 | socklen_t addrlen;
44 | } addr_info_t;
45 |
46 | /* the structure to store known client addresses for the server */
47 | typedef struct {
48 | int id;
49 | char user_token[SHADOWVPN_USERTOKEN_LEN];
50 |
51 | // source address of UDP
52 | addr_info_t source_addr;
53 |
54 | // input tun IP
55 | // in network order
56 | // TODO support IPv6 address on tun
57 | uint32_t input_tun_ip;
58 |
59 | // output tun IP
60 | // in network order
61 | uint32_t output_tun_ip;
62 |
63 | UT_hash_handle hh1;
64 | UT_hash_handle hh2;
65 | } client_info_t;
66 |
67 | typedef struct {
68 | /* clients map
69 | key: user token */
70 | client_info_t *token_to_clients;
71 |
72 | /* clients map
73 | TODO: use index instead of hash
74 | key: IP */
75 | client_info_t *ip_to_clients;
76 | } nat_ctx_t;
77 |
78 | /* init hash tables */
79 | int nat_init(nat_ctx_t *ctx, shadowvpn_args_t *args);
80 |
81 | /* UDP -> TUN NAT
82 | buf starts from payload
83 | */
84 | int nat_fix_upstream(nat_ctx_t *ctx, unsigned char *buf, size_t buflen,
85 | const struct sockaddr *addr, socklen_t addrlen);
86 |
87 | /* TUN -> UDP NAT
88 | buf starts from payload
89 | */
90 | int nat_fix_downstream(nat_ctx_t *ctx, unsigned char *buf, size_t buflen,
91 | struct sockaddr *addr, socklen_t *addrlen);
92 |
93 | #endif
94 |
--------------------------------------------------------------------------------
/src/portable_endian.h:
--------------------------------------------------------------------------------
1 | // "License": Public Domain
2 | // I, Mathias Panzenböck, place this file hereby into the public domain. Use it at your own risk for whatever you like.
3 | // In case there are jurisdictions that don't support putting things in the public domain you can also consider it to
4 | // be "dual licensed" under the BSD, MIT and Apache licenses, if you want to. This code is trivial anyway. Consider it
5 | // an example on how to get the endian conversion functions on different platforms.
6 |
7 | #ifndef PORTABLE_ENDIAN_H__
8 | #define PORTABLE_ENDIAN_H__
9 |
10 | #if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__)
11 |
12 | # define __WINDOWS__
13 |
14 | #endif
15 |
16 | #if defined(__linux__) || defined(__CYGWIN__)
17 |
18 | # include
19 |
20 | #elif defined(__APPLE__)
21 |
22 | # include
23 |
24 | # define htobe16(x) OSSwapHostToBigInt16(x)
25 | # define htole16(x) OSSwapHostToLittleInt16(x)
26 | # define be16toh(x) OSSwapBigToHostInt16(x)
27 | # define le16toh(x) OSSwapLittleToHostInt16(x)
28 |
29 | # define htobe32(x) OSSwapHostToBigInt32(x)
30 | # define htole32(x) OSSwapHostToLittleInt32(x)
31 | # define be32toh(x) OSSwapBigToHostInt32(x)
32 | # define le32toh(x) OSSwapLittleToHostInt32(x)
33 |
34 | # define htobe64(x) OSSwapHostToBigInt64(x)
35 | # define htole64(x) OSSwapHostToLittleInt64(x)
36 | # define be64toh(x) OSSwapBigToHostInt64(x)
37 | # define le64toh(x) OSSwapLittleToHostInt64(x)
38 |
39 | # define __BYTE_ORDER BYTE_ORDER
40 | # define __BIG_ENDIAN BIG_ENDIAN
41 | # define __LITTLE_ENDIAN LITTLE_ENDIAN
42 | # define __PDP_ENDIAN PDP_ENDIAN
43 |
44 | #elif defined(__OpenBSD__)
45 |
46 | # include
47 |
48 | #elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
49 |
50 | # include
51 |
52 | # define be16toh(x) betoh16(x)
53 | # define le16toh(x) letoh16(x)
54 |
55 | # define be32toh(x) betoh32(x)
56 | # define le32toh(x) letoh32(x)
57 |
58 | # define be64toh(x) betoh64(x)
59 | # define le64toh(x) letoh64(x)
60 |
61 | #elif defined(__WINDOWS__)
62 |
63 | # include
64 | # include
65 |
66 | # if BYTE_ORDER == LITTLE_ENDIAN
67 |
68 | # define htobe16(x) htons(x)
69 | # define htole16(x) (x)
70 | # define be16toh(x) ntohs(x)
71 | # define le16toh(x) (x)
72 |
73 | # define htobe32(x) htonl(x)
74 | # define htole32(x) (x)
75 | # define be32toh(x) ntohl(x)
76 | # define le32toh(x) (x)
77 |
78 | # define htobe64(x) htonll(x)
79 | # define htole64(x) (x)
80 | # define be64toh(x) ntohll(x)
81 | # define le64toh(x) (x)
82 |
83 | # elif BYTE_ORDER == BIG_ENDIAN
84 |
85 | /* that would be xbox 360 */
86 | # define htobe16(x) (x)
87 | # define htole16(x) __builtin_bswap16(x)
88 | # define be16toh(x) (x)
89 | # define le16toh(x) __builtin_bswap16(x)
90 |
91 | # define htobe32(x) (x)
92 | # define htole32(x) __builtin_bswap32(x)
93 | # define be32toh(x) (x)
94 | # define le32toh(x) __builtin_bswap32(x)
95 |
96 | # define htobe64(x) (x)
97 | # define htole64(x) __builtin_bswap64(x)
98 | # define be64toh(x) (x)
99 | # define le64toh(x) __builtin_bswap64(x)
100 |
101 | # else
102 |
103 | # error byte order not supported
104 |
105 | # endif
106 |
107 | # define __BYTE_ORDER BYTE_ORDER
108 | # define __BIG_ENDIAN BIG_ENDIAN
109 | # define __LITTLE_ENDIAN LITTLE_ENDIAN
110 | # define __PDP_ENDIAN PDP_ENDIAN
111 |
112 | #else
113 |
114 | # error platform not supported
115 |
116 | #endif
117 |
118 | #endif
--------------------------------------------------------------------------------
/src/shadowvpn.h:
--------------------------------------------------------------------------------
1 | /**
2 | shadowvpn.h
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #ifndef SHADOWVPN_H
22 | #define SHADOWVPN_H
23 |
24 | #ifdef HAVE_CONFIG_H
25 | #include "config.h"
26 | #endif
27 |
28 | #include "log.h"
29 | #include "crypto.h"
30 | #include "args.h"
31 | #include "daemon.h"
32 | #include "shell.h"
33 | #include "nat.h"
34 | #include "vpn.h"
35 |
36 | #endif
37 |
--------------------------------------------------------------------------------
/src/shell.c:
--------------------------------------------------------------------------------
1 | /**
2 | shell.c
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #include
22 | #include
23 | #include "shadowvpn.h"
24 | #include "shell.h"
25 |
26 | static int shell_run(shadowvpn_args_t *args, int is_up);
27 |
28 | int shell_up(shadowvpn_args_t *args) {
29 | return shell_run(args, 1);
30 | }
31 |
32 | int shell_down(shadowvpn_args_t *args) {
33 | return shell_run(args, 0);
34 | }
35 |
36 | static int shell_run(shadowvpn_args_t *args, int is_up) {
37 | const char *script;
38 | char *buf;
39 | int r;
40 | if (is_up) {
41 | script = args->up_script;
42 | } else {
43 | script = args->down_script;
44 | }
45 | if (script == NULL || script[0] == 0) {
46 | errf("warning: script not set");
47 | return 0;
48 | }
49 | buf = malloc(strlen(script) + 8);
50 | #ifdef TARGET_WIN32
51 | sprintf(buf, "cmd /c %s", script);
52 | #else
53 | sprintf(buf, "sh %s", script);
54 | #endif
55 | logf("executing %s", script);
56 | if (0 != (r = system(buf))) {
57 | free(buf);
58 | errf("script %s returned non-zero return code: %d", script, r);
59 | return -1;
60 | }
61 | free(buf);
62 | return 0;
63 | }
64 |
65 |
66 |
--------------------------------------------------------------------------------
/src/shell.h:
--------------------------------------------------------------------------------
1 | /**
2 | shell.h
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #ifndef SHELL_H
22 | #define SHELL_H
23 |
24 | #include "args.h"
25 |
26 | int shell_up(shadowvpn_args_t *args);
27 | int shell_down(shadowvpn_args_t *args);
28 |
29 | #endif
30 |
31 |
--------------------------------------------------------------------------------
/src/vpn.c:
--------------------------------------------------------------------------------
1 | /**
2 | vpn.c
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | // TODO we want to put shadowvpn.h at the bottom of the imports
22 | // but TARGET_* is defined in config.h
23 | #include "shadowvpn.h"
24 |
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 |
31 | #ifndef TARGET_WIN32
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #endif
40 |
41 | #ifdef TARGET_DARWIN
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 | #endif
48 |
49 | #ifdef TARGET_LINUX
50 | #include
51 | #endif
52 |
53 | #ifdef TARGET_FREEBSD
54 | #include
55 | #endif
56 |
57 |
58 | /*
59 | * Darwin & OpenBSD use utun which is slightly
60 | * different from standard tun device. It adds
61 | * a uint32 to the beginning of the IP header
62 | * to designate the protocol.
63 | *
64 | * We use utun_read to strip off the header
65 | * and utun_write to put it back.
66 | */
67 | #ifdef TARGET_DARWIN
68 | #define tun_read(...) utun_read(__VA_ARGS__)
69 | #define tun_write(...) utun_write(__VA_ARGS__)
70 | #elif !defined(TARGET_WIN32)
71 | #define tun_read(...) read(__VA_ARGS__)
72 | #define tun_write(...) write(__VA_ARGS__)
73 | #endif
74 |
75 | #ifdef TARGET_WIN32
76 |
77 | #undef errno
78 | #undef EWOULDBLOCK
79 | #undef EAGAIN
80 | #undef EINTR
81 | #undef ENETDOWN
82 | #undef ENETUNREACH
83 | #undef EMSGSIZE
84 |
85 | #define errno WSAGetLastError()
86 | #define EWOULDBLOCK WSAEWOULDBLOCK
87 | #define EAGAIN WSAEWOULDBLOCK
88 | #define EINTR WSAEINTR
89 | #define ENETUNREACH WSAENETUNREACH
90 | #define ENETDOWN WSAENETDOWN
91 | #define EMSGSIZE WSAEMSGSIZE
92 | #define close(fd) closesocket(fd)
93 |
94 | #endif
95 |
96 | #ifdef TARGET_LINUX
97 | int vpn_tun_alloc(const char *dev) {
98 | struct ifreq ifr;
99 | int fd, e;
100 |
101 | if ((fd = open("/dev/net/tun", O_RDWR)) < 0) {
102 | err("open");
103 | errf("can not open /dev/net/tun");
104 | return -1;
105 | }
106 |
107 | memset(&ifr, 0, sizeof(ifr));
108 |
109 | /* Flags: IFF_TUN - TUN device (no Ethernet headers)
110 | * IFF_TAP - TAP device
111 | *
112 | * IFF_NO_PI - Do not provide packet information
113 | */
114 | ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
115 | if(*dev)
116 | strncpy(ifr.ifr_name, dev, IFNAMSIZ);
117 |
118 | if ((e = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0) {
119 | err("ioctl[TUNSETIFF]");
120 | errf("can not setup tun device: %s", dev);
121 | close(fd);
122 | return -1;
123 | }
124 | // strcpy(dev, ifr.ifr_name);
125 | return fd;
126 | }
127 | #endif
128 |
129 | #ifdef TARGET_FREEBSD
130 | int vpn_tun_alloc(const char *dev) {
131 | int fd;
132 | char devname[32]={0,};
133 | snprintf(devname, sizeof(devname), "/dev/%s", dev);
134 | if ((fd = open(devname, O_RDWR)) < 0) {
135 | err("open");
136 | errf("can not open %s", devname);
137 | return -1;
138 | }
139 | int i = IFF_POINTOPOINT | IFF_MULTICAST;
140 | if (ioctl(fd, TUNSIFMODE, &i) < 0) {
141 | err("ioctl[TUNSIFMODE]");
142 | errf("can not setup tun device: %s", dev);
143 | close(fd);
144 | return -1;
145 | }
146 | i = 0;
147 | if (ioctl(fd, TUNSIFHEAD, &i) < 0) {
148 | err("ioctl[TUNSIFHEAD]");
149 | errf("can not setup tun device: %s", dev);
150 | close(fd);
151 | return -1;
152 | }
153 | return fd;
154 | }
155 | #endif
156 |
157 | #ifdef TARGET_DARWIN
158 | static inline int utun_modified_len(int len) {
159 | if (len > 0)
160 | return (len > sizeof (u_int32_t)) ? len - sizeof (u_int32_t) : 0;
161 | else
162 | return len;
163 | }
164 |
165 | static int utun_write(int fd, void *buf, size_t len) {
166 | u_int32_t type;
167 | struct iovec iv[2];
168 | struct ip *iph;
169 |
170 | iph = (struct ip *) buf;
171 |
172 | if (iph->ip_v == 6)
173 | type = htonl(AF_INET6);
174 | else
175 | type = htonl(AF_INET);
176 |
177 | iv[0].iov_base = &type;
178 | iv[0].iov_len = sizeof(type);
179 | iv[1].iov_base = buf;
180 | iv[1].iov_len = len;
181 |
182 | return utun_modified_len(writev(fd, iv, 2));
183 | }
184 |
185 | static int utun_read(int fd, void *buf, size_t len) {
186 | u_int32_t type;
187 | struct iovec iv[2];
188 |
189 | iv[0].iov_base = &type;
190 | iv[0].iov_len = sizeof(type);
191 | iv[1].iov_base = buf;
192 | iv[1].iov_len = len;
193 |
194 | return utun_modified_len(readv(fd, iv, 2));
195 | }
196 |
197 | int vpn_tun_alloc(const char *dev) {
198 | struct ctl_info ctlInfo;
199 | struct sockaddr_ctl sc;
200 | int fd;
201 | int utunnum;
202 |
203 | if (dev == NULL) {
204 | errf("utun device name cannot be null");
205 | return -1;
206 | }
207 | if (sscanf(dev, "utun%d", &utunnum) != 1) {
208 | errf("invalid utun device name: %s", dev);
209 | return -1;
210 | }
211 |
212 | memset(&ctlInfo, 0, sizeof(ctlInfo));
213 | if (strlcpy(ctlInfo.ctl_name, UTUN_CONTROL_NAME, sizeof(ctlInfo.ctl_name)) >=
214 | sizeof(ctlInfo.ctl_name)) {
215 | errf("can not setup utun device: UTUN_CONTROL_NAME too long");
216 | return -1;
217 | }
218 |
219 | fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
220 |
221 | if (fd == -1) {
222 | err("socket[SYSPROTO_CONTROL]");
223 | return -1;
224 | }
225 |
226 | if (ioctl(fd, CTLIOCGINFO, &ctlInfo) == -1) {
227 | close(fd);
228 | err("ioctl[CTLIOCGINFO]");
229 | return -1;
230 | }
231 |
232 | sc.sc_id = ctlInfo.ctl_id;
233 | sc.sc_len = sizeof(sc);
234 | sc.sc_family = AF_SYSTEM;
235 | sc.ss_sysaddr = AF_SYS_CONTROL;
236 | sc.sc_unit = utunnum + 1;
237 |
238 | if (connect(fd, (struct sockaddr *) &sc, sizeof(sc)) == -1) {
239 | close(fd);
240 | err("connect[AF_SYS_CONTROL]");
241 | return -1;
242 | }
243 |
244 | return fd;
245 | }
246 | #endif
247 |
248 | #ifdef TARGET_WIN32
249 | static int tun_write(int tun_fd, char *data, size_t len) {
250 | DWORD written;
251 | DWORD res;
252 | OVERLAPPED olpd;
253 |
254 | olpd.Offset = 0;
255 | olpd.OffsetHigh = 0;
256 | olpd.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
257 | res = WriteFile(dev_handle, data, len, &written, &olpd);
258 | if (!res && GetLastError() == ERROR_IO_PENDING) {
259 | WaitForSingleObject(olpd.hEvent, INFINITE);
260 | res = GetOverlappedResult(dev_handle, &olpd, &written, FALSE);
261 | if (written != len) {
262 | return -1;
263 | }
264 | }
265 | return 0;
266 | }
267 |
268 | static int tun_read(int tun_fd, char *buf, size_t len) {
269 | return recv(tun_fd, buf, len, 0);
270 | }
271 | #endif
272 |
273 | int vpn_udp_alloc(int if_bind, const char *host, int port,
274 | struct sockaddr *addr, socklen_t* addrlen) {
275 | struct addrinfo hints;
276 | struct addrinfo *res;
277 | int sock, r, flags;
278 |
279 | memset(&hints, 0, sizeof(hints));
280 | hints.ai_socktype = SOCK_DGRAM;
281 | hints.ai_protocol = IPPROTO_UDP;
282 | if (0 != (r = getaddrinfo(host, NULL, &hints, &res))) {
283 | errf("getaddrinfo: %s", gai_strerror(r));
284 | return -1;
285 | }
286 |
287 | if (res->ai_family == AF_INET)
288 | ((struct sockaddr_in *)res->ai_addr)->sin_port = htons(port);
289 | else if (res->ai_family == AF_INET6)
290 | ((struct sockaddr_in6 *)res->ai_addr)->sin6_port = htons(port);
291 | else {
292 | errf("unknown ai_family %d", res->ai_family);
293 | freeaddrinfo(res);
294 | return -1;
295 | }
296 | memcpy(addr, res->ai_addr, res->ai_addrlen);
297 | *addrlen = res->ai_addrlen;
298 |
299 | if (-1 == (sock = socket(res->ai_family, SOCK_DGRAM, IPPROTO_UDP))) {
300 | err("socket");
301 | errf("can not create socket");
302 | freeaddrinfo(res);
303 | return -1;
304 | }
305 |
306 | if (if_bind) {
307 | if (0 != bind(sock, res->ai_addr, res->ai_addrlen)) {
308 | err("bind");
309 | errf("can not bind %s:%d", host, port);
310 | close(sock);
311 | freeaddrinfo(res);
312 | return -1;
313 | }
314 | }
315 | freeaddrinfo(res);
316 |
317 | #ifndef TARGET_WIN32
318 | flags = fcntl(sock, F_GETFL, 0);
319 | if (flags != -1) {
320 | if (-1 != fcntl(sock, F_SETFL, flags | O_NONBLOCK))
321 | return sock;
322 | }
323 | err("fcntl");
324 | #else
325 | u_long mode = 0;
326 | if (NO_ERROR == ioctlsocket(sock, FIONBIO, &mode))
327 | return disable_reset_report(sock);
328 | err("ioctlsocket");
329 | #endif
330 |
331 | close(sock);
332 | return -1;
333 | }
334 |
335 | #ifndef TARGET_WIN32
336 | static int max(int a, int b) {
337 | return a > b ? a : b;
338 | }
339 | #endif
340 |
341 | int vpn_ctx_init(vpn_ctx_t *ctx, shadowvpn_args_t *args) {
342 | int i;
343 | #ifdef TARGET_WIN32
344 | WORD wVersionRequested;
345 | WSADATA wsaData;
346 | int ret;
347 |
348 | wVersionRequested = MAKEWORD(1, 1);
349 | ret = WSAStartup(wVersionRequested, &wsaData);
350 | if (ret != 0) {
351 | errf("can not initialize winsock");
352 | return -1;
353 | }
354 | if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {
355 | WSACleanup();
356 | errf("can not find a usable version of winsock");
357 | return -1;
358 | }
359 | #endif
360 |
361 | bzero(ctx, sizeof(vpn_ctx_t));
362 | ctx->remote_addrp = (struct sockaddr *)&ctx->remote_addr;
363 |
364 | #ifndef TARGET_WIN32
365 | if (-1 == pipe(ctx->control_pipe)) {
366 | err("pipe");
367 | return -1;
368 | }
369 | if (-1 == (ctx->tun = vpn_tun_alloc(args->intf))) {
370 | errf("failed to create tun device");
371 | return -1;
372 | }
373 | #else
374 | if (-1 == (ctx->control_fd = vpn_udp_alloc(1, TUN_DELEGATE_ADDR,
375 | args->tun_port + 1,
376 | &ctx->control_addr,
377 | &ctx->control_addrlen))) {
378 | err("failed to create control socket");
379 | return -1;
380 | }
381 | if (NULL == (ctx->cleanEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) {
382 | err("CreateEvent");
383 | return -1;
384 | }
385 | if (-1 == (ctx->tun = tun_open(args->intf, args->tun_ip, args->tun_mask,
386 | args->tun_port))) {
387 | errf("failed to create tun device");
388 | return -1;
389 | }
390 | #endif
391 | ctx->nsock = 1;
392 | ctx->socks = calloc(ctx->nsock, sizeof(int));
393 | for (i = 0; i < ctx->nsock; i++) {
394 | int *sock = ctx->socks + i;
395 | if (-1 == (*sock = vpn_udp_alloc(args->mode == SHADOWVPN_MODE_SERVER,
396 | args->server, args->port,
397 | ctx->remote_addrp,
398 | &ctx->remote_addrlen))) {
399 | errf("failed to create UDP socket");
400 | close(ctx->tun);
401 | return -1;
402 | }
403 | }
404 | ctx->args = args;
405 | return 0;
406 | }
407 |
408 | int vpn_run(vpn_ctx_t *ctx) {
409 | fd_set readset;
410 | int max_fd = 0, i;
411 | ssize_t r;
412 | size_t usertoken_len = 0;
413 | if (ctx->running) {
414 | errf("can not start, already running");
415 | return -1;
416 | }
417 |
418 | ctx->running = 1;
419 |
420 | shell_up(ctx->args);
421 |
422 | if (ctx->args->user_tokens_len) {
423 | usertoken_len = SHADOWVPN_USERTOKEN_LEN;
424 | }
425 |
426 | ctx->tun_buf = malloc(ctx->args->mtu + SHADOWVPN_ZERO_BYTES +
427 | usertoken_len);
428 | ctx->udp_buf = malloc(ctx->args->mtu + SHADOWVPN_ZERO_BYTES +
429 | usertoken_len);
430 | bzero(ctx->tun_buf, SHADOWVPN_ZERO_BYTES);
431 | bzero(ctx->udp_buf, SHADOWVPN_ZERO_BYTES);
432 |
433 | if (ctx->args->mode == SHADOWVPN_MODE_SERVER && usertoken_len) {
434 | ctx->nat_ctx = malloc(sizeof(nat_ctx_t));
435 | nat_init(ctx->nat_ctx, ctx->args);
436 | }
437 |
438 | logf("VPN started");
439 |
440 | while (ctx->running) {
441 | FD_ZERO(&readset);
442 | #ifndef TARGET_WIN32
443 | FD_SET(ctx->control_pipe[0], &readset);
444 | #else
445 | FD_SET(ctx->control_fd, &readset);
446 | #endif
447 | FD_SET(ctx->tun, &readset);
448 |
449 | max_fd = 0;
450 | for (i = 0; i < ctx->nsock; i++) {
451 | FD_SET(ctx->socks[i], &readset);
452 | max_fd = max(max_fd, ctx->socks[i]);
453 | }
454 |
455 | // we assume that pipe fd is always less than tun and sock fd which are
456 | // created later
457 | max_fd = max(ctx->tun, max_fd) + 1;
458 |
459 | if (-1 == select(max_fd, &readset, NULL, NULL, NULL)) {
460 | if (errno == EINTR)
461 | continue;
462 | err("select");
463 | break;
464 | }
465 | #ifndef TARGET_WIN32
466 | if (FD_ISSET(ctx->control_pipe[0], &readset)) {
467 | char pipe_buf;
468 | (void)read(ctx->control_pipe[0], &pipe_buf, 1);
469 | break;
470 | }
471 | #else
472 | if (FD_ISSET(ctx->control_fd, &readset)) {
473 | char buf;
474 | recv(ctx->control_fd, &buf, 1, 0);
475 | break;
476 | }
477 | #endif
478 | if (FD_ISSET(ctx->tun, &readset)) {
479 | r = tun_read(ctx->tun,
480 | ctx->tun_buf + SHADOWVPN_ZERO_BYTES + usertoken_len,
481 | ctx->args->mtu);
482 | if (r == -1) {
483 | if (errno == EAGAIN || errno == EWOULDBLOCK) {
484 | // do nothing
485 | } else if (errno == EPERM || errno == EINTR) {
486 | // just log, do nothing
487 | err("read from tun");
488 | } else {
489 | err("read from tun");
490 | break;
491 | }
492 | }
493 | if (usertoken_len) {
494 | if (ctx->args->mode == SHADOWVPN_MODE_CLIENT) {
495 | memcpy(ctx->tun_buf + SHADOWVPN_ZERO_BYTES,
496 | ctx->args->user_tokens[0], usertoken_len);
497 | } else {
498 | // do NAT for downstream
499 | nat_fix_downstream(ctx->nat_ctx,
500 | ctx->tun_buf + SHADOWVPN_ZERO_BYTES,
501 | r + usertoken_len,
502 | ctx->remote_addrp, &ctx->remote_addrlen);
503 | }
504 | }
505 | if (ctx->remote_addrlen) {
506 | crypto_encrypt(ctx->udp_buf, ctx->tun_buf, r + usertoken_len);
507 |
508 | // TODO concurrency is currently removed
509 | int sock_to_send = ctx->socks[0];
510 |
511 | r = sendto(sock_to_send, ctx->udp_buf + SHADOWVPN_PACKET_OFFSET,
512 | SHADOWVPN_OVERHEAD_LEN + usertoken_len + r, 0,
513 | ctx->remote_addrp, ctx->remote_addrlen);
514 | if (r == -1) {
515 | if (errno == EAGAIN || errno == EWOULDBLOCK) {
516 | // do nothing
517 | } else if (errno == ENETUNREACH || errno == ENETDOWN ||
518 | errno == EPERM || errno == EINTR || errno == EMSGSIZE) {
519 | // just log, do nothing
520 | err("sendto");
521 | } else {
522 | err("sendto");
523 | // TODO rebuild socket
524 | break;
525 | }
526 | }
527 | }
528 | }
529 | for (i = 0; i < ctx->nsock; i++) {
530 | int sock = ctx->socks[i];
531 | if (FD_ISSET(sock, &readset)) {
532 | // only change remote addr if decryption succeeds
533 | struct sockaddr_storage temp_remote_addr;
534 | socklen_t temp_remote_addrlen = sizeof(temp_remote_addr);
535 | r = recvfrom(sock, ctx->udp_buf + SHADOWVPN_PACKET_OFFSET,
536 | SHADOWVPN_OVERHEAD_LEN + usertoken_len + ctx->args->mtu, 0,
537 | (struct sockaddr *)&temp_remote_addr,
538 | &temp_remote_addrlen);
539 | if (r == -1) {
540 | if (errno == EAGAIN || errno == EWOULDBLOCK) {
541 | // do nothing
542 | } else if (errno == ENETUNREACH || errno == ENETDOWN ||
543 | errno == EPERM || errno == EINTR) {
544 | // just log, do nothing
545 | err("recvfrom");
546 | } else {
547 | err("recvfrom");
548 | // TODO rebuild socket
549 | break;
550 | }
551 | }
552 | if (r == 0)
553 | continue;
554 |
555 | if (-1 == crypto_decrypt(ctx->tun_buf, ctx->udp_buf,
556 | r - SHADOWVPN_OVERHEAD_LEN)) {
557 | errf("dropping invalid packet, maybe wrong password");
558 | } else {
559 | if (ctx->args->mode == SHADOWVPN_MODE_SERVER) {
560 | // if we are running a server, update server address from
561 | // recv_from
562 | memcpy(ctx->remote_addrp, &temp_remote_addr, temp_remote_addrlen);
563 | ctx->remote_addrlen = temp_remote_addrlen;
564 | }
565 | if (usertoken_len) {
566 | if (ctx->args->mode == SHADOWVPN_MODE_SERVER) {
567 | // do NAT for upstream
568 | if (-1 == nat_fix_upstream(ctx->nat_ctx,
569 | ctx->tun_buf + SHADOWVPN_ZERO_BYTES,
570 | r - SHADOWVPN_OVERHEAD_LEN,
571 | ctx->remote_addrp, ctx->remote_addrlen)) {
572 | continue;
573 | }
574 | }
575 | }
576 | if (-1 == tun_write(ctx->tun,
577 | ctx->tun_buf + SHADOWVPN_ZERO_BYTES + usertoken_len,
578 | r - SHADOWVPN_OVERHEAD_LEN - usertoken_len)) {
579 | if (errno == EAGAIN || errno == EWOULDBLOCK) {
580 | // do nothing
581 | } else if (errno == EPERM || errno == EINTR || errno == EINVAL) {
582 | // just log, do nothing
583 | err("write to tun");
584 | } else {
585 | err("write to tun");
586 | break;
587 | }
588 | }
589 | }
590 | }
591 | }
592 | }
593 | free(ctx->tun_buf);
594 | free(ctx->udp_buf);
595 |
596 | shell_down(ctx->args);
597 |
598 | close(ctx->tun);
599 | for (i = 0; i < ctx->nsock; i++) {
600 | close(ctx->socks[i]);
601 | }
602 |
603 | ctx->running = 0;
604 |
605 | #ifdef TARGET_WIN32
606 | close(ctx->control_fd);
607 | WSACleanup();
608 | SetEvent(ctx->cleanEvent);
609 | #endif
610 |
611 | return -1;
612 | }
613 |
614 | int vpn_stop(vpn_ctx_t *ctx) {
615 | logf("shutting down by user");
616 | if (!ctx->running) {
617 | errf("can not stop, not running");
618 | return -1;
619 | }
620 | ctx->running = 0;
621 | char buf = 0;
622 | #ifndef TARGET_WIN32
623 | if (-1 == write(ctx->control_pipe[1], &buf, 1)) {
624 | err("write");
625 | return -1;
626 | }
627 | #else
628 | int send_sock;
629 | struct sockaddr addr;
630 | socklen_t addrlen;
631 | if (-1 == (send_sock = vpn_udp_alloc(0, TUN_DELEGATE_ADDR, 0, &addr,
632 | &addrlen))) {
633 | errf("failed to init control socket");
634 | return -1;
635 | }
636 | if (-1 == sendto(send_sock, &buf, 1, 0, &ctx->control_addr,
637 | ctx->control_addrlen)) {
638 | err("sendto");
639 | close(send_sock);
640 | return -1;
641 | }
642 | close(send_sock);
643 | WaitForSingleObject(ctx->cleanEvent, INFINITE);
644 | CloseHandle(ctx->cleanEvent);
645 | #endif
646 | return 0;
647 | }
648 |
--------------------------------------------------------------------------------
/src/vpn.h:
--------------------------------------------------------------------------------
1 | /**
2 | vpn.h
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #ifndef VPN_H
22 | #define VPN_H
23 |
24 | #include
25 |
26 | #include "args.h"
27 | #include "nat.h"
28 |
29 | typedef struct {
30 | int running;
31 | int nsock;
32 | int *socks;
33 | int tun;
34 | /* select() in winsock doesn't support file handler */
35 | #ifndef TARGET_WIN32
36 | int control_pipe[2];
37 | #else
38 | int control_fd;
39 | struct sockaddr control_addr;
40 | socklen_t control_addrlen;
41 | HANDLE cleanEvent;
42 | #endif
43 | unsigned char *tun_buf;
44 | unsigned char *udp_buf;
45 |
46 | /* the address we currently use (client only) */
47 | struct sockaddr_storage remote_addr;
48 | /* points to above, just for convenience */
49 | struct sockaddr *remote_addrp;
50 | socklen_t remote_addrlen;
51 | shadowvpn_args_t *args;
52 |
53 | /* server with NAT enabled only */
54 | nat_ctx_t *nat_ctx;
55 | } vpn_ctx_t;
56 |
57 | /* return -1 on error. no need to destroy any resource */
58 | int vpn_ctx_init(vpn_ctx_t *ctx, shadowvpn_args_t *args);
59 |
60 | /* return -1 on error. no need to destroy any resource */
61 | int vpn_run(vpn_ctx_t *ctx);
62 |
63 | /* return -1 on error. no need to destroy any resource */
64 | int vpn_stop(vpn_ctx_t *ctx);
65 |
66 | /* these low level functions are exposed for Android jni */
67 | #ifndef TARGET_WIN32
68 | int vpn_tun_alloc(const char *dev);
69 | #endif
70 | int vpn_udp_alloc(int if_bind, const char *host, int port,
71 | struct sockaddr *addr, socklen_t* addrlen);
72 |
73 | #endif
74 |
--------------------------------------------------------------------------------
/src/win32.c:
--------------------------------------------------------------------------------
1 | /**
2 | win32.c
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 | /*
21 | * Windows TUN/TAP support from iodine
22 | * http://code.kryo.se/iodine/
23 | *
24 | * Copyright (c) 2006-2014 Erik Ekman ,
25 | * 2006-2009 Bjorn Andersson
26 | *
27 | * Permission to use, copy, modify, and/or distribute this software for any
28 | * purpose with or without fee is hereby granted, provided that the above
29 | * copyright notice and this permission notice appear in all copies.
30 | *
31 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
32 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
33 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
34 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
35 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
36 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
37 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
38 | */
39 |
40 | #include "shadowvpn.h"
41 | #include
42 |
43 | struct tun_data {
44 | HANDLE tun;
45 | int sock;
46 | struct sockaddr addr;
47 | socklen_t addrlen;
48 | };
49 |
50 | #define TUN_READER_BUF_SIZE (64 * 1024)
51 | #define TUN_NAME_BUF_SIZE 256
52 |
53 | #define TAP_CONTROL_CODE(request,method) CTL_CODE(FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)
54 | #define TAP_IOCTL_CONFIG_TUN TAP_CONTROL_CODE(10, METHOD_BUFFERED)
55 | #define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE(6, METHOD_BUFFERED)
56 |
57 | #define TAP_ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
58 | #define NETWORK_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
59 | #define TAP_DEVICE_SPACE "\\\\.\\Global\\"
60 | #define TAP_VERSION_ID_0801 "tap0801"
61 | #define TAP_VERSION_ID_0901 "tap0901"
62 | #define KEY_COMPONENT_ID "ComponentId"
63 | #define NET_CFG_INST_ID "NetCfgInstanceId"
64 | #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR, 12)
65 |
66 | HANDLE dev_handle;
67 | static struct tun_data data;
68 | static char if_name[TUN_NAME_BUF_SIZE];
69 |
70 | static void get_name(char *ifname, int namelen, char *dev_name);
71 |
72 | static void get_device(char *device, int device_len, const char *wanted_dev) {
73 | LONG status;
74 | HKEY adapter_key;
75 | int index;
76 |
77 | index = 0;
78 | status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TAP_ADAPTER_KEY, 0, KEY_READ,
79 | &adapter_key);
80 |
81 | if (status != ERROR_SUCCESS) {
82 | errf("Error opening registry key " TAP_ADAPTER_KEY );
83 | return;
84 | }
85 |
86 | while (TRUE) {
87 | char name[TUN_NAME_BUF_SIZE];
88 | char unit[TUN_NAME_BUF_SIZE];
89 | char component[TUN_NAME_BUF_SIZE];
90 |
91 | char cid_string[TUN_NAME_BUF_SIZE] = KEY_COMPONENT_ID;
92 | HKEY device_key;
93 | DWORD datatype;
94 | DWORD len;
95 |
96 | /* Iterate through all adapter of this kind */
97 | len = sizeof(name);
98 | status = RegEnumKeyEx(adapter_key, index, name, &len, NULL, NULL, NULL,
99 | NULL);
100 | if (status == ERROR_NO_MORE_ITEMS) {
101 | break;
102 | } else if (status != ERROR_SUCCESS) {
103 | errf("Error enumerating subkeys of registry key " TAP_ADAPTER_KEY );
104 | break;
105 | }
106 |
107 | snprintf(unit, sizeof(unit), TAP_ADAPTER_KEY "\\%s", name);
108 | status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, unit, 0, KEY_READ, &device_key);
109 | if (status != ERROR_SUCCESS) {
110 | errf("Error opening registry key %s", unit);
111 | goto next;
112 | }
113 |
114 | /* Check component id */
115 | len = sizeof(component);
116 | status = RegQueryValueEx(device_key, cid_string, NULL, &datatype,
117 | (LPBYTE)component, &len);
118 | if (status != ERROR_SUCCESS || datatype != REG_SZ) {
119 | goto next;
120 | }
121 | if (strncmp(TAP_VERSION_ID_0801, component,
122 | strlen(TAP_VERSION_ID_0801)) == 0 ||
123 | strncmp(TAP_VERSION_ID_0901, component,
124 | strlen(TAP_VERSION_ID_0901)) == 0) {
125 | /* We found a TAP32 device, get its NetCfgInstanceId */
126 | char iid_string[TUN_NAME_BUF_SIZE] = NET_CFG_INST_ID;
127 |
128 | status = RegQueryValueEx(device_key, iid_string, NULL, &datatype,
129 | (LPBYTE) device, (DWORD *) &device_len);
130 | if (status != ERROR_SUCCESS || datatype != REG_SZ) {
131 | errf("Error reading registry key %s\\%s on TAP device", unit,
132 | iid_string);
133 | } else {
134 | /* Done getting GUID of TAP device,
135 | * now check if the name is the requested one */
136 | if (wanted_dev) {
137 | char name[TUN_NAME_BUF_SIZE];
138 | get_name(name, sizeof(name), device);
139 | if (strncmp(name, wanted_dev, strlen(wanted_dev))) {
140 | /* Skip if name mismatch */
141 | goto next;
142 | }
143 | }
144 | /* Get the if name */
145 | get_name(if_name, sizeof(if_name), device);
146 | RegCloseKey(device_key);
147 | return;
148 | }
149 | }
150 | next:
151 | RegCloseKey(device_key);
152 | index++;
153 | }
154 | RegCloseKey(adapter_key);
155 | }
156 |
157 | static void get_name(char *ifname, int namelen, char *dev_name) {
158 | char path[TUN_NAME_BUF_SIZE];
159 | char name_str[TUN_NAME_BUF_SIZE] = "Name";
160 | LONG status;
161 | HKEY conn_key;
162 | DWORD len;
163 | DWORD datatype;
164 |
165 | memset(ifname, 0, namelen);
166 |
167 | snprintf(path, sizeof(path), NETWORK_KEY "\\%s\\Connection", dev_name);
168 | status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_READ, &conn_key);
169 | if (status != ERROR_SUCCESS) {
170 | errf("could not look up name of interface %s: error opening key\n",
171 | dev_name);
172 | RegCloseKey(conn_key);
173 | return;
174 | }
175 | len = namelen;
176 | status = RegQueryValueEx(conn_key, name_str, NULL, &datatype, (LPBYTE)ifname,
177 | &len);
178 | if (status != ERROR_SUCCESS || datatype != REG_SZ) {
179 | errf("could not look up name of interface %s: error reading value\n",
180 | dev_name);
181 | RegCloseKey(conn_key);
182 | return;
183 | }
184 | RegCloseKey(conn_key);
185 | }
186 |
187 | static int inet_aton(const char *cp, struct in_addr *inp) {
188 | inp->s_addr = inet_addr(cp);
189 | return inp->s_addr != INADDR_ANY;
190 | }
191 |
192 | static int tun_setip(const char *ip, int netbits) {
193 | int netmask;
194 | struct in_addr net;
195 | int i;
196 | int r;
197 | DWORD status;
198 | DWORD ipdata[3];
199 | struct in_addr addr;
200 | DWORD len;
201 |
202 | if (ip == NULL) {
203 | errf("missing tunip: win32 needs to specify tun ip");
204 | return -1;
205 | }
206 |
207 | netmask = 0;
208 | for (i = 0; i < netbits; i++) {
209 | netmask = (netmask << 1) | 1;
210 | }
211 | netmask <<= (32 - netbits);
212 | net.s_addr = htonl(netmask);
213 |
214 | if (inet_addr(ip) == INADDR_NONE) {
215 | errf("invalid tun ip: %s", ip);
216 | return -1;
217 | }
218 |
219 | /* Set device as connected */
220 | logf("enabling interface '%s'", if_name);
221 | status = 1;
222 | r = DeviceIoControl(dev_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status,
223 | sizeof(status), &status, sizeof(status), &len, NULL);
224 | if (!r) {
225 | errf("failed to enable interface");
226 | return -1;
227 | }
228 |
229 | if (inet_aton(ip, &addr)) {
230 | ipdata[0] = (DWORD) addr.s_addr; /* local ip addr */
231 | ipdata[1] = net.s_addr & ipdata[0]; /* network addr */
232 | ipdata[2] = (DWORD) net.s_addr; /* netmask */
233 | } else {
234 | return -1;
235 | }
236 |
237 | /* Tell ip/networkaddr/netmask to device for arp use */
238 | r = DeviceIoControl(dev_handle, TAP_IOCTL_CONFIG_TUN, &ipdata,
239 | sizeof(ipdata), &ipdata, sizeof(ipdata), &len, NULL);
240 | if (!r) {
241 | errf("failed to set interface in tun mode");
242 | return -1;
243 | }
244 |
245 | return 0;
246 | }
247 |
248 | DWORD WINAPI tun_reader(LPVOID arg) {
249 | struct tun_data *tun = arg;
250 | char buf[TUN_READER_BUF_SIZE];
251 | int len;
252 | int res;
253 | OVERLAPPED olpd;
254 | int sock;
255 | struct sockaddr addr;
256 | socklen_t addrlen;
257 |
258 | sock = vpn_udp_alloc(1, TUN_DELEGATE_ADDR, 0, &addr, &addrlen);
259 |
260 | olpd.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
261 |
262 | while(TRUE) {
263 | olpd.Offset = 0;
264 | olpd.OffsetHigh = 0;
265 | res = ReadFile(tun->tun, buf, sizeof(buf), (LPDWORD) &len, &olpd);
266 | if (!res) {
267 | WaitForSingleObject(olpd.hEvent, INFINITE);
268 | res = GetOverlappedResult(dev_handle, &olpd, (LPDWORD) &len, FALSE);
269 | res = sendto(sock, buf, len, 0, &tun->addr, tun->addrlen);
270 | }
271 | }
272 |
273 | return 0;
274 | }
275 |
276 | int tun_open(const char *tun_device, const char *tun_ip, int tun_mask,
277 | int tun_port) {
278 | char adapter[TUN_NAME_BUF_SIZE];
279 | char tapfile[TUN_NAME_BUF_SIZE * 2];
280 | int tunfd;
281 |
282 | memset(adapter, 0, sizeof(adapter));
283 | memset(if_name, 0, sizeof(if_name));
284 | get_device(adapter, sizeof(adapter), tun_device);
285 |
286 | if (strlen(adapter) == 0 || strlen(if_name) == 0) {
287 | if (tun_device) {
288 | errf("no TAP adapters found");
289 | } else {
290 | errf("no TAP adapters found: version 0801 and 0901 are supported");
291 | }
292 | return -1;
293 | }
294 |
295 | logf("opening device %s\n", if_name);
296 | snprintf(tapfile, sizeof(tapfile), "%s%s.tap", TAP_DEVICE_SPACE, adapter);
297 | dev_handle = CreateFile(tapfile, GENERIC_WRITE | GENERIC_READ, 0, 0,
298 | OPEN_EXISTING,
299 | FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, NULL);
300 | if (dev_handle == INVALID_HANDLE_VALUE) {
301 | errf("can not open device");
302 | return -1;
303 | }
304 | if (0 != tun_setip(tun_ip, tun_mask)) {
305 | errf("can not connect device");
306 | return -1;
307 | }
308 |
309 | /* Use a UDP connection to forward packets from tun,
310 | * so we can still use select() in main code.
311 | * A thread does blocking reads on tun device and
312 | * sends data as udp to this socket */
313 |
314 | tunfd = vpn_udp_alloc(1, TUN_DELEGATE_ADDR, tun_port, &data.addr,
315 | &data.addrlen);
316 | if (INVALID_SOCKET == tunfd) {
317 | errf("can not bind delegate port for tun: %d", tun_port);
318 | return -1;
319 | }
320 |
321 | data.tun = dev_handle;
322 | CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) tun_reader, &data, 0, NULL);
323 | return tunfd;
324 | }
325 |
326 | int setenv(const char *name, const char *value, int overwrite) {
327 | char envbuf[TUN_NAME_BUF_SIZE];
328 | snprintf(envbuf, sizeof(envbuf), "%s=%s", name, value);
329 | return _putenv(envbuf);
330 | }
331 |
332 | /*
333 | * disable new behavior using IOCTL: SIO_UDP_CONNRESET
334 | * Reference: http://support2.microsoft.com/kb/263823/en-us
335 | */
336 | int disable_reset_report(int fd) {
337 | DWORD dwBytesReturned = 0;
338 | BOOL bNewBehavior = FALSE;
339 | if (INVALID_SOCKET == fd) {
340 | return -1;
341 | }
342 | if (SOCKET_ERROR == WSAIoctl(fd, SIO_UDP_CONNRESET,
343 | &bNewBehavior, sizeof(bNewBehavior),
344 | NULL, 0, &dwBytesReturned, NULL, NULL)) {
345 | errf("cannot disable UDP-Socket option SIO_UDP_CONNRESET");
346 | close(fd);
347 | return -1;
348 | }
349 | return fd;
350 | }
351 |
--------------------------------------------------------------------------------
/src/win32.h:
--------------------------------------------------------------------------------
1 | /**
2 | win32.h
3 |
4 | Copyright (C) 2015 clowwindy
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with this program. If not, see .
18 |
19 | */
20 |
21 | #ifndef WIN32_H
22 | #define WIN32_H
23 |
24 | #ifdef _WIN32_WINNT
25 | #undef _WIN32_WINNT
26 | #endif
27 |
28 | #define _WIN32_WINNT 0x0501
29 |
30 | #include
31 | #include
32 | #include
33 |
34 | #define bzero(...) ZeroMemory(__VA_ARGS__)
35 | #define TUN_DELEGATE_ADDR "127.0.0.1"
36 | #define TUN_DELEGATE_PORT 55151
37 |
38 | extern HANDLE dev_handle;
39 |
40 | int tun_open(const char *tun_device, const char *tun_ip, int tun_mask, int tun_port);
41 | int setenv(const char *name, const char *value, int overwrite);
42 | int disable_reset_report(int fd);
43 |
44 | #endif
45 |
--------------------------------------------------------------------------------
/tests/concurrency.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # conn=1
4 | # server=root@x.x.x.x
5 |
6 | sudo sed -i -E "s/concurrency=[[:digit:]]+/concurrency=$conn/g" /etc/shadowvpn/client.conf
7 | ssh $server "sed -i -E \"s/concurrency=[[:digit:]]+/concurrency=$conn/g\" /etc/shadowvpn/server.conf"
8 | ssh $server "shadowvpn -c /etc/shadowvpn/server.conf -s restart"
9 | sudo shadowvpn -s restart -c /etc/shadowvpn/client.conf
10 | sleep 5
11 |
12 | ping -c 20 -i 0.2 -n 10.8.0.1
13 | curl http://speedtest.tokyo.linode.com/100MB-tokyo.bin >/dev/null
14 |
--------------------------------------------------------------------------------
/tools/gen_chnroutes.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | path=$(dirname $0)
4 |
5 | list=$(grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}" $path/chnroute.txt |\
6 | sed -e "s/^/route \$action /" -e "s/$/ \$suf/")
7 |
8 | cat <<-EOH > $path/chnroutes.sh
9 | #!/bin/sh
10 |
11 | if [ "\$1" = "down" -o "\$1" = "del" ]; then
12 | action=del
13 | else
14 | action=add
15 | suf="via \$(ip route show 0/0 | grep via | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}')"
16 | fi
17 |
18 | ip -batch - < foreign.txt
6 |
7 | list=$(grep -E "^([0-9]{1,3}\.){3}[0-9]{1,3}" foreign.txt |\
8 | sed -e "s/^/route \$action /" -e "s/$/ \$suf/")
9 |
10 | cat <<-EOH > foreign.sh
11 | #!/bin/sh
12 |
13 | if [ "\$1" = "down" -o "\$1" = "del" ]; then
14 | action=del
15 | else
16 | action=add
17 | suf="via 10.7.0.1"
18 | fi
19 |
20 | ip -batch - <