1 // SoftEther VPN Source Code - Stable Edition Repository
2 // Cedar Communication Module
3 //
4 // SoftEther VPN Server, Client and Bridge are free software under the Apache License, Version 2.0.
5 //
6 // Copyright (c) Daiyuu Nobori.
7 // Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
8 // Copyright (c) SoftEther Corporation.
9 // Copyright (c) all contributors on SoftEther VPN project in GitHub.
10 //
11 // All Rights Reserved.
12 //
13 // http://www.softether.org/
14 //
15 // This stable branch is officially managed by Daiyuu Nobori, the owner of SoftEther VPN Project.
16 // Pull requests should be sent to the Developer Edition Master Repository on https://github.com/SoftEtherVPN/SoftEtherVPN
17 //
18 // License: The Apache License, Version 2.0
19 // https://www.apache.org/licenses/LICENSE-2.0
20 //
21 // DISCLAIMER
22 // ==========
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 // SOFTWARE.
31 //
32 // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER
33 // JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH,
34 // DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY
35 // JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS,
36 // AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER
37 // SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND
38 // OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING,
39 // AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
40 // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE
41 // JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE
42 // ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS.
43 // PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE
44 // LAW OR COURT RULE.
45 //
46 // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE
47 // A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL
48 // RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS
49 // COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND
50 // DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING
51 // CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER
52 // COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES.
53 // WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
54 // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES
55 // AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH
56 // DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS
57 // AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE
58 // PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A
59 // PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE
60 // LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
61 // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A
62 // STATEMENT FOR WARNING AND DISCLAIMER.
63 //
64 // READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE.
65 // SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH
66 // LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE.
67 //
68 //
69 // SOURCE CODE CONTRIBUTION
70 // ------------------------
71 //
72 // Your contribution to SoftEther VPN Project is much appreciated.
73 // Please send patches to us through GitHub.
74 // Read the SoftEther VPN Patch Acceptance Policy in advance:
75 // http://www.softether.org/5-download/src/9.patch
76 //
77 //
78 // DEAR SECURITY EXPERTS
79 // ---------------------
80 //
81 // If you find a bug or a security vulnerability please kindly inform us
82 // about the problem immediately so that we can fix the security problem
83 // to protect a lot of users around the world as soon as possible.
84 //
85 // Our e-mail address for security reports is:
86 // softether-vpn-security [at] softether.org
87 //
88 // Please note that the above e-mail address is not a technical support
89 // inquiry address. If you need technical assistance, please visit
90 // http://www.softether.org/ and ask your question on the users forum.
91 //
92 // Thank you for your cooperation.
93 //
94 //
95 // NO MEMORY OR RESOURCE LEAKS
96 // ---------------------------
97 //
98 // The memory-leaks and resource-leaks verification under the stress
99 // test has been passed before release this source code.
100 
101 
102 // Protocol.c
103 // SoftEther protocol related routines
104 
105 #include "CedarPch.h"
106 
107 static UCHAR ssl_packet_start[3] = {0x17, 0x03, 0x00};
108 
109 // MIME list from https://www.freeformatter.com/mime-types-list.html
110 static HTTP_MIME_TYPE http_mime_types[] =
111 {
112 	{".x3d", "application/vnd.hzn-3d-crossword"},
113 	{".3gp", "video/3gpp"},
114 	{".3g2", "video/3gpp2"},
115 	{".mseq", "application/vnd.mseq"},
116 	{".pwn", "application/vnd.3m.post-it-notes"},
117 	{".plb", "application/vnd.3gpp.pic-bw-large"},
118 	{".psb", "application/vnd.3gpp.pic-bw-small"},
119 	{".pvb", "application/vnd.3gpp.pic-bw-var"},
120 	{".tcap", "application/vnd.3gpp2.tcap"},
121 	{".7z", "application/x-7z-compressed"},
122 	{".abw", "application/x-abiword"},
123 	{".ace", "application/x-ace-compressed"},
124 	{".acc", "application/vnd.americandynamics.acc"},
125 	{".acu", "application/vnd.acucobol"},
126 	{".atc", "application/vnd.acucorp"},
127 	{".adp", "audio/adpcm"},
128 	{".aab", "application/x-authorware-bin"},
129 	{".aam", "application/x-authorware-map"},
130 	{".aas", "application/x-authorware-seg"},
131 	{".air", "application/vnd.adobe.air-application-installer-package+zip"},
132 	{".swf", "application/x-shockwave-flash"},
133 	{".fxp", "application/vnd.adobe.fxp"},
134 	{".pdf", "application/pdf"},
135 	{".ppd", "application/vnd.cups-ppd"},
136 	{".dir", "application/x-director"},
137 	{".xdp", "application/vnd.adobe.xdp+xml"},
138 	{".xfdf", "application/vnd.adobe.xfdf"},
139 	{".aac", "audio/x-aac"},
140 	{".ahead", "application/vnd.ahead.space"},
141 	{".azf", "application/vnd.airzip.filesecure.azf"},
142 	{".azs", "application/vnd.airzip.filesecure.azs"},
143 	{".azw", "application/vnd.amazon.ebook"},
144 	{".ami", "application/vnd.amiga.ami"},
145 	{".apk", "application/vnd.android.package-archive"},
146 	{".cii", "application/vnd.anser-web-certificate-issue-initiation"},
147 	{".fti", "application/vnd.anser-web-funds-transfer-initiation"},
148 	{".atx", "application/vnd.antix.game-component"},
149 	{".dmg", "application/x-apple-diskimage"},
150 	{".mpkg", "application/vnd.apple.installer+xml"},
151 	{".aw", "application/applixware"},
152 	{".les", "application/vnd.hhe.lesson-player"},
153 	{".swi", "application/vnd.aristanetworks.swi"},
154 	{".s", "text/x-asm"},
155 	{".atomcat", "application/atomcat+xml"},
156 	{".atomsvc", "application/atomsvc+xml"},
157 	{".atom", "application/atom+xml"},
158 	{".ac", "application/pkix-attr-cert"},
159 	{".aif", "audio/x-aiff"},
160 	{".avi", "video/x-msvideo"},
161 	{".aep", "application/vnd.audiograph"},
162 	{".dxf", "image/vnd.dxf"},
163 	{".dwf", "model/vnd.dwf"},
164 	{".par", "text/plain-bas"},
165 	{".bcpio", "application/x-bcpio"},
166 	{".bin", "application/octet-stream"},
167 	{".bmp", "image/bmp"},
168 	{".torrent", "application/x-bittorrent"},
169 	{".cod", "application/vnd.rim.cod"},
170 	{".mpm", "application/vnd.blueice.multipass"},
171 	{".bmi", "application/vnd.bmi"},
172 	{".sh", "application/x-sh"},
173 	{".btif", "image/prs.btif"},
174 	{".rep", "application/vnd.businessobjects"},
175 	{".bz", "application/x-bzip"},
176 	{".bz2", "application/x-bzip2"},
177 	{".csh", "application/x-csh"},
178 	{".c", "text/x-c"},
179 	{".cdxml", "application/vnd.chemdraw+xml"},
180 	{".css", "text/css"},
181 	{".cdx", "chemical/x-cdx"},
182 	{".cml", "chemical/x-cml"},
183 	{".csml", "chemical/x-csml"},
184 	{".cdbcmsg", "application/vnd.contact.cmsg"},
185 	{".cla", "application/vnd.claymore"},
186 	{".c4g", "application/vnd.clonk.c4group"},
187 	{".sub", "image/vnd.dvb.subtitle"},
188 	{".cdmia", "application/cdmi-capability"},
189 	{".cdmic", "application/cdmi-container"},
190 	{".cdmid", "application/cdmi-domain"},
191 	{".cdmio", "application/cdmi-object"},
192 	{".cdmiq", "application/cdmi-queue"},
193 	{".c11amc", "application/vnd.cluetrust.cartomobile-config"},
194 	{".c11amz", "application/vnd.cluetrust.cartomobile-config-pkg"},
195 	{".ras", "image/x-cmu-raster"},
196 	{".dae", "model/vnd.collada+xml"},
197 	{".csv", "text/csv"},
198 	{".cpt", "application/mac-compactpro"},
199 	{".wmlc", "application/vnd.wap.wmlc"},
200 	{".cgm", "image/cgm"},
201 	{".ice", "x-conference/x-cooltalk"},
202 	{".cmx", "image/x-cmx"},
203 	{".xar", "application/vnd.xara"},
204 	{".cmc", "application/vnd.cosmocaller"},
205 	{".cpio", "application/x-cpio"},
206 	{".clkx", "application/vnd.crick.clicker"},
207 	{".clkk", "application/vnd.crick.clicker.keyboard"},
208 	{".clkp", "application/vnd.crick.clicker.palette"},
209 	{".clkt", "application/vnd.crick.clicker.template"},
210 	{".clkw", "application/vnd.crick.clicker.wordbank"},
211 	{".wbs", "application/vnd.criticaltools.wbs+xml"},
212 	{".cryptonote", "application/vnd.rig.cryptonote"},
213 	{".cif", "chemical/x-cif"},
214 	{".cmdf", "chemical/x-cmdf"},
215 	{".cu", "application/cu-seeme"},
216 	{".cww", "application/prs.cww"},
217 	{".curl", "text/vnd.curl"},
218 	{".dcurl", "text/vnd.curl.dcurl"},
219 	{".mcurl", "text/vnd.curl.mcurl"},
220 	{".scurl", "text/vnd.curl.scurl"},
221 	{".car", "application/vnd.curl.car"},
222 	{".pcurl", "application/vnd.curl.pcurl"},
223 	{".cmp", "application/vnd.yellowriver-custom-menu"},
224 	{".dssc", "application/dssc+der"},
225 	{".xdssc", "application/dssc+xml"},
226 	{".deb", "application/x-debian-package"},
227 	{".uva", "audio/vnd.dece.audio"},
228 	{".uvi", "image/vnd.dece.graphic"},
229 	{".uvh", "video/vnd.dece.hd"},
230 	{".uvm", "video/vnd.dece.mobile"},
231 	{".uvu", "video/vnd.uvvu.mp4"},
232 	{".uvp", "video/vnd.dece.pd"},
233 	{".uvs", "video/vnd.dece.sd"},
234 	{".uvv", "video/vnd.dece.video"},
235 	{".dvi", "application/x-dvi"},
236 	{".seed", "application/vnd.fdsn.seed"},
237 	{".dtb", "application/x-dtbook+xml"},
238 	{".res", "application/x-dtbresource+xml"},
239 	{".ait", "application/vnd.dvb.ait"},
240 	{".svc", "application/vnd.dvb.service"},
241 	{".eol", "audio/vnd.digital-winds"},
242 	{".djvu", "image/vnd.djvu"},
243 	{".dtd", "application/xml-dtd"},
244 	{".mlp", "application/vnd.dolby.mlp"},
245 	{".wad", "application/x-doom"},
246 	{".dpg", "application/vnd.dpgraph"},
247 	{".dra", "audio/vnd.dra"},
248 	{".dfac", "application/vnd.dreamfactory"},
249 	{".dts", "audio/vnd.dts"},
250 	{".dtshd", "audio/vnd.dts.hd"},
251 	{".dwg", "image/vnd.dwg"},
252 	{".geo", "application/vnd.dynageo"},
253 	{".es", "application/ecmascript"},
254 	{".mag", "application/vnd.ecowin.chart"},
255 	{".mmr", "image/vnd.fujixerox.edmics-mmr"},
256 	{".rlc", "image/vnd.fujixerox.edmics-rlc"},
257 	{".exi", "application/exi"},
258 	{".mgz", "application/vnd.proteus.magazine"},
259 	{".epub", "application/epub+zip"},
260 	{".eml", "message/rfc822"},
261 	{".nml", "application/vnd.enliven"},
262 	{".xpr", "application/vnd.is-xpr"},
263 	{".xif", "image/vnd.xiff"},
264 	{".xfdl", "application/vnd.xfdl"},
265 	{".emma", "application/emma+xml"},
266 	{".ez2", "application/vnd.ezpix-album"},
267 	{".ez3", "application/vnd.ezpix-package"},
268 	{".fst", "image/vnd.fst"},
269 	{".fvt", "video/vnd.fvt"},
270 	{".fbs", "image/vnd.fastbidsheet"},
271 	{".fe_launch", "application/vnd.denovo.fcselayout-link"},
272 	{".f4v", "video/x-f4v"},
273 	{".flv", "video/x-flv"},
274 	{".fpx", "image/vnd.fpx"},
275 	{".npx", "image/vnd.net-fpx"},
276 	{".flx", "text/vnd.fmi.flexstor"},
277 	{".fli", "video/x-fli"},
278 	{".ftc", "application/vnd.fluxtime.clip"},
279 	{".fdf", "application/vnd.fdf"},
280 	{".f", "text/x-fortran"},
281 	{".mif", "application/vnd.mif"},
282 	{".fm", "application/vnd.framemaker"},
283 	{".fh", "image/x-freehand"},
284 	{".fsc", "application/vnd.fsc.weblaunch"},
285 	{".fnc", "application/vnd.frogans.fnc"},
286 	{".ltf", "application/vnd.frogans.ltf"},
287 	{".ddd", "application/vnd.fujixerox.ddd"},
288 	{".xdw", "application/vnd.fujixerox.docuworks"},
289 	{".xbd", "application/vnd.fujixerox.docuworks.binder"},
290 	{".oas", "application/vnd.fujitsu.oasys"},
291 	{".oa2", "application/vnd.fujitsu.oasys2"},
292 	{".oa3", "application/vnd.fujitsu.oasys3"},
293 	{".fg5", "application/vnd.fujitsu.oasysgp"},
294 	{".bh2", "application/vnd.fujitsu.oasysprs"},
295 	{".spl", "application/x-futuresplash"},
296 	{".fzs", "application/vnd.fuzzysheet"},
297 	{".g3", "image/g3fax"},
298 	{".gmx", "application/vnd.gmx"},
299 	{".gtw", "model/vnd.gtw"},
300 	{".txd", "application/vnd.genomatix.tuxedo"},
301 	{".ggb", "application/vnd.geogebra.file"},
302 	{".ggt", "application/vnd.geogebra.tool"},
303 	{".gdl", "model/vnd.gdl"},
304 	{".gex", "application/vnd.geometry-explorer"},
305 	{".gxt", "application/vnd.geonext"},
306 	{".g2w", "application/vnd.geoplan"},
307 	{".g3w", "application/vnd.geospace"},
308 	{".gsf", "application/x-font-ghostscript"},
309 	{".bdf", "application/x-font-bdf"},
310 	{".gtar", "application/x-gtar"},
311 	{".texinfo", "application/x-texinfo"},
312 	{".gnumeric", "application/x-gnumeric"},
313 	{".kml", "application/vnd.google-earth.kml+xml"},
314 	{".kmz", "application/vnd.google-earth.kmz"},
315 	{".gqf", "application/vnd.grafeq"},
316 	{".gif", "image/gif"},
317 	{".gv", "text/vnd.graphviz"},
318 	{".gac", "application/vnd.groove-account"},
319 	{".ghf", "application/vnd.groove-help"},
320 	{".gim", "application/vnd.groove-identity-message"},
321 	{".grv", "application/vnd.groove-injector"},
322 	{".gtm", "application/vnd.groove-tool-message"},
323 	{".tpl", "application/vnd.groove-tool-template"},
324 	{".vcg", "application/vnd.groove-vcard"},
325 	{".h261", "video/h261"},
326 	{".h263", "video/h263"},
327 	{".h264", "video/h264"},
328 	{".hpid", "application/vnd.hp-hpid"},
329 	{".hps", "application/vnd.hp-hps"},
330 	{".hdf", "application/x-hdf"},
331 	{".rip", "audio/vnd.rip"},
332 	{".hbci", "application/vnd.hbci"},
333 	{".jlt", "application/vnd.hp-jlyt"},
334 	{".pcl", "application/vnd.hp-pcl"},
335 	{".hpgl", "application/vnd.hp-hpgl"},
336 	{".hvs", "application/vnd.yamaha.hv-script"},
337 	{".hvd", "application/vnd.yamaha.hv-dic"},
338 	{".hvp", "application/vnd.yamaha.hv-voice"},
339 	{".sfd-hdstx", "application/vnd.hydrostatix.sof-data"},
340 	{".stk", "application/hyperstudio"},
341 	{".hal", "application/vnd.hal+xml"},
342 	{".htm", "text/html; charset=utf-8"},
343 	{".html", "text/html; charset=utf-8"},
344 	{".irm", "application/vnd.ibm.rights-management"},
345 	{".sc", "application/vnd.ibm.secure-container"},
346 	{".ics", "text/calendar"},
347 	{".icc", "application/vnd.iccprofile"},
348 	{".ico", "image/x-icon"},
349 	{".igl", "application/vnd.igloader"},
350 	{".ief", "image/ief"},
351 	{".ivp", "application/vnd.immervision-ivp"},
352 	{".ivu", "application/vnd.immervision-ivu"},
353 	{".rif", "application/reginfo+xml"},
354 	{".3dml", "text/vnd.in3d.3dml"},
355 	{".spot", "text/vnd.in3d.spot"},
356 	{".igs", "model/iges"},
357 	{".i2g", "application/vnd.intergeo"},
358 	{".cdy", "application/vnd.cinderella"},
359 	{".xpw", "application/vnd.intercon.formnet"},
360 	{".fcs", "application/vnd.isac.fcs"},
361 	{".ipfix", "application/ipfix"},
362 	{".cer", "application/pkix-cert"},
363 	{".pki", "application/pkixcmp"},
364 	{".crl", "application/pkix-crl"},
365 	{".pkipath", "application/pkix-pkipath"},
366 	{".igm", "application/vnd.insors.igm"},
367 	{".rcprofile", "application/vnd.ipunplugged.rcprofile"},
368 	{".irp", "application/vnd.irepository.package+xml"},
369 	{".jad", "text/vnd.sun.j2me.app-descriptor"},
370 	{".jar", "application/java-archive"},
371 	{".class", "application/java-vm"},
372 	{".jnlp", "application/x-java-jnlp-file"},
373 	{".ser", "application/java-serialized-object"},
374 	{".java", "text/x-java-source"},
375 	{".js", "application/javascript"},
376 	{".json", "application/json"},
377 	{".joda", "application/vnd.joost.joda-archive"},
378 	{".jpm", "video/jpm"},
379 	{".jpg", "image/jpeg"},
380 	{".jpeg", "image/jpeg"},
381 	{".pjpeg", "image/pjpeg"},
382 	{".jpgv", "video/jpeg"},
383 	{".ktz", "application/vnd.kahootz"},
384 	{".mmd", "application/vnd.chipnuts.karaoke-mmd"},
385 	{".karbon", "application/vnd.kde.karbon"},
386 	{".chrt", "application/vnd.kde.kchart"},
387 	{".kfo", "application/vnd.kde.kformula"},
388 	{".flw", "application/vnd.kde.kivio"},
389 	{".kon", "application/vnd.kde.kontour"},
390 	{".kpr", "application/vnd.kde.kpresenter"},
391 	{".ksp", "application/vnd.kde.kspread"},
392 	{".kwd", "application/vnd.kde.kword"},
393 	{".htke", "application/vnd.kenameaapp"},
394 	{".kia", "application/vnd.kidspiration"},
395 	{".kne", "application/vnd.kinar"},
396 	{".sse", "application/vnd.kodak-descriptor"},
397 	{".lasxml", "application/vnd.las.las+xml"},
398 	{".latex", "application/x-latex"},
399 	{".lbd", "application/vnd.llamagraphics.life-balance.desktop"},
400 	{".lbe", "application/vnd.llamagraphics.life-balance.exchange+xml"},
401 	{".jam", "application/vnd.jam"},
402 	{"0.123", "application/vnd.lotus-1-2-3"},
403 	{".apr", "application/vnd.lotus-approach"},
404 	{".pre", "application/vnd.lotus-freelance"},
405 	{".nsf", "application/vnd.lotus-notes"},
406 	{".org", "application/vnd.lotus-organizer"},
407 	{".scm", "application/vnd.lotus-screencam"},
408 	{".lwp", "application/vnd.lotus-wordpro"},
409 	{".lvp", "audio/vnd.lucent.voice"},
410 	{".m3u", "audio/x-mpegurl"},
411 	{".m4v", "video/x-m4v"},
412 	{".hqx", "application/mac-binhex40"},
413 	{".portpkg", "application/vnd.macports.portpkg"},
414 	{".mgp", "application/vnd.osgeo.mapguide.package"},
415 	{".mrc", "application/marc"},
416 	{".mrcx", "application/marcxml+xml"},
417 	{".mxf", "application/mxf"},
418 	{".nbp", "application/vnd.wolfram.player"},
419 	{".ma", "application/mathematica"},
420 	{".mathml", "application/mathml+xml"},
421 	{".mbox", "application/mbox"},
422 	{".mc1", "application/vnd.medcalcdata"},
423 	{".mscml", "application/mediaservercontrol+xml"},
424 	{".cdkey", "application/vnd.mediastation.cdkey"},
425 	{".mwf", "application/vnd.mfer"},
426 	{".mfm", "application/vnd.mfmp"},
427 	{".msh", "model/mesh"},
428 	{".mads", "application/mads+xml"},
429 	{".mets", "application/mets+xml"},
430 	{".mods", "application/mods+xml"},
431 	{".meta4", "application/metalink4+xml"},
432 	{".mcd", "application/vnd.mcd"},
433 	{".flo", "application/vnd.micrografx.flo"},
434 	{".igx", "application/vnd.micrografx.igx"},
435 	{".es3", "application/vnd.eszigno3+xml"},
436 	{".mdb", "application/x-msaccess"},
437 	{".asf", "video/x-ms-asf"},
438 	{".exe", "application/x-msdownload"},
439 	{".cil", "application/vnd.ms-artgalry"},
440 	{".cab", "application/vnd.ms-cab-compressed"},
441 	{".ims", "application/vnd.ms-ims"},
442 	{".application", "application/x-ms-application"},
443 	{".clp", "application/x-msclip"},
444 	{".mdi", "image/vnd.ms-modi"},
445 	{".eot", "application/vnd.ms-fontobject"},
446 	{".xls", "application/vnd.ms-excel"},
447 	{".xlam", "application/vnd.ms-excel.addin.macroenabled.12"},
448 	{".xlsb", "application/vnd.ms-excel.sheet.binary.macroenabled.12"},
449 	{".xltm", "application/vnd.ms-excel.template.macroenabled.12"},
450 	{".xlsm", "application/vnd.ms-excel.sheet.macroenabled.12"},
451 	{".chm", "application/vnd.ms-htmlhelp"},
452 	{".crd", "application/x-mscardfile"},
453 	{".lrm", "application/vnd.ms-lrm"},
454 	{".mvb", "application/x-msmediaview"},
455 	{".mny", "application/x-msmoney"},
456 	{".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
457 	{".sldx", "application/vnd.openxmlformats-officedocument.presentationml.slide"},
458 	{".ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow"},
459 	{".potx", "application/vnd.openxmlformats-officedocument.presentationml.template"},
460 	{".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
461 	{".xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template"},
462 	{".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
463 	{".dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"},
464 	{".obd", "application/x-msbinder"},
465 	{".thmx", "application/vnd.ms-officetheme"},
466 	{".onetoc", "application/onenote"},
467 	{".pya", "audio/vnd.ms-playready.media.pya"},
468 	{".pyv", "video/vnd.ms-playready.media.pyv"},
469 	{".ppt", "application/vnd.ms-powerpoint"},
470 	{".ppam", "application/vnd.ms-powerpoint.addin.macroenabled.12"},
471 	{".sldm", "application/vnd.ms-powerpoint.slide.macroenabled.12"},
472 	{".pptm", "application/vnd.ms-powerpoint.presentation.macroenabled.12"},
473 	{".ppsm", "application/vnd.ms-powerpoint.slideshow.macroenabled.12"},
474 	{".potm", "application/vnd.ms-powerpoint.template.macroenabled.12"},
475 	{".mpp", "application/vnd.ms-project"},
476 	{".pub", "application/x-mspublisher"},
477 	{".scd", "application/x-msschedule"},
478 	{".xap", "application/x-silverlight-app"},
479 	{".stl", "application/vnd.ms-pki.stl"},
480 	{".cat", "application/vnd.ms-pki.seccat"},
481 	{".vsd", "application/vnd.visio"},
482 	{".vsdx", "application/vnd.visio2013"},
483 	{".wm", "video/x-ms-wm"},
484 	{".wma", "audio/x-ms-wma"},
485 	{".wax", "audio/x-ms-wax"},
486 	{".wmx", "video/x-ms-wmx"},
487 	{".wmd", "application/x-ms-wmd"},
488 	{".wpl", "application/vnd.ms-wpl"},
489 	{".wmz", "application/x-ms-wmz"},
490 	{".wmv", "video/x-ms-wmv"},
491 	{".wvx", "video/x-ms-wvx"},
492 	{".wmf", "application/x-msmetafile"},
493 	{".trm", "application/x-msterminal"},
494 	{".doc", "application/msword"},
495 	{".docm", "application/vnd.ms-word.document.macroenabled.12"},
496 	{".dotm", "application/vnd.ms-word.template.macroenabled.12"},
497 	{".wri", "application/x-mswrite"},
498 	{".wps", "application/vnd.ms-works"},
499 	{".xbap", "application/x-ms-xbap"},
500 	{".xps", "application/vnd.ms-xpsdocument"},
501 	{".mid", "audio/midi"},
502 	{".mpy", "application/vnd.ibm.minipay"},
503 	{".afp", "application/vnd.ibm.modcap"},
504 	{".rms", "application/vnd.jcp.javame.midlet-rms"},
505 	{".tmo", "application/vnd.tmobile-livetv"},
506 	{".prc", "application/x-mobipocket-ebook"},
507 	{".mbk", "application/vnd.mobius.mbk"},
508 	{".dis", "application/vnd.mobius.dis"},
509 	{".plc", "application/vnd.mobius.plc"},
510 	{".mqy", "application/vnd.mobius.mqy"},
511 	{".msl", "application/vnd.mobius.msl"},
512 	{".txf", "application/vnd.mobius.txf"},
513 	{".daf", "application/vnd.mobius.daf"},
514 	{".fly", "text/vnd.fly"},
515 	{".mpc", "application/vnd.mophun.certificate"},
516 	{".mpn", "application/vnd.mophun.application"},
517 	{".mj2", "video/mj2"},
518 	{".mpga", "audio/mpeg"},
519 	{".mxu", "video/vnd.mpegurl"},
520 	{".mpeg", "video/mpeg"},
521 	{".m21", "application/mp21"},
522 	{".mp4a", "audio/mp4"},
523 	{".mp4", "video/mp4"},
524 	{".mp4", "application/mp4"},
525 	{".m3u8", "application/vnd.apple.mpegurl"},
526 	{".mus", "application/vnd.musician"},
527 	{".msty", "application/vnd.muvee.style"},
528 	{".mxml", "application/xv+xml"},
529 	{".ngdat", "application/vnd.nokia.n-gage.data"},
530 	{".n-gage", "application/vnd.nokia.n-gage.symbian.install"},
531 	{".ncx", "application/x-dtbncx+xml"},
532 	{".nc", "application/x-netcdf"},
533 	{".nlu", "application/vnd.neurolanguage.nlu"},
534 	{".dna", "application/vnd.dna"},
535 	{".nnd", "application/vnd.noblenet-directory"},
536 	{".nns", "application/vnd.noblenet-sealer"},
537 	{".nnw", "application/vnd.noblenet-web"},
538 	{".rpst", "application/vnd.nokia.radio-preset"},
539 	{".rpss", "application/vnd.nokia.radio-presets"},
540 	{".n3", "text/n3"},
541 	{".edm", "application/vnd.novadigm.edm"},
542 	{".edx", "application/vnd.novadigm.edx"},
543 	{".ext", "application/vnd.novadigm.ext"},
544 	{".gph", "application/vnd.flographit"},
545 	{".ecelp4800", "audio/vnd.nuera.ecelp4800"},
546 	{".ecelp7470", "audio/vnd.nuera.ecelp7470"},
547 	{".ecelp9600", "audio/vnd.nuera.ecelp9600"},
548 	{".oda", "application/oda"},
549 	{".ogx", "application/ogg"},
550 	{".oga", "audio/ogg"},
551 	{".ogv", "video/ogg"},
552 	{".dd2", "application/vnd.oma.dd2+xml"},
553 	{".oth", "application/vnd.oasis.opendocument.text-web"},
554 	{".opf", "application/oebps-package+xml"},
555 	{".qbo", "application/vnd.intu.qbo"},
556 	{".oxt", "application/vnd.openofficeorg.extension"},
557 	{".osf", "application/vnd.yamaha.openscoreformat"},
558 	{".weba", "audio/webm"},
559 	{".webm", "video/webm"},
560 	{".odc", "application/vnd.oasis.opendocument.chart"},
561 	{".otc", "application/vnd.oasis.opendocument.chart-template"},
562 	{".odb", "application/vnd.oasis.opendocument.database"},
563 	{".odf", "application/vnd.oasis.opendocument.formula"},
564 	{".odft", "application/vnd.oasis.opendocument.formula-template"},
565 	{".odg", "application/vnd.oasis.opendocument.graphics"},
566 	{".otg", "application/vnd.oasis.opendocument.graphics-template"},
567 	{".odi", "application/vnd.oasis.opendocument.image"},
568 	{".oti", "application/vnd.oasis.opendocument.image-template"},
569 	{".odp", "application/vnd.oasis.opendocument.presentation"},
570 	{".otp", "application/vnd.oasis.opendocument.presentation-template"},
571 	{".ods", "application/vnd.oasis.opendocument.spreadsheet"},
572 	{".ots", "application/vnd.oasis.opendocument.spreadsheet-template"},
573 	{".odt", "application/vnd.oasis.opendocument.text"},
574 	{".odm", "application/vnd.oasis.opendocument.text-master"},
575 	{".ott", "application/vnd.oasis.opendocument.text-template"},
576 	{".ktx", "image/ktx"},
577 	{".sxc", "application/vnd.sun.xml.calc"},
578 	{".stc", "application/vnd.sun.xml.calc.template"},
579 	{".sxd", "application/vnd.sun.xml.draw"},
580 	{".std", "application/vnd.sun.xml.draw.template"},
581 	{".sxi", "application/vnd.sun.xml.impress"},
582 	{".sti", "application/vnd.sun.xml.impress.template"},
583 	{".sxm", "application/vnd.sun.xml.math"},
584 	{".sxw", "application/vnd.sun.xml.writer"},
585 	{".sxg", "application/vnd.sun.xml.writer.global"},
586 	{".stw", "application/vnd.sun.xml.writer.template"},
587 	{".otf", "application/x-font-otf"},
588 	{".osfpvg", "application/vnd.yamaha.openscoreformat.osfpvg+xml"},
589 	{".dp", "application/vnd.osgi.dp"},
590 	{".pdb", "application/vnd.palm"},
591 	{".p", "text/x-pascal"},
592 	{".paw", "application/vnd.pawaafile"},
593 	{".pclxl", "application/vnd.hp-pclxl"},
594 	{".efif", "application/vnd.picsel"},
595 	{".pcx", "image/x-pcx"},
596 	{".psd", "image/vnd.adobe.photoshop"},
597 	{".prf", "application/pics-rules"},
598 	{".pic", "image/x-pict"},
599 	{".chat", "application/x-chat"},
600 	{".p10", "application/pkcs10"},
601 	{".p12", "application/x-pkcs12"},
602 	{".p7m", "application/pkcs7-mime"},
603 	{".p7s", "application/pkcs7-signature"},
604 	{".p7r", "application/x-pkcs7-certreqresp"},
605 	{".p7b", "application/x-pkcs7-certificates"},
606 	{".p8", "application/pkcs8"},
607 	{".plf", "application/vnd.pocketlearn"},
608 	{".pnm", "image/x-portable-anymap"},
609 	{".pbm", "image/x-portable-bitmap"},
610 	{".pcf", "application/x-font-pcf"},
611 	{".pfr", "application/font-tdpfr"},
612 	{".pgn", "application/x-chess-pgn"},
613 	{".pgm", "image/x-portable-graymap"},
614 	{".png", "image/png"},
615 	{".png", "image/x-citrix-png"},
616 	{".png", "image/x-png"},
617 	{".ppm", "image/x-portable-pixmap"},
618 	{".pskcxml", "application/pskc+xml"},
619 	{".pml", "application/vnd.ctc-posml"},
620 	{".ai", "application/postscript"},
621 	{".pfa", "application/x-font-type1"},
622 	{".pbd", "application/vnd.powerbuilder6"},
623 	{".pgp", "application/pgp-encrypted"},
624 	{".pgp", "application/pgp-signature"},
625 	{".box", "application/vnd.previewsystems.box"},
626 	{".ptid", "application/vnd.pvi.ptid1"},
627 	{".pls", "application/pls+xml"},
628 	{".str", "application/vnd.pg.format"},
629 	{".ei6", "application/vnd.pg.osasli"},
630 	{".dsc", "text/prs.lines.tag"},
631 	{".psf", "application/x-font-linux-psf"},
632 	{".qps", "application/vnd.publishare-delta-tree"},
633 	{".wg", "application/vnd.pmi.widget"},
634 	{".qxd", "application/vnd.quark.quarkxpress"},
635 	{".esf", "application/vnd.epson.esf"},
636 	{".msf", "application/vnd.epson.msf"},
637 	{".ssf", "application/vnd.epson.ssf"},
638 	{".qam", "application/vnd.epson.quickanime"},
639 	{".qfx", "application/vnd.intu.qfx"},
640 	{".qt", "video/quicktime"},
641 	{".rar", "application/x-rar-compressed"},
642 	{".ram", "audio/x-pn-realaudio"},
643 	{".rmp", "audio/x-pn-realaudio-plugin"},
644 	{".rsd", "application/rsd+xml"},
645 	{".rm", "application/vnd.rn-realmedia"},
646 	{".bed", "application/vnd.realvnc.bed"},
647 	{".mxl", "application/vnd.recordare.musicxml"},
648 	{".musicxml", "application/vnd.recordare.musicxml+xml"},
649 	{".rnc", "application/relax-ng-compact-syntax"},
650 	{".rdz", "application/vnd.data-vision.rdz"},
651 	{".rdf", "application/rdf+xml"},
652 	{".rp9", "application/vnd.cloanto.rp9"},
653 	{".jisp", "application/vnd.jisp"},
654 	{".rtf", "application/rtf"},
655 	{".rtx", "text/richtext"},
656 	{".link66", "application/vnd.route66.link66+xml"},
657 	{".rss", "application/rss+xml"},
658 	{".shf", "application/shf+xml"},
659 	{".st", "application/vnd.sailingtracker.track"},
660 	{".svg", "image/svg+xml"},
661 	{".sus", "application/vnd.sus-calendar"},
662 	{".sru", "application/sru+xml"},
663 	{".setpay", "application/set-payment-initiation"},
664 	{".setreg", "application/set-registration-initiation"},
665 	{".sema", "application/vnd.sema"},
666 	{".semd", "application/vnd.semd"},
667 	{".semf", "application/vnd.semf"},
668 	{".see", "application/vnd.seemail"},
669 	{".snf", "application/x-font-snf"},
670 	{".spq", "application/scvp-vp-request"},
671 	{".spp", "application/scvp-vp-response"},
672 	{".scq", "application/scvp-cv-request"},
673 	{".scs", "application/scvp-cv-response"},
674 	{".sdp", "application/sdp"},
675 	{".etx", "text/x-setext"},
676 	{".movie", "video/x-sgi-movie"},
677 	{".ifm", "application/vnd.shana.informed.formdata"},
678 	{".itp", "application/vnd.shana.informed.formtemplate"},
679 	{".iif", "application/vnd.shana.informed.interchange"},
680 	{".ipk", "application/vnd.shana.informed.package"},
681 	{".tfi", "application/thraud+xml"},
682 	{".shar", "application/x-shar"},
683 	{".rgb", "image/x-rgb"},
684 	{".slt", "application/vnd.epson.salt"},
685 	{".aso", "application/vnd.accpac.simply.aso"},
686 	{".imp", "application/vnd.accpac.simply.imp"},
687 	{".twd", "application/vnd.simtech-mindmapper"},
688 	{".csp", "application/vnd.commonspace"},
689 	{".saf", "application/vnd.yamaha.smaf-audio"},
690 	{".mmf", "application/vnd.smaf"},
691 	{".spf", "application/vnd.yamaha.smaf-phrase"},
692 	{".teacher", "application/vnd.smart.teacher"},
693 	{".svd", "application/vnd.svd"},
694 	{".rq", "application/sparql-query"},
695 	{".srx", "application/sparql-results+xml"},
696 	{".gram", "application/srgs"},
697 	{".grxml", "application/srgs+xml"},
698 	{".ssml", "application/ssml+xml"},
699 	{".skp", "application/vnd.koan"},
700 	{".sgml", "text/sgml"},
701 	{".sdc", "application/vnd.stardivision.calc"},
702 	{".sda", "application/vnd.stardivision.draw"},
703 	{".sdd", "application/vnd.stardivision.impress"},
704 	{".smf", "application/vnd.stardivision.math"},
705 	{".sdw", "application/vnd.stardivision.writer"},
706 	{".sgl", "application/vnd.stardivision.writer-global"},
707 	{".sm", "application/vnd.stepmania.stepchart"},
708 	{".sit", "application/x-stuffit"},
709 	{".sitx", "application/x-stuffitx"},
710 	{".sdkm", "application/vnd.solent.sdkm+xml"},
711 	{".xo", "application/vnd.olpc-sugar"},
712 	{".au", "audio/basic"},
713 	{".wqd", "application/vnd.wqd"},
714 	{".sis", "application/vnd.symbian.install"},
715 	{".smi", "application/smil+xml"},
716 	{".xsm", "application/vnd.syncml+xml"},
717 	{".bdm", "application/vnd.syncml.dm+wbxml"},
718 	{".xdm", "application/vnd.syncml.dm+xml"},
719 	{".sv4cpio", "application/x-sv4cpio"},
720 	{".sv4crc", "application/x-sv4crc"},
721 	{".sbml", "application/sbml+xml"},
722 	{".tsv", "text/tab-separated-values"},
723 	{".tiff", "image/tiff"},
724 	{".tao", "application/vnd.tao.intent-module-archive"},
725 	{".tar", "application/x-tar"},
726 	{".tcl", "application/x-tcl"},
727 	{".tex", "application/x-tex"},
728 	{".tfm", "application/x-tex-tfm"},
729 	{".tei", "application/tei+xml"},
730 	{".txt", "text/plain; charset=utf-8"},
731 	{".md", "text/markdown; charset=utf-8"},
732 	{".dxp", "application/vnd.spotfire.dxp"},
733 	{".sfs", "application/vnd.spotfire.sfs"},
734 	{".tsd", "application/timestamped-data"},
735 	{".tpt", "application/vnd.trid.tpt"},
736 	{".mxs", "application/vnd.triscape.mxs"},
737 	{".t", "text/troff"},
738 	{".tra", "application/vnd.trueapp"},
739 	{".ttf", "application/x-font-ttf"},
740 	{".ttl", "text/turtle"},
741 	{".umj", "application/vnd.umajin"},
742 	{".uoml", "application/vnd.uoml+xml"},
743 	{".unityweb", "application/vnd.unity"},
744 	{".ufd", "application/vnd.ufdl"},
745 	{".uri", "text/uri-list"},
746 	{".utz", "application/vnd.uiq.theme"},
747 	{".ustar", "application/x-ustar"},
748 	{".uu", "text/x-uuencode"},
749 	{".vcs", "text/x-vcalendar"},
750 	{".vcf", "text/x-vcard"},
751 	{".vcd", "application/x-cdlink"},
752 	{".vsf", "application/vnd.vsf"},
753 	{".wrl", "model/vrml"},
754 	{".vcx", "application/vnd.vcx"},
755 	{".mts", "model/vnd.mts"},
756 	{".vtu", "model/vnd.vtu"},
757 	{".vis", "application/vnd.visionary"},
758 	{".viv", "video/vnd.vivo"},
759 	{".ccxml", "application/ccxml+xml"},
760 	{".vxml", "application/voicexml+xml"},
761 	{".src", "application/x-wais-source"},
762 	{".wbxml", "application/vnd.wap.wbxml"},
763 	{".wbmp", "image/vnd.wap.wbmp"},
764 	{".wav", "audio/x-wav"},
765 	{".davmount", "application/davmount+xml"},
766 	{".woff", "application/x-font-woff"},
767 	{".wspolicy", "application/wspolicy+xml"},
768 	{".webp", "image/webp"},
769 	{".wtb", "application/vnd.webturbo"},
770 	{".wgt", "application/widget"},
771 	{".hlp", "application/winhlp"},
772 	{".wml", "text/vnd.wap.wml"},
773 	{".wmls", "text/vnd.wap.wmlscript"},
774 	{".wmlsc", "application/vnd.wap.wmlscriptc"},
775 	{".wpd", "application/vnd.wordperfect"},
776 	{".stf", "application/vnd.wt.stf"},
777 	{".wsdl", "application/wsdl+xml"},
778 	{".xbm", "image/x-xbitmap"},
779 	{".xpm", "image/x-xpixmap"},
780 	{".xwd", "image/x-xwindowdump"},
781 	{".der", "application/x-x509-ca-cert"},
782 	{".fig", "application/x-xfig"},
783 	{".xhtml", "application/xhtml+xml"},
784 	{".xml", "application/xml"},
785 	{".xdf", "application/xcap-diff+xml"},
786 	{".xenc", "application/xenc+xml"},
787 	{".xer", "application/patch-ops-error+xml"},
788 	{".rl", "application/resource-lists+xml"},
789 	{".rs", "application/rls-services+xml"},
790 	{".rld", "application/resource-lists-diff+xml"},
791 	{".xslt", "application/xslt+xml"},
792 	{".xop", "application/xop+xml"},
793 	{".xpi", "application/x-xpinstall"},
794 	{".xspf", "application/xspf+xml"},
795 	{".xul", "application/vnd.mozilla.xul+xml"},
796 	{".xyz", "chemical/x-xyz"},
797 	{".yaml", "text/yaml"},
798 	{".yang", "application/yang"},
799 	{".yin", "application/yin+xml"},
800 	{".zir", "application/vnd.zul"},
801 	{".zip", "application/zip"},
802 	{".zmm", "application/vnd.handheld-entertainment+xml"},
803 	{".zaz", "application/vnd.zzazz.deck+xml"},
804 };
805 
806 // Get HTTP MIME type from filename
GetMimeTypeFromFileName(char * filename)807 char *GetMimeTypeFromFileName(char *filename)
808 {
809 	UINT i;
810 	UINT num = sizeof(http_mime_types) / sizeof(HTTP_MIME_TYPE);
811 	if (filename == NULL)
812 	{
813 		return NULL;
814 	}
815 
816 	for (i = 0;i < num;i++)
817 	{
818 		HTTP_MIME_TYPE *a = &http_mime_types[i];
819 
820 		if (EndWith(filename, a->Extension))
821 		{
822 			return a->MimeType;
823 		}
824 	}
825 
826 	return NULL;
827 }
828 
829 // Download and save intermediate certificates if necessary
DownloadAndSaveIntermediateCertificatesIfNecessary(X * x)830 bool DownloadAndSaveIntermediateCertificatesIfNecessary(X *x)
831 {
832 	LIST *o;
833 	bool ret = false;
834 	// Validate arguments
835 	if (x == NULL)
836 	{
837 		return false;
838 	}
839 
840 	if (x->root_cert)
841 	{
842 		return true;
843 	}
844 
845 	o = NewCertList(true);
846 
847 	ret = TryGetRootCertChain(o, x, true, NULL);
848 
849 	FreeCertList(o);
850 
851 	return ret;
852 }
853 
854 // Attempt to fetch the full chain of the specified cert
TryGetRootCertChain(LIST * o,X * x,bool auto_save,X ** found_root_x)855 bool TryGetRootCertChain(LIST *o, X *x, bool auto_save, X **found_root_x)
856 {
857 	bool ret = false;
858 	LIST *chain = NULL;
859 	LIST *current_chain_dir = NULL;
860 	// Validate arguments
861 	if (o == NULL || x == NULL)
862 	{
863 		return false;
864 	}
865 
866 	chain = NewCertList(false);
867 
868 	ret = TryGetParentCertFromCertList(o, x, chain);
869 
870 	if (ret)
871 	{
872 		UINT i;
873 		DIRLIST *dir;
874 		wchar_t dirname[MAX_SIZE];
875 		wchar_t exedir[MAX_SIZE];
876 
877 		GetDbDirW(exedir, sizeof(exedir));
878 		CombinePathW(dirname, sizeof(dirname), exedir, L"chain_certs");
879 		MakeDirExW(dirname);
880 
881 		if (auto_save)
882 		{
883 			// delete the current auto_save files
884 			dir = EnumDirW(dirname);
885 			if (dir != NULL)
886 			{
887 				for (i = 0;i < dir->NumFiles;i++)
888 				{
889 					DIRENT *e = dir->File[i];
890 
891 					if (e->Folder == false)
892 					{
893 						if (UniStartWith(e->FileNameW, AUTO_DOWNLOAD_CERTS_PREFIX))
894 						{
895 							wchar_t tmp[MAX_SIZE];
896 
897 							CombinePathW(tmp, sizeof(tmp), dirname, e->FileNameW);
898 
899 							FileDeleteW(tmp);
900 						}
901 					}
902 				}
903 
904 				FreeDir(dir);
905 			}
906 		}
907 
908 		current_chain_dir = NewCertList(false);
909 		AddAllChainCertsToCertList(current_chain_dir);
910 
911 		for (i = 0;i < LIST_NUM(chain);i++)
912 		{
913 			wchar_t tmp[MAX_SIZE];
914 			X *xx = LIST_DATA(chain, i);
915 
916 			GetAllNameFromName(tmp, sizeof(tmp), xx->subject_name);
917 
918 			Debug("depth = %u, subject = %S\n", i, tmp);
919 
920 			if (auto_save && CompareX(x, xx) == false && IsXInCertList(current_chain_dir, xx) == false)
921 			{
922 				wchar_t fn[MAX_PATH];
923 				char hex_a[128];
924 				wchar_t hex[128];
925 				UCHAR hash[SHA1_SIZE];
926 				wchar_t tmp[MAX_SIZE];
927 				BUF *b;
928 
929 				GetXDigest(xx, hash, true);
930 				BinToStr(hex_a, sizeof(hex_a), hash, SHA1_SIZE);
931 				StrToUni(hex, sizeof(hex), hex_a);
932 
933 				UniStrCpy(fn, sizeof(fn), AUTO_DOWNLOAD_CERTS_PREFIX);
934 				UniStrCat(fn, sizeof(fn), hex);
935 				UniStrCat(fn, sizeof(fn), L".cer");
936 
937 				CombinePathW(tmp, sizeof(tmp), dirname, fn);
938 
939 				b = XToBuf(xx, true);
940 
941 				DumpBufW(b, tmp);
942 
943 				FreeBuf(b);
944 			}
945 
946 			if (xx->root_cert)
947 			{
948 				if (found_root_x != NULL)
949 				{
950 					*found_root_x = CloneX(xx);
951 				}
952 			}
953 		}
954 	}
955 
956 	FreeCertList(chain);
957 
958 	FreeCertList(current_chain_dir);
959 
960 	return ret;
961 }
962 
963 // Try get the parent cert
TryGetParentCertFromCertList(LIST * o,X * x,LIST * found_chain)964 bool TryGetParentCertFromCertList(LIST *o, X *x, LIST *found_chain)
965 {
966 	bool ret = false;
967 	X *r;
968 	bool do_free = false;
969 	// Validate arguments
970 	if (o == NULL || x == NULL || found_chain == NULL)
971 	{
972 		return false;
973 	}
974 
975 	if (LIST_NUM(found_chain) >= FIND_CERT_CHAIN_MAX_DEPTH)
976 	{
977 		return false;
978 	}
979 
980 	Add(found_chain, CloneX(x));
981 
982 	if (x->root_cert)
983 	{
984 		return true;
985 	}
986 
987 	r = FindCertIssuerFromCertList(o, x);
988 
989 	if (r == NULL)
990 	{
991 		if (IsEmptyStr(x->issuer_url) == false)
992 		{
993 			r = DownloadCert(x->issuer_url);
994 
995 			if (CheckXEx(x, r, true, true) && CompareX(x, r) == false)
996 			{
997 				// found
998 				do_free = true;
999 			}
1000 			else
1001 			{
1002 				// invalid
1003 				FreeX(r);
1004 				r = NULL;
1005 			}
1006 		}
1007 	}
1008 
1009 	if (r != NULL)
1010 	{
1011 		ret = TryGetParentCertFromCertList(o, r, found_chain);
1012 	}
1013 
1014 	if (do_free)
1015 	{
1016 		FreeX(r);
1017 	}
1018 
1019 	return ret;
1020 }
1021 
1022 // Find the issuer of the cert from the cert list
FindCertIssuerFromCertList(LIST * o,X * x)1023 X *FindCertIssuerFromCertList(LIST *o, X *x)
1024 {
1025 	UINT i;
1026 	// Validate arguments
1027 	if (o == NULL || x == NULL)
1028 	{
1029 		return NULL;
1030 	}
1031 
1032 	if (x->root_cert)
1033 	{
1034 		return NULL;
1035 	}
1036 
1037 	for (i = 0;i < LIST_NUM(o);i++)
1038 	{
1039 		X *xx = LIST_DATA(o, i);
1040 
1041 		if (CheckXEx(x, xx, true, true))
1042 		{
1043 			if (CompareX(x, xx) == false)
1044 			{
1045 				return xx;
1046 			}
1047 		}
1048 	}
1049 
1050 	return NULL;
1051 }
1052 
1053 // Download a cert by using HTTP
DownloadCert(char * url)1054 X *DownloadCert(char *url)
1055 {
1056 	BUF *b;
1057 	URL_DATA url_data;
1058 	X *ret = NULL;
1059 	// Validate arguments
1060 	if (IsEmptyStr(url))
1061 	{
1062 		return NULL;
1063 	}
1064 
1065 	Debug("Trying to download a cert from %s ...\n", url);
1066 
1067 	if (ParseUrl(&url_data, url, false, NULL) == false)
1068 	{
1069 		Debug("Download failed.\n");
1070 		return NULL;
1071 	}
1072 
1073 	b = HttpRequestEx(&url_data, NULL, CERT_HTTP_DOWNLOAD_TIMEOUT, CERT_HTTP_DOWNLOAD_TIMEOUT,
1074 		NULL, false, NULL, NULL, NULL, NULL, NULL, CERT_HTTP_DOWNLOAD_MAXSIZE);
1075 
1076 	if (b == NULL)
1077 	{
1078 		Debug("Download failed.\n");
1079 		return NULL;
1080 	}
1081 
1082 	ret = BufToX(b, IsBase64(b));
1083 
1084 	FreeBuf(b);
1085 
1086 	Debug("Download ok.\n");
1087 	return ret;
1088 }
1089 
1090 // New cert list
NewCertList(bool load_root_and_chain)1091 LIST *NewCertList(bool load_root_and_chain)
1092 {
1093 	LIST *o;
1094 
1095 	o = NewList(NULL);
1096 
1097 	if (load_root_and_chain)
1098 	{
1099 		AddAllRootCertsToCertList(o);
1100 		AddAllChainCertsToCertList(o);
1101 	}
1102 
1103 	return o;
1104 }
1105 
1106 // Free cert list
FreeCertList(LIST * o)1107 void FreeCertList(LIST *o)
1108 {
1109 	UINT i;
1110 	// Validate arguments
1111 	if (o == NULL)
1112 	{
1113 		return;
1114 	}
1115 
1116 	for (i = 0;i < LIST_NUM(o);i++)
1117 	{
1118 		X *x = LIST_DATA(o, i);
1119 
1120 		FreeX(x);
1121 	}
1122 
1123 	ReleaseList(o);
1124 }
1125 
1126 // Check whether the cert is in the cert list
IsXInCertList(LIST * o,X * x)1127 bool IsXInCertList(LIST *o, X *x)
1128 {
1129 	UINT i;
1130 	// Validate arguments
1131 	if (o == NULL || x == NULL)
1132 	{
1133 		return false;
1134 	}
1135 
1136 	for (i = 0;i < LIST_NUM(o);i++)
1137 	{
1138 		X *xx = LIST_DATA(o, i);
1139 
1140 		if (CompareX(x, xx))
1141 		{
1142 			return true;
1143 		}
1144 	}
1145 
1146 	return false;
1147 }
1148 
1149 // Add a cert to the cert list
AddXToCertList(LIST * o,X * x)1150 void AddXToCertList(LIST *o, X *x)
1151 {
1152 	// Validate arguments
1153 	if (o == NULL || x == NULL)
1154 	{
1155 		return;
1156 	}
1157 
1158 	if (IsXInCertList(o, x))
1159 	{
1160 		return;
1161 	}
1162 
1163 	if (CheckXDateNow(x) == false)
1164 	{
1165 		return;
1166 	}
1167 
1168 	Add(o, CloneX(x));
1169 }
1170 
1171 // Add all chain certs to the cert list
AddAllChainCertsToCertList(LIST * o)1172 void AddAllChainCertsToCertList(LIST *o)
1173 {
1174 	wchar_t dirname[MAX_SIZE];
1175 	wchar_t exedir[MAX_SIZE];
1176 	DIRLIST *dir;
1177 	// Validate arguments
1178 	if (o == NULL)
1179 	{
1180 		return;
1181 	}
1182 
1183 	GetDbDirW(exedir, sizeof(exedir));
1184 
1185 	CombinePathW(dirname, sizeof(dirname), exedir, L"chain_certs");
1186 
1187 	MakeDirExW(dirname);
1188 
1189 	dir = EnumDirW(dirname);
1190 
1191 	if (dir != NULL)
1192 	{
1193 		UINT i;
1194 
1195 		for (i = 0;i < dir->NumFiles;i++)
1196 		{
1197 			DIRENT *e = dir->File[i];
1198 
1199 			if (e->Folder == false)
1200 			{
1201 				wchar_t tmp[MAX_SIZE];
1202 				X *x;
1203 
1204 				CombinePathW(tmp, sizeof(tmp), dirname, e->FileNameW);
1205 
1206 				x = FileToXW(tmp);
1207 
1208 				if (x != NULL)
1209 				{
1210 					AddXToCertList(o, x);
1211 
1212 					FreeX(x);
1213 				}
1214 			}
1215 		}
1216 
1217 		FreeDir(dir);
1218 	}
1219 }
1220 
1221 // Add all root certs to the cert list
AddAllRootCertsToCertList(LIST * o)1222 void AddAllRootCertsToCertList(LIST *o)
1223 {
1224 	BUF *buf;
1225 	PACK *p;
1226 	UINT num_ok = 0, num_error = 0;
1227 	// Validate arguments
1228 	if (o == NULL)
1229 	{
1230 		return;
1231 	}
1232 
1233 	buf = ReadDump(ROOT_CERTS_FILENAME);
1234 	if (buf == NULL)
1235 	{
1236 		return;
1237 	}
1238 
1239 	p = BufToPack(buf);
1240 
1241 	if (p != NULL)
1242 	{
1243 		UINT num = PackGetIndexCount(p, "cert");
1244 		UINT i;
1245 
1246 		for (i = 0;i < num;i++)
1247 		{
1248 			bool ok = false;
1249 			BUF *b = PackGetBufEx(p, "cert", i);
1250 
1251 			if (b != NULL)
1252 			{
1253 				X *x = BufToX(b, false);
1254 
1255 				if (x != NULL)
1256 				{
1257 					AddXToCertList(o, x);
1258 
1259 					ok = true;
1260 
1261 					FreeX(x);
1262 				}
1263 
1264 				FreeBuf(b);
1265 			}
1266 
1267 			if (ok)
1268 			{
1269 				num_ok++;
1270 			}
1271 			else
1272 			{
1273 				num_error++;
1274 			}
1275 		}
1276 
1277 		FreePack(p);
1278 	}
1279 
1280 	FreeBuf(buf);
1281 
1282 	Debug("AddAllRootCertsToCertList: ok=%u error=%u total_list_len=%u\n", num_ok, num_error, LIST_NUM(o));
1283 }
1284 
1285 // Convert the date of YYYYMMDD format to a number
ShortStrToDate64(char * str)1286 UINT64 ShortStrToDate64(char *str)
1287 {
1288 	UINT v;
1289 	SYSTEMTIME st;
1290 	// Validate arguments
1291 	if (str == NULL)
1292 	{
1293 		return 0;
1294 	}
1295 
1296 	v = ToInt(str);
1297 
1298 	Zero(&st, sizeof(st));
1299 
1300 	st.wYear = (v % 100000000) / 10000;
1301 	st.wMonth = (v % 10000) / 100;
1302 	st.wDay = v % 100;
1303 
1304 	return SystemToUINT64(&st);
1305 }
1306 
1307 // Handle the response that is returned from the server in the update client
UpdateClientThreadProcessResults(UPDATE_CLIENT * c,BUF * b)1308 void UpdateClientThreadProcessResults(UPDATE_CLIENT *c, BUF *b)
1309 {
1310 	bool exit = false;
1311 	// Validate arguments
1312 	if (c == NULL || b == NULL)
1313 	{
1314 		return;
1315 	}
1316 
1317 	SeekBufToBegin(b);
1318 
1319 	while (true)
1320 	{
1321 		char *line = CfgReadNextLine(b);
1322 		if (line == NULL)
1323 		{
1324 			break;
1325 		}
1326 
1327 		Trim(line);
1328 
1329 		if (StartWith(line, "#") == false && IsEmptyStr(line) == false)
1330 		{
1331 			TOKEN_LIST *t = ParseTokenWithNullStr(line, " \t");
1332 
1333 			if (t != NULL)
1334 			{
1335 				if (t->NumTokens >= 5)
1336 				{
1337 					if (StrCmpi(t->Token[0], c->FamilyName) == 0)
1338 					{
1339 						// Match
1340 						UINT64 date = ShortStrToDate64(t->Token[1]);
1341 						if (date != 0)
1342 						{
1343 							UINT build = ToInt(t->Token[2]);
1344 							if (build != 0)
1345 							{
1346 								if (build > c->MyBuild && build > c->LatestBuild && build > c->Setting.LatestIgnoreBuild)
1347 								{
1348 									c->Callback(c, build, date, t->Token[3], t->Token[4], &c->HaltFlag, c->Param);
1349 
1350 									c->LatestBuild = build;
1351 
1352 									exit = true;
1353 								}
1354 							}
1355 						}
1356 					}
1357 				}
1358 
1359 				FreeToken(t);
1360 			}
1361 		}
1362 
1363 		Free(line);
1364 
1365 		if (exit)
1366 		{
1367 			break;
1368 		}
1369 	}
1370 }
1371 
1372 // Update client main process
UpdateClientThreadMain(UPDATE_CLIENT * c)1373 void UpdateClientThreadMain(UPDATE_CLIENT *c)
1374 {
1375 	char url[MAX_SIZE];
1376 	char id[MAX_SIZE];
1377 	URL_DATA data;
1378 	BUF *cert_hash;
1379 	UINT ret = 0;
1380 	BUF *recv;
1381 	// Validate arguments
1382 	if (c == NULL)
1383 	{
1384 		return;
1385 	}
1386 
1387 	// Generate the URL
1388 	Format(url, sizeof(url), IsUseAlternativeHostname() ? UPDATE_SERVER_URL_CHINA : UPDATE_SERVER_URL_GLOBAL, c->FamilyName, c->SoftwareName, c->MyBuild, c->MyLanguage);
1389 
1390 	if (IsEmptyStr(c->ClientId) == false)
1391 	{
1392 		Format(id, sizeof(id), "&id=%s", c->ClientId);
1393 		StrCat(url, sizeof(url), id);
1394 	}
1395 
1396 	// Get a text file at this URL
1397 	if (ParseUrl(&data, url, false, NULL) == false)
1398 	{
1399 		return;
1400 	}
1401 
1402 	cert_hash = StrToBin(UPDATE_SERVER_CERT_HASH);
1403 
1404 	StrCpy(data.SniString, sizeof(data.SniString), DDNS_SNI_VER_STRING);
1405 
1406 	recv = HttpRequestEx3(&data, NULL, UPDATE_CONNECT_TIMEOUT, UPDATE_COMM_TIMEOUT, &ret, false, NULL, NULL,
1407 		NULL, ((cert_hash != NULL && (cert_hash->Size % SHA1_SIZE) == 0) ? cert_hash->Buf : NULL),
1408 		(cert_hash != NULL ? (cert_hash->Size / SHA1_SIZE) : 0),
1409 		(bool *)&c->HaltFlag, 0, NULL, NULL);
1410 
1411 	FreeBuf(cert_hash);
1412 
1413 	if (recv != NULL)
1414 	{
1415 		UpdateClientThreadProcessResults(c, recv);
1416 
1417 		FreeBuf(recv);
1418 	}
1419 }
1420 
1421 // Update client main thread
UpdateClientThreadProc(THREAD * thread,void * param)1422 void UpdateClientThreadProc(THREAD *thread, void *param)
1423 {
1424 	UPDATE_CLIENT *c = (UPDATE_CLIENT *)param;
1425 	bool first_loop = true;
1426 	// Validate arguments
1427 	if (thread == NULL || param == NULL)
1428 	{
1429 		return;
1430 	}
1431 
1432 	while (true)
1433 	{
1434 		// Termination check
1435 		if (c->HaltFlag)
1436 		{
1437 			break;
1438 		}
1439 
1440 		if (first_loop == false)
1441 		{
1442 			// Wait for the foreground
1443 			if (c->IsForegroundCb != NULL)
1444 			{
1445 				while (true)
1446 				{
1447 					if (c->HaltFlag)
1448 					{
1449 						break;
1450 					}
1451 
1452 					if (c->IsForegroundCb(c, c->Param))
1453 					{
1454 						break;
1455 					}
1456 
1457 					Wait(c->HaltEvent, 1000);
1458 				}
1459 			}
1460 		}
1461 
1462 		first_loop = false;
1463 
1464 		if (c->HaltFlag)
1465 		{
1466 			break;
1467 		}
1468 
1469 		if (c->Setting.DisableCheck == false)
1470 		{
1471 			UpdateClientThreadMain(c);
1472 		}
1473 
1474 		// Wait until the next attempt
1475 		Wait(c->HaltEvent, GenRandInterval(UPDATE_CHECK_INTERVAL_MIN, UPDATE_CHECK_INTERVAL_MAX));
1476 	}
1477 }
1478 
1479 // Update the configuration of the update client
SetUpdateClientSetting(UPDATE_CLIENT * c,UPDATE_CLIENT_SETTING * s)1480 void SetUpdateClientSetting(UPDATE_CLIENT *c, UPDATE_CLIENT_SETTING *s)
1481 {
1482 	bool old_disable;
1483 	// Validate arguments
1484 	if (c == NULL || s == NULL)
1485 	{
1486 		return;
1487 	}
1488 
1489 	old_disable = c->Setting.DisableCheck;
1490 
1491 	Copy(&c->Setting, s, sizeof(UPDATE_CLIENT_SETTING));
1492 
1493 	Set(c->HaltEvent);
1494 }
1495 
1496 // Start the update client
NewUpdateClient(UPDATE_NOTIFY_PROC * cb,UPDATE_ISFOREGROUND_PROC * isforeground_cb,void * param,char * family_name,char * software_name,wchar_t * software_title,UINT my_build,UINT64 my_date,char * my_lang,UPDATE_CLIENT_SETTING * current_setting,char * client_id)1497 UPDATE_CLIENT *NewUpdateClient(UPDATE_NOTIFY_PROC *cb, UPDATE_ISFOREGROUND_PROC *isforeground_cb, void *param, char *family_name, char *software_name, wchar_t *software_title, UINT my_build, UINT64 my_date, char *my_lang, UPDATE_CLIENT_SETTING *current_setting, char *client_id)
1498 {
1499 	UPDATE_CLIENT *c;
1500 	// Validate arguments
1501 	if (family_name == NULL || software_title == NULL || software_name == NULL || my_build == 0 ||
1502 		my_lang == NULL || current_setting == NULL || cb == NULL)
1503 	{
1504 		return NULL;
1505 	}
1506 
1507 	c = ZeroMalloc(sizeof(UPDATE_CLIENT));
1508 
1509 	c->Callback = cb;
1510 	c->IsForegroundCb = isforeground_cb;
1511 
1512 	StrCpy(c->ClientId, sizeof(c->ClientId), client_id);
1513 	StrCpy(c->FamilyName, sizeof(c->FamilyName), family_name);
1514 	StrCpy(c->SoftwareName, sizeof(c->SoftwareName), software_name);
1515 	UniStrCpy(c->SoftwareTitle, sizeof(c->SoftwareTitle), software_title);
1516 	c->MyBuild = my_build;
1517 	c->MyDate = my_date;
1518 	StrCpy(c->MyLanguage, sizeof(c->MyLanguage), my_lang);
1519 
1520 	Copy(&c->Setting, current_setting, sizeof(c->Setting));
1521 
1522 	c->Param = param;
1523 
1524 	c->HaltEvent = NewEvent();
1525 
1526 	// Create a thread
1527 	c->Thread = NewThread(UpdateClientThreadProc, c);
1528 
1529 	return c;
1530 }
1531 
1532 // Terminate the update client
FreeUpdateClient(UPDATE_CLIENT * c)1533 void FreeUpdateClient(UPDATE_CLIENT *c)
1534 {
1535 	// Validate arguments
1536 	if (c == NULL)
1537 	{
1538 		return;
1539 	}
1540 
1541 	// Thread stop
1542 	c->HaltFlag = true;
1543 	Set(c->HaltEvent);
1544 
1545 	// Wait for thread termination
1546 	WaitThread(c->Thread, INFINITE);
1547 
1548 	ReleaseThread(c->Thread);
1549 	ReleaseEvent(c->HaltEvent);
1550 
1551 	Free(c);
1552 }
1553 
1554 // Generate unique IDs for each machine
GenerateMachineUniqueHash(void * data)1555 void GenerateMachineUniqueHash(void *data)
1556 {
1557 	BUF *b;
1558 	char name[64];
1559 	OS_INFO *osinfo;
1560 	UINT64 iphash = 0;
1561 	// Validate arguments
1562 	if (data == NULL)
1563 	{
1564 		return;
1565 	}
1566 
1567 	iphash = GetHostIPAddressListHash();
1568 
1569 	b = NewBuf();
1570 	GetMachineName(name, sizeof(name));
1571 
1572 	osinfo = GetOsInfo();
1573 
1574 	WriteBuf(b, name, StrLen(name));
1575 
1576 	WriteBufInt64(b, iphash);
1577 
1578 	WriteBuf(b, &osinfo->OsType, sizeof(osinfo->OsType));
1579 	WriteBuf(b, osinfo->KernelName, StrLen(osinfo->KernelName));
1580 	WriteBuf(b, osinfo->KernelVersion, StrLen(osinfo->KernelVersion));
1581 	WriteBuf(b, osinfo->OsProductName, StrLen(osinfo->OsProductName));
1582 	WriteBuf(b, &osinfo->OsServicePack, sizeof(osinfo->OsServicePack));
1583 	WriteBuf(b, osinfo->OsSystemName, StrLen(osinfo->OsSystemName));
1584 	WriteBuf(b, osinfo->OsVendorName, StrLen(osinfo->OsVendorName));
1585 	WriteBuf(b, osinfo->OsVersion, StrLen(osinfo->OsVersion));
1586 
1587 	Hash(data, b->Buf, b->Size, true);
1588 
1589 	FreeBuf(b);
1590 }
1591 
1592 // Convert a node information to a string
NodeInfoToStr(wchar_t * str,UINT size,NODE_INFO * info)1593 void NodeInfoToStr(wchar_t *str, UINT size, NODE_INFO *info)
1594 {
1595 	char client_ip[128], server_ip[128], proxy_ip[128], unique_id[128];
1596 	// Validate arguments
1597 	if (str == NULL || info == NULL)
1598 	{
1599 		return;
1600 	}
1601 
1602 	IPToStr4or6(client_ip, sizeof(client_ip), info->ClientIpAddress, info->ClientIpAddress6);
1603 	IPToStr4or6(server_ip, sizeof(server_ip), info->ServerIpAddress, info->ServerIpAddress6);
1604 	IPToStr4or6(proxy_ip, sizeof(proxy_ip), info->ProxyIpAddress, info->ProxyIpAddress6);
1605 	BinToStr(unique_id, sizeof(unique_id), info->UniqueId, sizeof(info->UniqueId));
1606 
1607 	UniFormat(str, size, _UU("LS_NODE_INFO_TAG"), info->ClientProductName,
1608 		Endian32(info->ClientProductVer), Endian32(info->ClientProductBuild),
1609 		info->ServerProductName, Endian32(info->ServerProductVer), Endian32(info->ServerProductBuild),
1610 		info->ClientOsName, info->ClientOsVer, info->ClientOsProductId,
1611 		info->ClientHostname, client_ip, Endian32(info->ClientPort),
1612 		info->ServerHostname, server_ip, Endian32(info->ServerPort),
1613 		info->ProxyHostname, proxy_ip, Endian32(info->ProxyPort),
1614 		info->HubName, unique_id);
1615 }
1616 
1617 // Comparison of node information
CompareNodeInfo(NODE_INFO * a,NODE_INFO * b)1618 bool CompareNodeInfo(NODE_INFO *a, NODE_INFO *b)
1619 {
1620 	// Validate arguments
1621 	if (a == NULL || b == NULL)
1622 	{
1623 		return false;
1624 	}
1625 
1626 	if (StrCmp(a->ClientProductName, b->ClientProductName) != 0)
1627 	{
1628 		return false;
1629 	}
1630 	if (a->ClientProductVer != b->ClientProductVer)
1631 	{
1632 		return false;
1633 	}
1634 	if (a->ClientProductBuild != b->ClientProductBuild)
1635 	{
1636 		return false;
1637 	}
1638 	if (StrCmp(a->ServerProductName, b->ServerProductName) != 0)
1639 	{
1640 		return false;
1641 	}
1642 	if (a->ServerProductVer != b->ServerProductVer)
1643 	{
1644 		return false;
1645 	}
1646 	if (a->ServerProductBuild != b->ServerProductBuild)
1647 	{
1648 		return false;
1649 	}
1650 	if (StrCmp(a->ClientOsName, b->ClientOsName) != 0)
1651 	{
1652 		return false;
1653 	}
1654 	if (StrCmp(a->ClientOsVer, b->ClientOsVer) != 0)
1655 	{
1656 		return false;
1657 	}
1658 	if (StrCmp(a->ClientOsProductId, b->ClientOsProductId) != 0)
1659 	{
1660 		return false;
1661 	}
1662 	if (StrCmp(a->ClientHostname, b->ClientHostname) != 0)
1663 	{
1664 		return false;
1665 	}
1666 	if (a->ClientIpAddress != b->ClientIpAddress)
1667 	{
1668 		return false;
1669 	}
1670 	if (StrCmp(a->ServerHostname, b->ServerHostname) != 0)
1671 	{
1672 		return false;
1673 	}
1674 	if (a->ServerIpAddress != b->ServerIpAddress)
1675 	{
1676 		return false;
1677 	}
1678 	if (a->ServerPort != b->ServerPort)
1679 	{
1680 		return false;
1681 	}
1682 	if (StrCmp(a->ProxyHostname, b->ProxyHostname) != 0)
1683 	{
1684 		return false;
1685 	}
1686 	if (a->ProxyIpAddress != b->ProxyIpAddress)
1687 	{
1688 		return false;
1689 	}
1690 	if (a->ProxyPort != b->ProxyPort)
1691 	{
1692 		return false;
1693 	}
1694 	if (StrCmp(a->HubName, b->HubName) != 0)
1695 	{
1696 		return false;
1697 	}
1698 	if (Cmp(a->UniqueId, b->UniqueId, 16) != 0)
1699 	{
1700 		return false;
1701 	}
1702 
1703 	return true;
1704 }
1705 
1706 // Accept the password change
ChangePasswordAccept(CONNECTION * c,PACK * p)1707 UINT ChangePasswordAccept(CONNECTION *c, PACK *p)
1708 {
1709 	CEDAR *cedar;
1710 	UCHAR random[SHA1_SIZE];
1711 	char hubname[MAX_HUBNAME_LEN + 1];
1712 	char username[MAX_USERNAME_LEN + 1];
1713 	UCHAR secure_old_password[SHA1_SIZE];
1714 	UCHAR new_password[SHA1_SIZE];
1715 	UCHAR new_password_ntlm[SHA1_SIZE];
1716 	UCHAR check_secure_old_password[SHA1_SIZE];
1717 	UINT ret = ERR_NO_ERROR;
1718 	HUB *hub;
1719 	bool save = false;
1720 	// Validate arguments
1721 	if (c == NULL || p == NULL)
1722 	{
1723 		return ERR_INTERNAL_ERROR;
1724 	}
1725 
1726 	Copy(random, c->Random, SHA1_SIZE);
1727 	if (PackGetStr(p, "hubname", hubname, sizeof(hubname)) == false ||
1728 		PackGetStr(p, "username", username, sizeof(username)) == false ||
1729 		PackGetData2(p, "secure_old_password", secure_old_password, sizeof(secure_old_password)) == false ||
1730 		PackGetData2(p, "new_password", new_password, sizeof(new_password)) == false)
1731 	{
1732 		return ERR_PROTOCOL_ERROR;
1733 	}
1734 
1735 	if (PackGetData2(p, "new_password_ntlm", new_password_ntlm, MD5_SIZE) == false)
1736 	{
1737 		Zero(new_password_ntlm, sizeof(new_password_ntlm));
1738 	}
1739 
1740 	cedar = c->Cedar;
1741 
1742 	LockHubList(cedar);
1743 	{
1744 		hub = GetHub(cedar, hubname);
1745 	}
1746 	UnlockHubList(cedar);
1747 
1748 	if (hub == NULL)
1749 	{
1750 		ret = ERR_HUB_NOT_FOUND;
1751 	}
1752 	else
1753 	{
1754 		char tmp[MAX_SIZE];
1755 
1756 		if (GetHubAdminOption(hub, "deny_change_user_password") != 0)
1757 		{
1758 			ReleaseHub(hub);
1759 			return ERR_NOT_ENOUGH_RIGHT;
1760 		}
1761 
1762 		IPToStr(tmp, sizeof(tmp), &c->FirstSock->RemoteIP);
1763 		HLog(hub, "LH_CHANGE_PASSWORD_1", c->Name, tmp);
1764 
1765 		AcLock(hub);
1766 		{
1767 			USER *u = AcGetUser(hub, username);
1768 			if (u == NULL)
1769 			{
1770 				HLog(hub, "LH_CHANGE_PASSWORD_2", c->Name, username);
1771 				ret = ERR_OLD_PASSWORD_WRONG;
1772 			}
1773 			else
1774 			{
1775 				Lock(u->lock);
1776 				{
1777 					if (u->AuthType	!= AUTHTYPE_PASSWORD)
1778 					{
1779 						// Not a password authentication
1780 						HLog(hub, "LH_CHANGE_PASSWORD_3", c->Name, username);
1781 						ret = ERR_USER_AUTHTYPE_NOT_PASSWORD;
1782 					}
1783 					else
1784 					{
1785 						bool fix_password = false;
1786 						if (u->Policy != NULL)
1787 						{
1788 							fix_password = u->Policy->FixPassword;
1789 						}
1790 						else
1791 						{
1792 							if (u->Group != NULL)
1793 							{
1794 								if (u->Group->Policy != NULL)
1795 								{
1796 									fix_password = u->Group->Policy->FixPassword;
1797 								}
1798 							}
1799 						}
1800 						if (fix_password == false)
1801 						{
1802 							// Confirmation of the old password
1803 							AUTHPASSWORD *pw = (AUTHPASSWORD *)u->AuthData;
1804 
1805 							SecurePassword(check_secure_old_password, pw->HashedKey, random);
1806 							if (Cmp(check_secure_old_password, secure_old_password, SHA1_SIZE) != 0)
1807 							{
1808 								// Old password is incorrect
1809 								ret = ERR_OLD_PASSWORD_WRONG;
1810 								HLog(hub, "LH_CHANGE_PASSWORD_4", c->Name, username);
1811 							}
1812 							else
1813 							{
1814 								// Write a new password
1815 								if (Cmp(pw->HashedKey, new_password, SHA1_SIZE) != 0 || IsZero(pw->NtLmSecureHash, MD5_SIZE))
1816 								{
1817 									Copy(pw->HashedKey, new_password, SHA1_SIZE);
1818 									Copy(pw->NtLmSecureHash, new_password_ntlm, MD5_SIZE);
1819 								}
1820 								HLog(hub, "LH_CHANGE_PASSWORD_5", c->Name, username);
1821 								save = true;
1822 							}
1823 						}
1824 						else
1825 						{
1826 							// Password change is prohibited
1827 							ret = ERR_NOT_ENOUGH_RIGHT;
1828 						}
1829 					}
1830 				}
1831 				Unlock(u->lock);
1832 
1833 				ReleaseUser(u);
1834 			}
1835 		}
1836 		AcUnlock(hub);
1837 		ReleaseHub(hub);
1838 	}
1839 
1840 	return ret;
1841 }
1842 
1843 // Change the password
ChangePassword(CEDAR * cedar,CLIENT_OPTION * o,char * hubname,char * username,char * old_pass,char * new_pass)1844 UINT ChangePassword(CEDAR *cedar, CLIENT_OPTION *o, char *hubname, char *username, char *old_pass, char *new_pass)
1845 {
1846 	UINT ret = ERR_NO_ERROR;
1847 	UCHAR old_password[SHA1_SIZE];
1848 	UCHAR secure_old_password[SHA1_SIZE];
1849 	UCHAR new_password[SHA1_SIZE];
1850 	UCHAR new_password_ntlm[MD5_SIZE];
1851 	SOCK *sock;
1852 	SESSION *s;
1853 	// Validate arguments
1854 	if (cedar == NULL || o == NULL || hubname == NULL || username == NULL || old_pass == NULL || new_pass == NULL)
1855 	{
1856 		return ERR_INTERNAL_ERROR;
1857 	}
1858 
1859 
1860 	// Create a session
1861 	s = NewRpcSessionEx(cedar, o, &ret, NULL);
1862 
1863 	if (s != NULL)
1864 	{
1865 		PACK *p = NewPack();
1866 
1867 		sock = s->Connection->FirstSock;
1868 
1869 		HashPassword(old_password, username, old_pass);
1870 		SecurePassword(secure_old_password, old_password, s->Connection->Random);
1871 		HashPassword(new_password, username, new_pass);
1872 		GenerateNtPasswordHash(new_password_ntlm, new_pass);
1873 
1874 		PackAddClientVersion(p, s->Connection);
1875 
1876 		PackAddStr(p, "method", "password");
1877 		PackAddStr(p, "hubname", hubname);
1878 		PackAddStr(p, "username", username);
1879 		PackAddData(p, "secure_old_password", secure_old_password, SHA1_SIZE);
1880 		PackAddData(p, "new_password", new_password, SHA1_SIZE);
1881 		PackAddData(p, "new_password_ntlm", new_password_ntlm, MD5_SIZE);
1882 
1883 		if (HttpClientSend(sock, p))
1884 		{
1885 			PACK *p = HttpClientRecv(sock);
1886 			if (p == NULL)
1887 			{
1888 				ret = ERR_DISCONNECTED;
1889 			}
1890 			else
1891 			{
1892 				ret = GetErrorFromPack(p);
1893 			}
1894 			FreePack(p);
1895 		}
1896 		else
1897 		{
1898 			ret = ERR_DISCONNECTED;
1899 		}
1900 		FreePack(p);
1901 
1902 		ReleaseSession(s);
1903 	}
1904 
1905 	return ret;
1906 }
1907 
1908 // Enumerate HUBs
EnumHub(SESSION * s)1909 TOKEN_LIST *EnumHub(SESSION *s)
1910 {
1911 	SOCK *sock;
1912 	TOKEN_LIST *ret;
1913 	PACK *p;
1914 	UINT num;
1915 	UINT i;
1916 	// Validate arguments
1917 	if (s == NULL || s->Connection == NULL)
1918 	{
1919 		return NULL;
1920 	}
1921 
1922 	sock = s->Connection->FirstSock;
1923 	if (sock == NULL)
1924 	{
1925 		return NULL;
1926 	}
1927 
1928 	// Set the Timeout
1929 	SetTimeout(sock, 10000);
1930 
1931 	p = NewPack();
1932 	PackAddStr(p, "method", "enum_hub");
1933 
1934 	PackAddClientVersion(p, s->Connection);
1935 
1936 	if (HttpClientSend(sock, p) == false)
1937 	{
1938 		FreePack(p);
1939 		return NULL;
1940 	}
1941 	FreePack(p);
1942 
1943 	p = HttpClientRecv(sock);
1944 	if (p == NULL)
1945 	{
1946 		return NULL;
1947 	}
1948 
1949 	num = PackGetInt(p, "NumHub");
1950 	ret = ZeroMalloc(sizeof(TOKEN_LIST));
1951 	ret->NumTokens = num;
1952 	ret->Token = ZeroMalloc(sizeof(char *) * num);
1953 	for (i = 0;i < num;i++)
1954 	{
1955 		char tmp[MAX_SIZE];
1956 		if (PackGetStrEx(p, "HubName", tmp, sizeof(tmp), i))
1957 		{
1958 			ret->Token[i] = CopyStr(tmp);
1959 		}
1960 	}
1961 	FreePack(p);
1962 
1963 	return ret;
1964 }
1965 
1966 // Server accepts a connection from client
ServerAccept(CONNECTION * c)1967 bool ServerAccept(CONNECTION *c)
1968 {
1969 	bool ret = false;
1970 	UINT err;
1971 	PACK *p;
1972 	char username_real[MAX_SIZE];
1973 	char method[MAX_SIZE];
1974 	char hubname[MAX_SIZE];
1975 	char username[MAX_SIZE];
1976 	char groupname[MAX_SIZE];
1977 	UCHAR session_key[SHA1_SIZE];
1978 	UCHAR ticket[SHA1_SIZE];
1979 	RC4_KEY_PAIR key_pair;
1980 	UINT authtype;
1981 	POLICY *policy;
1982 	UINT assigned_vlan_id = 0;
1983 	UCHAR assigned_ipc_mac_address[6];
1984 	HUB *hub;
1985 	SESSION *s = NULL;
1986 	UINT64 user_expires = 0;
1987 	bool use_encrypt;
1988 	bool use_compress;
1989 	bool half_connection;
1990 	UINT adjust_mss;
1991 	bool use_udp_acceleration_client;
1992 	UINT client_udp_acceleration_max_version = 1;
1993 	UINT udp_acceleration_version = 1;
1994 	UINT client_rudp_bulk_max_version = 1;
1995 	UINT rudp_bulk_version = 1;
1996 	bool support_hmac_on_udp_acceleration_client = false;
1997 	bool support_udp_accel_fast_disconnect_detect;
1998 	bool use_hmac_on_udp_acceleration = false;
1999 	bool supress_return_pack_error = false;
2000 	IP udp_acceleration_client_ip;
2001 	UCHAR udp_acceleration_client_key[UDP_ACCELERATION_COMMON_KEY_SIZE_V1];
2002 	UCHAR udp_acceleration_client_key_v2[UDP_ACCELERATION_COMMON_KEY_SIZE_V2];
2003 	UINT udp_acceleration_client_port;
2004 	bool use_fast_rc4;
2005 	bool admin_mode = false;
2006 	UINT direction;
2007 	UINT max_connection;
2008 	UINT timeout;
2009 	bool no_reconnect_to_session = false;
2010 	bool farm_controller = false;
2011 	bool farm_member = false;
2012 	bool farm_mode = false;
2013 	bool require_bridge_routing_mode;
2014 	bool require_monitor_mode;
2015 	bool support_bulk_on_rudp = false;
2016 	bool support_hmac_on_bulk_of_rudp = false;
2017 	bool support_udp_recovery = false;
2018 	bool enable_bulk_on_rudp = false;
2019 	bool enable_udp_recovery = false;
2020 	bool enable_hmac_on_bulk_of_rudp = false;
2021 	bool use_client_license = false, use_bridge_license = false;
2022 	bool local_host_session = false;
2023 	char sessionname[MAX_SESSION_NAME_LEN + 1];
2024 	bool is_server_or_bridge = false;
2025 	bool qos = false;
2026 	bool cluster_dynamic_secure_nat = false;
2027 	bool no_save_password = false;
2028 	NODE_INFO node;
2029 	wchar_t *msg = NULL;
2030 	bool suppress_client_update_notification = false;
2031 	USER *loggedin_user_object = NULL;
2032 	FARM_MEMBER *f = NULL;
2033 	SERVER *server = NULL;
2034 	POLICY ticketed_policy;
2035 	UCHAR unique[SHA1_SIZE], unique2[SHA1_SIZE];
2036 	CEDAR *cedar;
2037 	RPC_WINVER winver;
2038 	UINT client_id;
2039 	bool no_more_users_in_server = false;
2040 	UCHAR mschap_v2_server_response_20[20];
2041 	UINT ms_chap_error = 0;
2042 	bool is_empty_password = false;
2043 	char *error_detail = NULL;
2044 	char *error_detail_2 = NULL;
2045 	char ctoken_hash_str[64];
2046 	EAP_CLIENT *release_me_eap_client = NULL;
2047 
2048 	// Validate arguments
2049 	if (c == NULL)
2050 	{
2051 		return false;
2052 	}
2053 
2054 	GenerateMachineUniqueHash(unique2);
2055 
2056 	Zero(ctoken_hash_str, sizeof(ctoken_hash_str));
2057 
2058 	Zero(assigned_ipc_mac_address, sizeof(assigned_ipc_mac_address));
2059 
2060 	Zero(mschap_v2_server_response_20, sizeof(mschap_v2_server_response_20));
2061 
2062 	Zero(&udp_acceleration_client_ip, sizeof(udp_acceleration_client_ip));
2063 	udp_acceleration_client_port = 0;
2064 	Zero(udp_acceleration_client_key, sizeof(udp_acceleration_client_key));
2065 	Zero(udp_acceleration_client_key_v2, sizeof(udp_acceleration_client_key_v2));
2066 
2067 	Zero(&winver, sizeof(winver));
2068 
2069 	StrCpy(groupname, sizeof(groupname), "");
2070 	StrCpy(sessionname, sizeof(sessionname), "");
2071 
2072 	if (IsZero(c->CToken_Hash, SHA1_SIZE) == false)
2073 	{
2074 		BinToStr(ctoken_hash_str, sizeof(ctoken_hash_str), c->CToken_Hash, SHA1_SIZE);
2075 	}
2076 
2077 	cedar = c->Cedar;
2078 
2079 	// Get the license status
2080 
2081 	no_more_users_in_server = SiTooManyUserObjectsInServer(cedar->Server, true);
2082 
2083 	c->Status = CONNECTION_STATUS_NEGOTIATION;
2084 
2085 	if (c->Cedar->Server != NULL)
2086 	{
2087 		SERVER *s = c->Cedar->Server;
2088 		server = s;
2089 
2090 		if (s->ServerType == SERVER_TYPE_FARM_MEMBER)
2091 		{
2092 			farm_member = true;
2093 			farm_mode = true;
2094 		}
2095 
2096 		if (s->ServerType == SERVER_TYPE_FARM_CONTROLLER)
2097 		{
2098 			farm_controller = true;
2099 			farm_mode = true;
2100 		}
2101 	}
2102 
2103 	// Receive the signature
2104 	Debug("Downloading Signature...\n");
2105 	error_detail_2 = NULL;
2106 	if (ServerDownloadSignature(c, &error_detail_2) == false)
2107 	{
2108 		if (c->Type == CONNECTION_TYPE_ADMIN_RPC)
2109 		{
2110 			c->Err = ERR_NO_ERROR;
2111 		}
2112 
2113 		if (error_detail_2 == NULL)
2114 		{
2115 			error_detail = "ServerDownloadSignature";
2116 		}
2117 		else
2118 		{
2119 			error_detail = error_detail_2;
2120 		}
2121 
2122 		supress_return_pack_error = true;
2123 
2124 		goto CLEANUP;
2125 	}
2126 
2127 	// Send a Hello packet
2128 	Debug("Uploading Hello...\n");
2129 	if (ServerUploadHello(c) == false)
2130 	{
2131 		error_detail = "ServerUploadHello";
2132 		goto CLEANUP;
2133 	}
2134 
2135 	// Receive the authentication data
2136 	Debug("Auth...\n");
2137 
2138 	p = HttpServerRecv(c->FirstSock);
2139 	if (p == NULL)
2140 	{
2141 		// The connection disconnected
2142 		c->Err = ERR_DISCONNECTED;
2143 		error_detail = "RecvAuth1";
2144 		goto CLEANUP;
2145 	}
2146 
2147 	if (err = GetErrorFromPack(p))
2148 	{
2149 		// An error has occured
2150 		FreePack(p);
2151 		c->Err = err;
2152 		error_detail = "RecvAuth2";
2153 		goto CLEANUP;
2154 	}
2155 
2156 	// Get the method
2157 	if (GetMethodFromPack(p, method, sizeof(method)) == false)
2158 	{
2159 		// Protocol error
2160 		FreePack(p);
2161 		c->Err = ERR_PROTOCOL_ERROR;
2162 		error_detail = "GetMethodFromPack";
2163 		goto CLEANUP;
2164 	}
2165 
2166 	// Brand string for the connection limit
2167 	{
2168 		char tmp[20];
2169 		char *branded_ctos = _SS("BRANDED_C_TO_S");
2170 		PackGetStr(p, "branded_ctos", tmp, sizeof(tmp));
2171 
2172 		if(StrCmpi(method, "login") == 0 && StrLen(branded_ctos) > 0 && StrCmpi(branded_ctos, tmp) != 0)
2173 		{
2174 			FreePack(p);
2175 			c->Err = ERR_BRANDED_C_TO_S;
2176 			goto CLEANUP;
2177 		}
2178 	}
2179 
2180 	// Get the client version
2181 	PackGetStr(p, "client_str", c->ClientStr, sizeof(c->ClientStr));
2182 	c->ClientVer = PackGetInt(p, "client_ver");
2183 	c->ClientBuild = PackGetInt(p, "client_build");
2184 
2185 	if (SearchStrEx(c->ClientStr, "server", 0, false) != INFINITE ||
2186 		SearchStrEx(c->ClientStr, "bridge", 0, false) != INFINITE)
2187 	{
2188 		is_server_or_bridge = true;
2189 	}
2190 
2191 	// Get the client Windows version
2192 	InRpcWinVer(&winver, p);
2193 
2194 	DecrementNoSsl(c->Cedar, &c->FirstSock->RemoteIP, 2);
2195 
2196 	if (StrCmpi(method, "login") == 0)
2197 	{
2198 		bool auth_ret = false;
2199 
2200 		Debug("Login...\n");
2201 		c->Status = CONNECTION_STATUS_USERAUTH;
2202 
2203 		c->Type = CONNECTION_TYPE_LOGIN;
2204 
2205 		if (no_more_users_in_server)
2206 		{
2207 			// There are many users than are allowed in the VPN Server
2208 			FreePack(p);
2209 			c->Err = ERR_TOO_MANY_USER;
2210 			error_detail = "ERR_TOO_MANY_USER";
2211 			goto CLEANUP;
2212 		}
2213 
2214 		// Such as the client name
2215 		if (PackGetStr(p, "hello", c->ClientStr, sizeof(c->ClientStr)) == false)
2216 		{
2217 			StrCpy(c->ClientStr, sizeof(c->ClientStr), "Unknown");
2218 		}
2219 		c->ServerVer = CEDAR_VER;
2220 		c->ServerBuild = CEDAR_BUILD;
2221 
2222 		// Get the NODE_INFO
2223 		Zero(&node, sizeof(node));
2224 		InRpcNodeInfo(&node, p);
2225 
2226 		// Protocol
2227 		c->Protocol = GetProtocolFromPack(p);
2228 		if (c->Protocol == CONNECTION_UDP)
2229 		{
2230 			// Release the structure of the TCP connection
2231 			if (c->Tcp)
2232 			{
2233 				ReleaseList(c->Tcp->TcpSockList);
2234 				Free(c->Tcp);
2235 			}
2236 		}
2237 
2238 		if (GetServerCapsBool(c->Cedar->Server, "b_vpn_client_connect") == false)
2239 		{
2240 			// VPN client is unable to connect
2241 			FreePack(p);
2242 			c->Err = ERR_NOT_SUPPORTED;
2243 			goto CLEANUP;
2244 		}
2245 
2246 
2247 
2248 		// Login
2249 		if (GetHubnameAndUsernameFromPack(p, username, sizeof(username), hubname, sizeof(hubname)) == false)
2250 		{
2251 			// Protocol error
2252 			FreePack(p);
2253 			c->Err = ERR_PROTOCOL_ERROR;
2254 			error_detail = "GetHubnameAndUsernameFromPack";
2255 			goto CLEANUP;
2256 		}
2257 
2258 		if (farm_member)
2259 		{
2260 			bool ok = false;
2261 			UINT authtype;
2262 
2263 			authtype = GetAuthTypeFromPack(p);
2264 			if (StrCmpi(username, ADMINISTRATOR_USERNAME) == 0 &&
2265 				authtype == AUTHTYPE_PASSWORD)
2266 			{
2267 				ok = true;
2268 			}
2269 
2270 			if (authtype == AUTHTYPE_TICKET)
2271 			{
2272 				ok = true;
2273 			}
2274 
2275 			if (ok == false)
2276 			{
2277 				// Logging on directly to server farm members by
2278 				// non-Administrators are prohibited
2279 				FreePack(p);
2280 				SLog(c->Cedar, "LS_FARMMEMBER_NOT_ADMIN", c->Name, hubname, ADMINISTRATOR_USERNAME, username);
2281 				c->Err = ERR_ACCESS_DENIED;
2282 				goto CLEANUP;
2283 			}
2284 		}
2285 
2286 		Debug("Username = %s, HubName = %s\n", username, hubname);
2287 		LockHubList(c->Cedar);
2288 		{
2289 			hub = GetHub(c->Cedar, hubname);
2290 		}
2291 		UnlockHubList(c->Cedar);
2292 		if (hub == NULL)
2293 		{
2294 			// The HUB does not exist
2295 			FreePack(p);
2296 			c->Err = ERR_HUB_NOT_FOUND;
2297 			SLog(c->Cedar, "LS_HUB_NOT_FOUND", c->Name, hubname);
2298 			error_detail = "ERR_HUB_NOT_FOUND";
2299 			goto CLEANUP;
2300 		}
2301 
2302 		if (hub->ForceDisableComm)
2303 		{
2304 			// Commnunication function is disabled
2305 			FreePack(p);
2306 			c->Err = ERR_SERVER_CANT_ACCEPT;
2307 			error_detail = "ERR_COMM_DISABLED";
2308 			ReleaseHub(hub);
2309 			goto CLEANUP;
2310 		}
2311 
2312 		if (GetGlobalServerFlag(GSF_DISABLE_AC) == 0)
2313 		{
2314 			if (hub->HubDb != NULL && c->FirstSock != NULL)
2315 			{
2316 				IP ip;
2317 
2318 				Copy(&ip, &c->FirstSock->RemoteIP, sizeof(IP));
2319 
2320 				if (IsIpDeniedByAcList(&ip, hub->HubDb->AcList))
2321 				{
2322 					char ip_str[64];
2323 					// Access denied
2324 					ReleaseHub(hub);
2325 					hub = NULL;
2326 					FreePack(p);
2327 					c->Err = ERR_IP_ADDRESS_DENIED;
2328 					IPToStr(ip_str, sizeof(ip_str), &ip);
2329 					SLog(c->Cedar, "LS_IP_DENIED", c->Name, ip_str);
2330 					goto CLEANUP;
2331 				}
2332 			}
2333 		}
2334 
2335 		Lock(hub->lock);
2336 		{
2337 			UINT cert_size = 0;
2338 			void *cert_buf = NULL;
2339 			USER *user;
2340 			USERGROUP *group;
2341 			char plain_password[MAX_PASSWORD_LEN + 1];
2342 			RADIUS_LOGIN_OPTION radius_login_opt;
2343 
2344 			if (hub->Halt || hub->Offline)
2345 			{
2346 				// HUB is off-line
2347 				FreePack(p);
2348 				Unlock(hub->lock);
2349 				ReleaseHub(hub);
2350 				c->Err = ERR_HUB_STOPPING;
2351 				goto CLEANUP;
2352 			}
2353 
2354 			Zero(&radius_login_opt, sizeof(radius_login_opt));
2355 
2356 			if (hub->Option != NULL)
2357 			{
2358 				radius_login_opt.In_CheckVLanId = hub->Option->AssignVLanIdByRadiusAttribute;
2359 				radius_login_opt.In_DenyNoVlanId = hub->Option->DenyAllRadiusLoginWithNoVlanAssign;
2360 				if (hub->Option->UseHubNameAsRadiusNasId)
2361 				{
2362 					StrCpy(radius_login_opt.NasId, sizeof(radius_login_opt.NasId), hubname);
2363 				}
2364 			}
2365 
2366 			// Get the various flags
2367 			use_encrypt = PackGetInt(p, "use_encrypt") == 0 ? false : true;
2368 			use_compress = PackGetInt(p, "use_compress") == 0 ? false : true;
2369 			max_connection = PackGetInt(p, "max_connection");
2370 			half_connection = PackGetInt(p, "half_connection") == 0 ? false : true;
2371 			use_fast_rc4 = PackGetInt(p, "use_fast_rc4") == 0 ? false : true;
2372 			qos = PackGetInt(p, "qos") ? true : false;
2373 			client_id = PackGetInt(p, "client_id");
2374 			adjust_mss = PackGetInt(p, "adjust_mss");
2375 			use_udp_acceleration_client = PackGetBool(p, "use_udp_acceleration");
2376 			client_udp_acceleration_max_version = PackGetInt(p, "udp_acceleration_max_version");
2377 			if (client_udp_acceleration_max_version == 0)
2378 			{
2379 				client_udp_acceleration_max_version = 1;
2380 			}
2381 			client_rudp_bulk_max_version = PackGetInt(p, "rudp_bulk_max_version");
2382 			if (client_rudp_bulk_max_version == 0)
2383 			{
2384 				client_rudp_bulk_max_version = 1;
2385 			}
2386 			support_hmac_on_udp_acceleration_client = PackGetBool(p, "support_hmac_on_udp_acceleration");
2387 			support_udp_accel_fast_disconnect_detect = PackGetBool(p, "support_udp_accel_fast_disconnect_detect");
2388 			support_bulk_on_rudp = PackGetBool(p, "support_bulk_on_rudp");
2389 			support_hmac_on_bulk_of_rudp = PackGetBool(p, "support_hmac_on_bulk_of_rudp");
2390 			support_udp_recovery = PackGetBool(p, "support_udp_recovery");
2391 
2392 			if (c->IsInProc)
2393 			{
2394 				char tmp[MAX_SIZE];
2395 				UINT64 ptr;
2396 
2397 				ptr = PackGetInt64(p, "release_me_eap_client");
2398 				if (ptr != 0)
2399 				{
2400 					release_me_eap_client = (EAP_CLIENT *)ptr;
2401 				}
2402 
2403 				PackGetStr(p, "inproc_postfix", c->InProcPrefix, sizeof(c->InProcPrefix));
2404 				Zero(tmp, sizeof(tmp));
2405 				PackGetStr(p, "inproc_cryptname", tmp, sizeof(tmp));
2406 				c->InProcLayer = PackGetInt(p, "inproc_layer");
2407 
2408 				if (c->FirstSock != NULL)
2409 				{
2410 					if (IsEmptyStr(c->InProcPrefix) == false)
2411 					{
2412 						Format(c->FirstSock->UnderlayProtocol, sizeof(c->FirstSock->UnderlayProtocol),
2413 							SOCK_UNDERLAY_INPROC_EX, c->InProcPrefix);
2414 
2415 						AddProtocolDetailsStr(c->FirstSock->UnderlayProtocol,
2416 							sizeof(c->FirstSock->UnderlayProtocol),
2417 							c->InProcPrefix);
2418 					}
2419 				}
2420 
2421 				if (c->CipherName != NULL)
2422 				{
2423 					Free(c->CipherName);
2424 				}
2425 
2426 				c->CipherName = NULL;
2427 
2428 				if (IsEmptyStr(tmp) == false)
2429 				{
2430 					c->CipherName = CopyStr(tmp);
2431 					use_encrypt = true;
2432 				}
2433 
2434 				use_udp_acceleration_client = false;
2435 
2436 				Format(radius_login_opt.In_VpnProtocolState, sizeof(radius_login_opt.In_VpnProtocolState),
2437 					"L%u:%s", c->InProcLayer, c->InProcPrefix);
2438 			}
2439 			else
2440 			{
2441 				if (c->CipherName != NULL)
2442 				{
2443 					Free(c->CipherName);
2444 				}
2445 				c->CipherName = NULL;
2446 
2447 				if (c->FirstSock != NULL && IsEmptyStr(c->FirstSock->CipherName) == false)
2448 				{
2449 					c->CipherName = CopyStr(c->FirstSock->CipherName);
2450 				}
2451 
2452 				Format(radius_login_opt.In_VpnProtocolState, sizeof(radius_login_opt.In_VpnProtocolState),
2453 					"L%u:%s", IPC_LAYER_2, "SEVPN");
2454 			}
2455 
2456 			if (support_bulk_on_rudp && c->FirstSock != NULL && c->FirstSock->IsRUDPSocket &&
2457 				c->FirstSock->BulkRecvKey != NULL && c->FirstSock->BulkSendKey != NULL)
2458 			{
2459 				// Allow UDP bulk transfer if the client side supports
2460 				// in the case of using R-UDP Socket
2461 				enable_bulk_on_rudp = true;
2462 
2463 				enable_hmac_on_bulk_of_rudp = support_hmac_on_bulk_of_rudp;
2464 			}
2465 
2466 			if (support_udp_recovery && c->FirstSock != NULL && c->FirstSock->IsRUDPSocket)
2467 			{
2468 				// Allow UDP recovery
2469 				enable_udp_recovery = true;
2470 			}
2471 
2472 			if (use_udp_acceleration_client)
2473 			{
2474 				PackGetData2(p, "udp_acceleration_client_key", udp_acceleration_client_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1);
2475 				PackGetData2(p, "udp_acceleration_client_key_v2", udp_acceleration_client_key_v2, UDP_ACCELERATION_COMMON_KEY_SIZE_V2);
2476 
2477 				// Get the parameters for the UDP acceleration function
2478 				if (PackGetIp(p, "udp_acceleration_client_ip", &udp_acceleration_client_ip) == false)
2479 				{
2480 					use_udp_acceleration_client = false;
2481 				}
2482 				else
2483 				{
2484 					if (IsZeroIp(&udp_acceleration_client_ip))
2485 					{
2486 						Copy(&udp_acceleration_client_ip, &c->FirstSock->RemoteIP, sizeof(IP));
2487 					}
2488 					udp_acceleration_client_port = PackGetInt(p, "udp_acceleration_client_port");
2489 					if (udp_acceleration_client_port == 0)
2490 					{
2491 						use_udp_acceleration_client = false;
2492 					}
2493 				}
2494 
2495 				use_hmac_on_udp_acceleration = support_hmac_on_udp_acceleration_client;
2496 			}
2497 
2498 			Debug("use_udp_acceleration_client = %u\n", use_udp_acceleration_client);
2499 			Debug("use_hmac_on_udp_acceleration = %u\n", use_hmac_on_udp_acceleration);
2500 
2501 			// Request mode
2502 			require_bridge_routing_mode = PackGetBool(p, "require_bridge_routing_mode");
2503 			require_monitor_mode = PackGetBool(p, "require_monitor_mode");
2504 			if (require_monitor_mode)
2505 			{
2506 				qos = false;
2507 			}
2508 
2509 			if (is_server_or_bridge)
2510 			{
2511 				require_bridge_routing_mode = true;
2512 			}
2513 
2514 			// Client unique ID
2515 			Zero(unique, sizeof(unique));
2516 			if (PackGetDataSize(p, "unique_id") == SHA1_SIZE)
2517 			{
2518 				PackGetData(p, "unique_id", unique);
2519 			}
2520 
2521 			// Get the authentication method
2522 			authtype = GetAuthTypeFromPack(p);
2523 
2524 			if (1)
2525 			{
2526 				// Log
2527 				char ip1[64], ip2[64], verstr[64];
2528 				wchar_t *authtype_str = _UU("LH_AUTH_UNKNOWN");
2529 				switch (authtype)
2530 				{
2531 				case CLIENT_AUTHTYPE_ANONYMOUS:
2532 					authtype_str = _UU("LH_AUTH_ANONYMOUS");
2533 					break;
2534 				case CLIENT_AUTHTYPE_PASSWORD:
2535 					authtype_str = _UU("LH_AUTH_PASSWORD");
2536 					break;
2537 				case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
2538 					authtype_str = _UU("LH_AUTH_PLAIN_PASSWORD");
2539 					break;
2540 				case CLIENT_AUTHTYPE_CERT:
2541 					authtype_str = _UU("LH_AUTH_CERT");
2542 					break;
2543 				case AUTHTYPE_TICKET:
2544 					authtype_str = _UU("LH_AUTH_TICKET");
2545 					break;
2546 				case AUTHTYPE_OPENVPN_CERT:
2547 					authtype_str = _UU("LH_AUTH_OPENVPN_CERT");
2548 					break;
2549 				}
2550 				IPToStr(ip1, sizeof(ip1), &c->FirstSock->RemoteIP);
2551 				IPToStr(ip2, sizeof(ip2), &c->FirstSock->LocalIP);
2552 
2553 				Format(verstr, sizeof(verstr), "%u.%02u", c->ClientVer / 100, c->ClientVer % 100);
2554 
2555 				HLog(hub, "LH_CONNECT_CLIENT", c->Name, ip1, c->FirstSock->RemoteHostname, c->FirstSock->RemotePort,
2556 					c->ClientStr, verstr, c->ClientBuild, authtype_str, username);
2557 			}
2558 
2559 			// Attempt an anonymous authentication first
2560 			auth_ret = SamAuthUserByAnonymous(hub, username);
2561 
2562 			if (auth_ret)
2563 			{
2564 				if (c->IsInProc)
2565 				{
2566 					IPC_MSCHAP_V2_AUTHINFO mschap;
2567 					char password_tmp[MAX_SIZE];
2568 
2569 					Zero(&mschap, sizeof(mschap));
2570 
2571 					Zero(password_tmp, sizeof(password_tmp));
2572 					PackGetStr(p, "plain_password", password_tmp, sizeof(password_tmp));
2573 
2574 					if (ParseAndExtractMsChapV2InfoFromPassword(&mschap, password_tmp))
2575 					{
2576 						// Because the server don't know the NTLM hashed password, the bet to the possibility of
2577 						// the same character to the user name and empty, search a password of different
2578 						// versions of the upper and lower case characters in the case of anonymous authentication.
2579 						// Returns the MS-CHAPv2 response by using the password if there is a match.
2580 						// Fail the authentication if no match is found.
2581 						// (Because, if return a false MS-CHAPv2 Response, PPP client cause an error)
2582 						LIST *o = NewListFast(NULL);
2583 						char tmp1[MAX_SIZE];
2584 						char tmp2[MAX_SIZE];
2585 						char tmp3[MAX_SIZE];
2586 						char tmp4[MAX_SIZE];
2587 						char *response_pw;
2588 						char psk[MAX_SIZE];
2589 
2590 						ParseNtUsername(mschap.MsChapV2_PPPUsername, tmp1, sizeof(tmp1), tmp2, sizeof(tmp2), false);
2591 						ParseNtUsername(mschap.MsChapV2_PPPUsername, tmp3, sizeof(tmp3), tmp4, sizeof(tmp4), true);
2592 
2593 						Add(o, "");
2594 						Add(o, "-");
2595 						Add(o, ".");
2596 						Add(o, "*");
2597 						Add(o, "?");
2598 						Add(o, " ");
2599 						Add(o, "p");
2600 						Add(o, "guest");
2601 						Add(o, "anony");
2602 						Add(o, "anonymouse");
2603 						Add(o, "password");
2604 						Add(o, "passwd");
2605 						Add(o, "pass");
2606 						Add(o, "pw");
2607 						Add(o, mschap.MsChapV2_PPPUsername);
2608 						Add(o, tmp1);
2609 						Add(o, tmp2);
2610 						Add(o, tmp3);
2611 						Add(o, tmp4);
2612 
2613 						Zero(psk, sizeof(psk));
2614 
2615 						if (c->Cedar->Server != NULL)
2616 						{
2617 							SERVER *s = c->Cedar->Server;
2618 
2619 							if (s->IPsecServer != NULL)
2620 							{
2621 								StrCpy(psk, sizeof(psk), s->IPsecServer->Services.IPsec_Secret);
2622 
2623 								Add(o, psk);
2624 							}
2625 						}
2626 
2627 						response_pw = MsChapV2DoBruteForce(&mschap, o);
2628 
2629 						ReleaseList(o);
2630 
2631 						if (response_pw != NULL)
2632 						{
2633 							UCHAR challenge8[8];
2634 							UCHAR nt_hash[16];
2635 							UCHAR nt_hash_hash[16];
2636 
2637 							GenerateNtPasswordHash(nt_hash, response_pw);
2638 							GenerateNtPasswordHashHash(nt_hash_hash, nt_hash);
2639 							MsChapV2_GenerateChallenge8(challenge8, mschap.MsChapV2_ClientChallenge, mschap.MsChapV2_ServerChallenge,
2640 								mschap.MsChapV2_PPPUsername);
2641 							MsChapV2Server_GenerateResponse(mschap_v2_server_response_20, nt_hash_hash,
2642 								mschap.MsChapV2_ClientResponse, challenge8);
2643 
2644 							Free(response_pw);
2645 						}
2646 						else
2647 						{
2648 							auth_ret = false;
2649 						}
2650 					}
2651 				}
2652 
2653 				if (auth_ret)
2654 				{
2655 					// User authentication success by anonymous authentication
2656 					HLog(hub, "LH_AUTH_OK", c->Name, username);
2657 					is_empty_password = true;
2658 				}
2659 			}
2660 
2661 			if (auth_ret == false)
2662 			{
2663 				// Attempt other authentication methods if anonymous authentication fails
2664 				switch (authtype)
2665 				{
2666 				case CLIENT_AUTHTYPE_ANONYMOUS:
2667 					// Anonymous authentication (this have been already attempted)
2668 					break;
2669 
2670 				case AUTHTYPE_TICKET:
2671 					// Ticket authentication
2672 					if (PackGetDataSize(p, "ticket") == SHA1_SIZE)
2673 					{
2674 						PackGetData(p, "ticket", ticket);
2675 
2676 						auth_ret = SiCheckTicket(hub, ticket, username, sizeof(username), username_real, sizeof(username_real),
2677 							&ticketed_policy, sessionname, sizeof(sessionname), groupname, sizeof(groupname));
2678 					}
2679 					break;
2680 
2681 				case CLIENT_AUTHTYPE_PASSWORD:
2682 					// Password authentication
2683 					if (PackGetDataSize(p, "secure_password") == SHA1_SIZE)
2684 					{
2685 						POLICY *pol = NULL;
2686 						UCHAR secure_password[SHA1_SIZE];
2687 						Zero(secure_password, sizeof(secure_password));
2688 						if (PackGetDataSize(p, "secure_password") == SHA1_SIZE)
2689 						{
2690 							PackGetData(p, "secure_password", secure_password);
2691 						}
2692 						auth_ret = SamAuthUserByPassword(hub, username, c->Random, secure_password, NULL, NULL, NULL);
2693 
2694 						pol = SamGetUserPolicy(hub, username);
2695 						if (pol != NULL)
2696 						{
2697 							no_save_password = pol->NoSavePassword;
2698 							Free(pol);
2699 						}
2700 
2701 						if(auth_ret){
2702 							// Check whether the password was empty
2703 							UCHAR hashed_empty_password[SHA1_SIZE];
2704 							UCHAR secure_empty_password[SHA1_SIZE];
2705 							HashPassword(hashed_empty_password, username, "");
2706 							SecurePassword(secure_empty_password, hashed_empty_password, c->Random);
2707 							if(Cmp(secure_password, secure_empty_password, SHA1_SIZE)==0){
2708 								is_empty_password = true;
2709 							}
2710 						}
2711 					}
2712 					break;
2713 
2714 				case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
2715 					{
2716 						POLICY *pol = NULL;
2717 
2718 						// Plaintext password authentication
2719 						Zero(plain_password, sizeof(plain_password));
2720 						PackGetStr(p, "plain_password", plain_password, sizeof(plain_password));
2721 						if (c->IsInProc == false && StartWith(plain_password, IPC_PASSWORD_MSCHAPV2_TAG))
2722 						{
2723 							// Do not allow the MS-CHAPv2 authentication other than IPC sessions
2724 							Zero(plain_password, sizeof(plain_password));
2725 						}
2726 
2727 						if (auth_ret == false)
2728 						{
2729 							// Attempt a password authentication of normal user
2730 							UCHAR secure_password[SHA1_SIZE];
2731 							UCHAR hash_password[SHA1_SIZE];
2732 							bool is_mschap = StartWith(plain_password, IPC_PASSWORD_MSCHAPV2_TAG);
2733 
2734 							HashPassword(hash_password, username, plain_password);
2735 							SecurePassword(secure_password, hash_password, c->Random);
2736 
2737 							if (is_mschap == false)
2738 							{
2739 								auth_ret = SamAuthUserByPassword(hub, username, c->Random, secure_password, NULL, NULL, NULL);
2740 							}
2741 							else
2742 							{
2743 								auth_ret = SamAuthUserByPassword(hub, username, c->Random, secure_password,
2744 									plain_password, mschap_v2_server_response_20, &ms_chap_error);
2745 							}
2746 
2747 							if (auth_ret && pol == NULL)
2748 							{
2749 								pol = SamGetUserPolicy(hub, username);
2750 							}
2751 						}
2752 
2753 						if (auth_ret == false)
2754 						{
2755 							// Attempt external authentication registered users
2756 							bool fail_ext_user_auth = false;
2757 							if (GetGlobalServerFlag(GSF_DISABLE_RADIUS_AUTH) != 0)
2758 							{
2759 								fail_ext_user_auth = true;
2760 							}
2761 
2762 							if (fail_ext_user_auth == false)
2763 							{
2764 								auth_ret = SamAuthUserByPlainPassword(c, hub, username, plain_password, false, mschap_v2_server_response_20, &radius_login_opt);
2765 							}
2766 
2767 							if (auth_ret && pol == NULL)
2768 							{
2769 								pol = SamGetUserPolicy(hub, username);
2770 							}
2771 						}
2772 
2773 						if (auth_ret == false)
2774 						{
2775 							// Attempt external authentication asterisk user
2776 							bool b = false;
2777 							bool fail_ext_user_auth = false;
2778 
2779 							if (GetGlobalServerFlag(GSF_DISABLE_RADIUS_AUTH) != 0)
2780 							{
2781 								fail_ext_user_auth = true;
2782 							}
2783 
2784 							if (fail_ext_user_auth == false)
2785 							{
2786 								AcLock(hub);
2787 								{
2788 									b = AcIsUser(hub, "*");
2789 								}
2790 								AcUnlock(hub);
2791 
2792 								// If there is asterisk user, log on as the user
2793 								if (b)
2794 								{
2795 									auth_ret = SamAuthUserByPlainPassword(c, hub, username, plain_password, true, mschap_v2_server_response_20, &radius_login_opt);
2796 									if (auth_ret && pol == NULL)
2797 									{
2798 										pol = SamGetUserPolicy(hub, "*");
2799 									}
2800 								}
2801 							}
2802 						}
2803 
2804 						if (pol != NULL)
2805 						{
2806 							no_save_password = pol->NoSavePassword;
2807 							Free(pol);
2808 						}
2809 
2810 						if(auth_ret){
2811 							// Check whether the password was empty
2812 							if(IsEmptyStr(plain_password)){
2813 								is_empty_password = true;
2814 							}
2815 						}
2816 					}
2817 					break;
2818 
2819 				case CLIENT_AUTHTYPE_CERT:
2820 					if (GetGlobalServerFlag(GSF_DISABLE_CERT_AUTH) == 0)
2821 					{
2822 						// Certificate authentication
2823 						cert_size = PackGetDataSize(p, "cert");
2824 						if (cert_size >= 1 && cert_size <= 100000)
2825 						{
2826 							cert_buf = ZeroMalloc(cert_size);
2827 							if (PackGetData(p, "cert", cert_buf))
2828 							{
2829 								UCHAR sign[4096 / 8];
2830 								UINT sign_size = PackGetDataSize(p, "sign");
2831 								if (sign_size <= sizeof(sign) && sign_size >= 1)
2832 								{
2833 									if (PackGetData(p, "sign", sign))
2834 									{
2835 										BUF *b = NewBuf();
2836 										X *x;
2837 										WriteBuf(b, cert_buf, cert_size);
2838 										x = BufToX(b, false);
2839 										if (x != NULL && x->is_compatible_bit &&
2840 											sign_size == (x->bits / 8))
2841 										{
2842 											K *k = GetKFromX(x);
2843 											// Verify the signature received from the client
2844 											if (RsaVerifyEx(c->Random, SHA1_SIZE, sign, k, x->bits))
2845 											{
2846 												// Confirmed that the client has had this certificate
2847 												// certainly because the signature matched.
2848 												// Check whether the certificate is valid.
2849 												auth_ret = SamAuthUserByCert(hub, username, x);
2850 												if (auth_ret)
2851 												{
2852 													// Copy the certificate
2853 													c->ClientX = CloneX(x);
2854 												}
2855 											}
2856 											else
2857 											{
2858 												// Authentication failure
2859 											}
2860 											FreeK(k);
2861 										}
2862 										FreeX(x);
2863 										FreeBuf(b);
2864 									}
2865 								}
2866 							}
2867 							Free(cert_buf);
2868 						}
2869 					}
2870 					else
2871 					{
2872 						// Certificate authentication is not supported in the open source version
2873 						HLog(hub, "LH_AUTH_CERT_NOT_SUPPORT_ON_OPEN_SOURCE", c->Name, username);
2874 						Unlock(hub->lock);
2875 						ReleaseHub(hub);
2876 						FreePack(p);
2877 						c->Err = ERR_AUTHTYPE_NOT_SUPPORTED;
2878 						goto CLEANUP;
2879 					}
2880 					break;
2881 
2882 				case AUTHTYPE_OPENVPN_CERT:
2883 					// For OpenVPN; mostly same as CLIENT_AUTHTYPE_CERT, but without
2884 					// signature verification, because it was already performed during TLS handshake.
2885 					if (c->IsInProc)
2886 					{
2887 						// Certificate authentication
2888 						cert_size = PackGetDataSize(p, "cert");
2889 						if (cert_size >= 1 && cert_size <= 100000)
2890 						{
2891 							cert_buf = ZeroMalloc(cert_size);
2892 							if (PackGetData(p, "cert", cert_buf))
2893 							{
2894 								BUF *b = NewBuf();
2895 								X *x;
2896 								WriteBuf(b, cert_buf, cert_size);
2897 								x = BufToX(b, false);
2898 								if (x != NULL && x->is_compatible_bit)
2899 								{
2900 									Debug("Got to SamAuthUserByCert %s\n", username); // XXX
2901 									// Check whether the certificate is valid.
2902 									auth_ret = SamAuthUserByCert(hub, username, x);
2903 									if (auth_ret)
2904 									{
2905 										// Copy the certificate
2906 										c->ClientX = CloneX(x);
2907 									}
2908 								}
2909 								FreeX(x);
2910 								FreeBuf(b);
2911 							}
2912 							Free(cert_buf);
2913 						}
2914 					}
2915 					else
2916 					{
2917 						// OpenVPN certificate authentication cannot be used directly by external clients
2918 						Unlock(hub->lock);
2919 						ReleaseHub(hub);
2920 						FreePack(p);
2921 						c->Err = ERR_AUTHTYPE_NOT_SUPPORTED;
2922 						goto CLEANUP;
2923 					}
2924 					break;
2925 
2926 				default:
2927 					// Unknown authentication method
2928 					Unlock(hub->lock);
2929 					ReleaseHub(hub);
2930 					FreePack(p);
2931 					c->Err = ERR_AUTHTYPE_NOT_SUPPORTED;
2932 					error_detail = "ERR_AUTHTYPE_NOT_SUPPORTED";
2933 					goto CLEANUP;
2934 				}
2935 
2936 				if (auth_ret == false)
2937 				{
2938 					// Authentication failure
2939 					HLog(hub, "LH_AUTH_NG", c->Name, username);
2940 				}
2941 				else
2942 				{
2943 					// Authentication success
2944 					HLog(hub, "LH_AUTH_OK", c->Name, username);
2945 				}
2946 			}
2947 
2948 			if (auth_ret == false)
2949 			{
2950 				// Authentication failure
2951 				Unlock(hub->lock);
2952 				ReleaseHub(hub);
2953 				FreePack(p);
2954 				c->Err = ERR_AUTH_FAILED;
2955 				if (ms_chap_error != 0)
2956 				{
2957 					c->Err = ms_chap_error;
2958 				}
2959 				error_detail = "ERR_AUTH_FAILED";
2960 				goto CLEANUP;
2961 			}
2962 			else
2963 			{
2964 				if(is_empty_password)
2965 				{
2966 					SOCK *s = c->FirstSock;
2967 					if (s != NULL && s->RemoteIP.addr[0] != 127)
2968 					{
2969 						if(StrCmpi(username, ADMINISTRATOR_USERNAME) == 0 ||
2970 							GetHubAdminOption(hub, "deny_empty_password") != 0)
2971 						{
2972 							// When the password is empty, remote connection is not acceptable
2973 							HLog(hub, "LH_LOCAL_ONLY", c->Name, username);
2974 
2975 							Unlock(hub->lock);
2976 							ReleaseHub(hub);
2977 							FreePack(p);
2978 							c->Err = ERR_NULL_PASSWORD_LOCAL_ONLY;
2979 							error_detail = "ERR_NULL_PASSWORD_LOCAL_ONLY";
2980 							goto CLEANUP;
2981 						}
2982 					}
2983 				}
2984 			}
2985 
2986 			policy = NULL;
2987 
2988 			// Authentication success
2989 			FreePack(p);
2990 
2991 			// Check the assigned VLAN ID
2992 			if (radius_login_opt.Out_IsRadiusLogin)
2993 			{
2994 				if (radius_login_opt.In_CheckVLanId)
2995 				{
2996 					if (radius_login_opt.Out_VLanId != 0)
2997 					{
2998 						assigned_vlan_id = radius_login_opt.Out_VLanId;
2999 					}
3000 
3001 					if (radius_login_opt.In_DenyNoVlanId && assigned_vlan_id == 0 || assigned_vlan_id >= 4096)
3002 					{
3003 						// Deny this session
3004 						Unlock(hub->lock);
3005 						ReleaseHub(hub);
3006 						c->Err = ERR_ACCESS_DENIED;
3007 						error_detail = "In_DenyNoVlanId";
3008 						goto CLEANUP;
3009 					}
3010 				}
3011 			}
3012 
3013 			// Check the assigned MAC Address
3014 			if (radius_login_opt.Out_IsRadiusLogin)
3015 			{
3016 				Copy(assigned_ipc_mac_address, radius_login_opt.Out_VirtualMacAddress, 6);
3017 			}
3018 
3019 			if (StrCmpi(username, ADMINISTRATOR_USERNAME) != 0)
3020 			{
3021 				// Get the policy
3022 				if (farm_member == false)
3023 				{
3024 					bool is_asterisk_user = false;
3025 
3026 					// In the case of not a farm member
3027 					user = AcGetUser(hub, username);
3028 					if (user == NULL)
3029 					{
3030 						user = AcGetUser(hub, "*");
3031 						if (user == NULL)
3032 						{
3033 							// User acquisition failure
3034 							Unlock(hub->lock);
3035 							ReleaseHub(hub);
3036 							c->Err = ERR_ACCESS_DENIED;
3037 							error_detail = "AcGetUser";
3038 							goto CLEANUP;
3039 						}
3040 
3041 						is_asterisk_user = true;
3042 					}
3043 
3044 					policy = NULL;
3045 
3046 					Lock(user->lock);
3047 					{
3048 						if (is_asterisk_user == false)
3049 						{
3050 							UCHAR associated_mac_address[6];
3051 
3052 							// Get the associated virtual MAC address
3053 							if (GetUserMacAddressFromUserNote(associated_mac_address, user->Note))
3054 							{
3055 								if (IsZero(assigned_ipc_mac_address, 6))
3056 								{
3057 									Copy(assigned_ipc_mac_address, associated_mac_address, 6);
3058 								}
3059 							}
3060 						}
3061 
3062 						// Get the expiration date
3063 						user_expires = user->ExpireTime;
3064 
3065 						StrCpy(username_real, sizeof(username_real), user->Name);
3066 						group = user->Group;
3067 						if (group != NULL)
3068 						{
3069 							AddRef(group->ref);
3070 
3071 							Lock(group->lock);
3072 							{
3073 								// Get the group name
3074 								StrCpy(groupname, sizeof(groupname), group->Name);
3075 							}
3076 							Unlock(group->lock);
3077 						}
3078 
3079 						if (user->Policy != NULL)
3080 						{
3081 							policy = ClonePolicy(user->Policy);
3082 						}
3083 						else
3084 						{
3085 							if (group)
3086 							{
3087 								Lock(group->lock);
3088 								{
3089 									if (group->Policy != NULL)
3090 									{
3091 										policy = ClonePolicy(group->Policy);
3092 									}
3093 								}
3094 								Unlock(group->lock);
3095 							}
3096 						}
3097 
3098 						if (group != NULL)
3099 						{
3100 							ReleaseGroup(group);
3101 						}
3102 					}
3103 					Unlock(user->lock);
3104 					loggedin_user_object = user;
3105 				}
3106 				else
3107 				{
3108 					// In the case of farm member
3109 					policy = ClonePolicy(&ticketed_policy);
3110 				}
3111 			}
3112 			else
3113 			{
3114 				// Administrator mode
3115 				admin_mode = true;
3116 				StrCpy(username_real, sizeof(username_real), ADMINISTRATOR_USERNAME);
3117 
3118 				policy = ClonePolicy(GetDefaultPolicy());
3119 				policy->NoBroadcastLimiter = true;
3120 				policy->MonitorPort = true;
3121 			}
3122 
3123 			if (policy == NULL)
3124 			{
3125 				// Use the default policy
3126 				policy = ClonePolicy(GetDefaultPolicy());
3127 			}
3128 
3129 			if (policy->MaxConnection == 0)
3130 			{
3131 				policy->MaxConnection = MAX_TCP_CONNECTION;
3132 			}
3133 
3134 			if (policy->TimeOut == 0)
3135 			{
3136 				policy->TimeOut = 20;
3137 			}
3138 
3139 			if (qos)
3140 			{
3141 				// VoIP / QoS
3142 				if (policy->NoQoS)
3143 				{
3144 					// Policy does not allow QoS
3145 					qos = false;
3146 				}
3147 				if (GetServerCapsBool(c->Cedar->Server, "b_support_qos") == false)
3148 				{
3149 					// Server does not support QoS
3150 					qos = false;
3151 					policy->NoQoS = true;
3152 				}
3153 				if (GetHubAdminOption(hub, "deny_qos") != 0)
3154 				{
3155 					// It is prohibited in the management options
3156 					qos = false;
3157 					policy->NoQoS = true;
3158 				}
3159 			}
3160 
3161 			if (GetHubAdminOption(hub, "max_bitrates_download") != 0)
3162 			{
3163 				if (policy->MaxDownload == 0)
3164 				{
3165 					policy->MaxDownload = GetHubAdminOption(hub, "max_bitrates_download");
3166 				}
3167 				else
3168 				{
3169 					UINT r = GetHubAdminOption(hub, "max_bitrates_download");
3170 					policy->MaxDownload = MIN(policy->MaxDownload, r);
3171 				}
3172 			}
3173 
3174 			if (GetHubAdminOption(hub, "max_bitrates_upload") != 0)
3175 			{
3176 				if (policy->MaxUpload == 0)
3177 				{
3178 					policy->MaxUpload = GetHubAdminOption(hub, "max_bitrates_upload");
3179 				}
3180 				else
3181 				{
3182 					UINT r = GetHubAdminOption(hub, "max_bitrates_upload");
3183 					policy->MaxUpload = MIN(policy->MaxUpload, r);
3184 				}
3185 			}
3186 
3187 			if (GetHubAdminOption(hub, "deny_bridge") != 0)
3188 			{
3189 				policy->NoBridge = true;
3190 			}
3191 
3192 			if (GetHubAdminOption(hub, "deny_routing") != 0)
3193 			{
3194 				policy->NoRouting = true;
3195 			}
3196 
3197 			if (c->IsInProc)
3198 			{
3199 				policy->NoBridge = false;
3200 				policy->NoRouting = false;
3201 			}
3202 
3203 			if (hub->Option->ClientMinimumRequiredBuild > c->ClientBuild &&
3204 				 InStrEx(c->ClientStr, "client", false))
3205 			{
3206 				// Build number of the client is too small
3207 				HLog(hub, "LH_CLIENT_VERSION_OLD", c->Name, c->ClientBuild, hub->Option->ClientMinimumRequiredBuild);
3208 
3209 				Unlock(hub->lock);
3210 				ReleaseHub(hub);
3211 				c->Err = ERR_VERSION_INVALID;
3212 				Free(policy);
3213 				error_detail = "ERR_VERSION_INVALID";
3214 				goto CLEANUP;
3215 			}
3216 
3217 			if (hub->Option->RequiredClientId != 0 &&
3218 				hub->Option->RequiredClientId != client_id &&
3219 				InStrEx(c->ClientStr, "client", false))
3220 			{
3221 				// Build number of the client is too small
3222 				HLog(hub, "LH_CLIENT_ID_REQUIRED", c->Name, client_id, hub->Option->RequiredClientId);
3223 
3224 				Unlock(hub->lock);
3225 				ReleaseHub(hub);
3226 				c->Err = ERR_CLIENT_ID_REQUIRED;
3227 				error_detail = "ERR_CLIENT_ID_REQUIRED";
3228 				Free(policy);
3229 				goto CLEANUP;
3230 			}
3231 
3232 			if ((policy->NoSavePassword) || (policy->AutoDisconnect != 0))
3233 			{
3234 				if (c->ClientBuild < 6560 && InStrEx(c->ClientStr, "client", false))
3235 				{
3236 					// If NoSavePassword policy is specified,
3237 					// only supported client can connect
3238 					HLog(hub, "LH_CLIENT_VERSION_OLD", c->Name, c->ClientBuild, 6560);
3239 
3240 					Unlock(hub->lock);
3241 					ReleaseHub(hub);
3242 					c->Err = ERR_VERSION_INVALID;
3243 					error_detail = "ERR_VERSION_INVALID";
3244 					Free(policy);
3245 					goto CLEANUP;
3246 				}
3247 			}
3248 
3249 			if (user_expires != 0 && user_expires <= SystemTime64())
3250 			{
3251 				// User expired
3252 				HLog(hub, "LH_USER_EXPIRES", c->Name, username);
3253 
3254 				Unlock(hub->lock);
3255 				ReleaseHub(hub);
3256 				c->Err = ERR_ACCESS_DENIED;
3257 				error_detail = "LH_USER_EXPIRES";
3258 				Free(policy);
3259 				goto CLEANUP;
3260 			}
3261 
3262 			if (policy->Access == false)
3263 			{
3264 				// Access is denied
3265 				HLog(hub, "LH_POLICY_ACCESS_NG", c->Name, username);
3266 
3267 				Unlock(hub->lock);
3268 				ReleaseHub(hub);
3269 				error_detail = "LH_POLICY_ACCESS_NG";
3270 				c->Err = ERR_ACCESS_DENIED;
3271 				Free(policy);
3272 				goto CLEANUP;
3273 			}
3274 
3275 			// Determine the contents of the policy by comparing to
3276 			// option presented by client or deny the connection.
3277 			// Confirm the connectivity in the monitor-mode first
3278 			if (require_monitor_mode && policy->MonitorPort == false)
3279 			{
3280 				// Can not connect in the monitor port mode
3281 				HLog(hub, "LH_POLICY_MONITOR_MODE", c->Name);
3282 
3283 				Unlock(hub->lock);
3284 				ReleaseHub(hub);
3285 				c->Err = ERR_MONITOR_MODE_DENIED;
3286 				Free(policy);
3287 				error_detail = "ERR_MONITOR_MODE_DENIED";
3288 				goto CLEANUP;
3289 			}
3290 
3291 			if (policy->MonitorPort)
3292 			{
3293 				if (require_monitor_mode == false)
3294 				{
3295 					policy->MonitorPort = false;
3296 				}
3297 			}
3298 
3299 			if (policy->MonitorPort)
3300 			{
3301 				qos = false;
3302 			}
3303 
3304 			// Determine whether it can be connected by a bridge / routing mode next
3305 			if (require_bridge_routing_mode &&
3306 				(policy->NoBridge && policy->NoRouting))
3307 			{
3308 				// Can not be connected by a bridge / routing mode
3309 				HLog(hub, "LH_POLICY_BRIDGE_MODE", c->Name);
3310 
3311 				Unlock(hub->lock);
3312 				ReleaseHub(hub);
3313 				c->Err = ERR_BRIDGE_MODE_DENIED;
3314 				error_detail = "ERR_BRIDGE_MODE_DENIED";
3315 				Free(policy);
3316 				goto CLEANUP;
3317 			}
3318 
3319 			if (require_bridge_routing_mode == false)
3320 			{
3321 				policy->NoBridge = true;
3322 				policy->NoRouting = true;
3323 			}
3324 
3325 			if (Cmp(unique, unique2, SHA1_SIZE) == 0)
3326 			{
3327 				// It's a localhost session
3328 				local_host_session = true;
3329 			}
3330 
3331 			if (local_host_session == false)
3332 			{
3333 				// Make further judgment whether localhost session
3334 				SOCK *s = c->FirstSock;
3335 
3336 				if (s != NULL)
3337 				{
3338 					if (IsIPMyHost(&s->RemoteIP))
3339 					{
3340 						// It's a localhost session
3341 						local_host_session = true;
3342 					}
3343 				}
3344 			}
3345 
3346 			if (local_host_session)
3347 			{
3348 				// Permit routing or bridging in the case of localhost session
3349 				policy->NoBridge = false;
3350 				policy->NoRouting = false;
3351 			}
3352 
3353 			if (local_host_session == false)
3354 			{
3355 
3356 				if (policy->NoBridge == false || policy->NoRouting == false)
3357 				{
3358 					use_bridge_license = true;
3359 				}
3360 				else
3361 				{
3362 					use_client_license = true;
3363 				}
3364 			}
3365 
3366 
3367 			if (server != NULL && server->ServerType != SERVER_TYPE_FARM_MEMBER &&
3368 				policy != NULL)
3369 			{
3370 				if (GetServerCapsBool(hub->Cedar->Server, "b_support_limit_multilogin"))
3371 				{
3372 					// Check if the number of concurrent multiple logins limit is specified in the policy
3373 					RPC_ENUM_SESSION t;
3374 					UINT i, num;
3375 					UINT max_logins = policy->MultiLogins;
3376 					UINT ao = GetHubAdminOption(hub, "max_multilogins_per_user");
3377 
3378 					if (ao != 0)
3379 					{
3380 						if (max_logins != 0)
3381 						{
3382 							max_logins = MIN(max_logins, ao);
3383 						}
3384 						else
3385 						{
3386 							max_logins = ao;
3387 						}
3388 					}
3389 
3390 					if (max_logins != 0)
3391 					{
3392 						Zero(&t, sizeof(t));
3393 						StrCpy(t.HubName, sizeof(t.HubName), hub->Name);
3394 
3395 						Unlock(hub->lock);
3396 
3397 						SiEnumSessionMain(server, &t);
3398 
3399 						Lock(hub->lock);
3400 
3401 						num = 0;
3402 
3403 						for (i = 0;i < t.NumSession;i++)
3404 						{
3405 							RPC_ENUM_SESSION_ITEM *e = &t.Sessions[i];
3406 
3407 							if (e->BridgeMode == false && e->Layer3Mode == false && e->LinkMode == false && e->CurrentNumTcp != 0)
3408 							{
3409 								if (StrCmpi(e->Username, username) == 0 &&
3410 									(IsZero(e->UniqueId, 16) || Cmp(e->UniqueId, node.UniqueId, 16) != 0))
3411 								{
3412 									num++;
3413 								}
3414 							}
3415 						}
3416 
3417 						FreeRpcEnumSession(&t);
3418 
3419 						if (num >= max_logins)
3420 						{
3421 							// Can not connect any more
3422 							Unlock(hub->lock);
3423 
3424 							// Dump a detailed error log
3425 							HLog(hub, "LH_TOO_MANY_MULTILOGINS",
3426 								c->Name,
3427 								username, max_logins, num);
3428 
3429 							ReleaseHub(hub);
3430 							c->Err = ERR_TOO_MANY_USER_SESSION;
3431 							Free(policy);
3432 							goto CLEANUP;
3433 						}
3434 					}
3435 				}
3436 			}
3437 
3438 			if (loggedin_user_object != NULL)
3439 			{
3440 				// Update the user information
3441 				Lock(loggedin_user_object->lock);
3442 				{
3443 					loggedin_user_object->LastLoginTime = SystemTime64();
3444 				}
3445 				Unlock(loggedin_user_object->lock);
3446 			}
3447 
3448 			// Update the number of log-ins
3449 			hub->LastCommTime = hub->LastLoginTime = SystemTime64();
3450 
3451 			if (farm_controller)
3452 			{
3453 				wchar_t *msg = GetHubMsg(hub);
3454 
3455 				Unlock(hub->lock);
3456 
3457 				Lock(cedar->CedarSuperLock);
3458 
3459 				// In the case of farm controller, choose a farm members to host this HUB
3460 				LockList(server->FarmMemberList);
3461 				{
3462 					HLog(hub, "LH_FARM_SELECT_1", c->Name);
3463 					f = SiGetHubHostingMember(server, hub, admin_mode, c);
3464 
3465 					if (f == NULL)
3466 					{
3467 						// Failed in the selection
3468 						HLog(hub, "LH_FARM_SELECT_2", c->Name);
3469 						UnlockList(server->FarmMemberList);
3470 						Unlock(cedar->CedarSuperLock);
3471 						ReleaseHub(hub);
3472 						c->Err = ERR_COULD_NOT_HOST_HUB_ON_FARM;
3473 						Free(policy);
3474 						Free(msg);
3475 						goto CLEANUP;
3476 					}
3477 					else
3478 					{
3479 						if (f->Me == false)
3480 						{
3481 							UCHAR ticket[SHA1_SIZE];
3482 							PACK *p;
3483 							BUF *b;
3484 							UINT i;
3485 
3486 							SLog(c->Cedar, "LH_FARM_SELECT_4", c->Name, f->hostname);
3487 
3488 							// Create a session on the selected server farm member
3489 							Rand(ticket, sizeof(ticket));
3490 							SiCallCreateTicket(server, f, hub->Name,
3491 								username, username_real, policy, ticket, Inc(hub->SessionCounter), groupname);
3492 
3493 							p = NewPack();
3494 							PackAddInt(p, "Redirect", 1);
3495 							PackAddIp32(p, "Ip", f->Ip);
3496 							for (i = 0;i < f->NumPort;i++)
3497 							{
3498 								PackAddIntEx(p, "Port", f->Ports[i], i, f->NumPort);
3499 							}
3500 							PackAddData(p, "Ticket", ticket, sizeof(ticket));
3501 
3502 							if (true)
3503 							{
3504 								char *utf = CopyUniToUtf(msg);
3505 
3506 								PackAddData(p, "Msg", utf, StrLen(utf));
3507 
3508 								Free(utf);
3509 							}
3510 
3511 							b = XToBuf(f->ServerCert, false);
3512 							PackAddBuf(p, "Cert", b);
3513 							FreeBuf(b);
3514 
3515 							UnlockList(server->FarmMemberList);
3516 							Unlock(cedar->CedarSuperLock);
3517 							ReleaseHub(hub);
3518 
3519 							HttpServerSend(c->FirstSock, p);
3520 							FreePack(p);
3521 
3522 							c->Err = 0;
3523 							Free(policy);
3524 
3525 							FreePack(HttpServerRecv(c->FirstSock));
3526 							Free(msg);
3527 							goto CLEANUP;
3528 						}
3529 						else
3530 						{
3531 							HLog(hub, "LH_FARM_SELECT_3", c->Name);
3532 							// Continue the process because myself was selected
3533 							UnlockList(server->FarmMemberList);
3534 							Unlock(cedar->CedarSuperLock);
3535 							f->Point = SiGetPoint(server);
3536 							Lock(hub->lock);
3537 							Free(msg);
3538 						}
3539 					}
3540 				}
3541 			}
3542 
3543 			if (admin_mode == false)
3544 			{
3545 				// Check the maximum number of connections of the HUB
3546 				if (hub->Option->MaxSession != 0 &&
3547 					hub->Option->MaxSession <= Count(hub->NumSessions))
3548 				{
3549 					// Can not connect any more
3550 					Unlock(hub->lock);
3551 
3552 					HLog(hub, "LH_MAX_SESSION", c->Name, hub->Option->MaxSession);
3553 
3554 					ReleaseHub(hub);
3555 					c->Err = ERR_HUB_IS_BUSY;
3556 					Free(policy);
3557 					error_detail = "ERR_HUB_IS_BUSY";
3558 					goto CLEANUP;
3559 				}
3560 			}
3561 
3562 			if (use_encrypt == false && c->FirstSock->IsReverseAcceptedSocket)
3563 			{
3564 				// On VPN Azure, SSL encryption is mandated.
3565 				use_encrypt = true;
3566 			}
3567 
3568 			if (use_client_license || use_bridge_license)
3569 			{
3570 				// Examine whether not to conflict with the limit of simultaneous connections
3571 				// number of sessions defined by the Virtual HUB management options
3572 				if (
3573 					(GetHubAdminOption(hub, "max_sessions") != 0 &&
3574 					(Count(hub->NumSessionsClient) + Count(hub->NumSessionsBridge)) >= GetHubAdminOption(hub, "max_sessions"))
3575 					||
3576 					(hub->Option->MaxSession != 0 &&
3577 					(Count(hub->NumSessionsClient) + Count(hub->NumSessionsBridge)) >= hub->Option->MaxSession))
3578 				{
3579 					// Can not connect any more
3580 					Unlock(hub->lock);
3581 
3582 					HLog(hub, "LH_MAX_SESSION", c->Name, GetHubAdminOption(hub, "max_sessions"));
3583 
3584 					ReleaseHub(hub);
3585 					c->Err = ERR_HUB_IS_BUSY;
3586 					Free(policy);
3587 					goto CLEANUP;
3588 				}
3589 			}
3590 
3591 			if (use_client_license)
3592 			{
3593 				// Examine whether not to conflict with the limit of simultaneous connections
3594 				// number of sessions(client) defined by the Virtual HUB management options
3595 				if (((GetHubAdminOption(hub, "max_sessions_client_bridge_apply") != 0
3596 					) &&
3597 					Count(hub->NumSessionsClient) >= GetHubAdminOption(hub, "max_sessions_client") && hub->Cedar->Server != NULL && hub->Cedar->Server->ServerType != SERVER_TYPE_FARM_MEMBER)
3598 					||
3599 					(hub->FarmMember_MaxSessionClientBridgeApply &&
3600 					Count(hub->NumSessionsClient) >= hub->FarmMember_MaxSessionClient))
3601 				{
3602 					// Can not connect any more
3603 					Unlock(hub->lock);
3604 
3605 					HLog(hub, "LH_MAX_SESSION_CLIENT", c->Name, GetHubAdminOption(hub, "max_sessions_client"));
3606 
3607 					ReleaseHub(hub);
3608 					c->Err = ERR_HUB_IS_BUSY;
3609 					Free(policy);
3610 					goto CLEANUP;
3611 				}
3612 			}
3613 
3614 			if (use_bridge_license)
3615 			{
3616 				// Examine whether not to conflict with the limit of simultaneous connections
3617 				// number of sessions(bridge) defined by the Virtual HUB management options
3618 				if (((GetHubAdminOption(hub, "max_sessions_client_bridge_apply") != 0
3619 					) &&
3620 					Count(hub->NumSessionsBridge) >= GetHubAdminOption(hub, "max_sessions_bridge") && hub->Cedar->Server != NULL && hub->Cedar->Server->ServerType != SERVER_TYPE_FARM_MEMBER)
3621 					||
3622 					(hub->FarmMember_MaxSessionClientBridgeApply &&
3623 					Count(hub->NumSessionsBridge) >= hub->FarmMember_MaxSessionBridge))
3624 				{
3625 					// Can not connect any more
3626 					Unlock(hub->lock);
3627 
3628 					HLog(hub, "LH_MAX_SESSION_BRIDGE", c->Name, GetHubAdminOption(hub, "max_sessions_bridge"));
3629 
3630 					ReleaseHub(hub);
3631 					c->Err = ERR_HUB_IS_BUSY;
3632 					Free(policy);
3633 					goto CLEANUP;
3634 				}
3635 			}
3636 
3637 			if (Count(hub->Cedar->CurrentSessions) >= GetServerCapsInt(hub->Cedar->Server, "i_max_sessions"))
3638 			{
3639 				// Can not connect any more
3640 				Unlock(hub->lock);
3641 
3642 				HLog(hub, "LH_MAX_SESSION_2", c->Name, GetServerCapsInt(hub->Cedar->Server, "i_max_sessions"));
3643 
3644 				ReleaseHub(hub);
3645 				c->Err = ERR_HUB_IS_BUSY;
3646 				Free(policy);
3647 				goto CLEANUP;
3648 			}
3649 
3650 			// Increment the current number of connections
3651 			Inc(hub->NumSessions);
3652 			if (use_bridge_license)
3653 			{
3654 				Inc(hub->NumSessionsBridge);
3655 			}
3656 
3657 			if (use_client_license)
3658 			{
3659 				Inc(hub->NumSessionsClient);
3660 			}
3661 			Inc(hub->Cedar->CurrentSessions);
3662 
3663 			// Calculate the time-out period
3664 			timeout = policy->TimeOut * 1000;	// Convert milliseconds to seconds
3665 			if (timeout == 0)
3666 			{
3667 				timeout = TIMEOUT_DEFAULT;
3668 			}
3669 			timeout = MIN(timeout, TIMEOUT_MAX);
3670 			timeout = MAX(timeout, TIMEOUT_MIN);
3671 
3672 			// Update the max_connection according to the policy
3673 			max_connection = MIN(max_connection, policy->MaxConnection);
3674 			max_connection = MIN(max_connection, MAX_TCP_CONNECTION);
3675 			max_connection = MAX(max_connection, 1);
3676 
3677 			if (c->FirstSock->IsRUDPSocket)
3678 			{
3679 				// In the case of TCP-over-UDP
3680 				half_connection = false;
3681 
3682 				// Disable the QoS
3683 				qos = false;
3684 
3685 				if (enable_udp_recovery == false)
3686 				{
3687 					// Disable the session reconnection feature
3688 					no_reconnect_to_session = true;
3689 					max_connection = 1;
3690 				}
3691 				else
3692 				{
3693 					// If the UDP recovery is enabled, permit the session re-connection feature (for 2)
3694 					no_reconnect_to_session = false;
3695 					max_connection = NUM_TCP_CONNECTION_FOR_UDP_RECOVERY;
3696 				}
3697 			}
3698 
3699 			if (half_connection)
3700 			{
3701 				// Number of connections should be more than 2 in the case of Half Connection
3702 				max_connection = MAX(max_connection, 2);
3703 			}
3704 
3705 			if (qos)
3706 			{
3707 				// Number of connections is set to 2 or more when using the VoIP / QoS
3708 				max_connection = MAX(max_connection, 2);
3709 				if (half_connection)
3710 				{
3711 					max_connection = MAX(max_connection, 4);
3712 				}
3713 			}
3714 
3715 			c->Status = CONNECTION_STATUS_ESTABLISHED;
3716 
3717 			// Remove the connection from Cedar
3718 			DelConnection(c->Cedar, c);
3719 
3720 			// VLAN ID
3721 			if (assigned_vlan_id != 0)
3722 			{
3723 				if (policy->VLanId == 0)
3724 				{
3725 					policy->VLanId = assigned_vlan_id;
3726 				}
3727 			}
3728 
3729 			// Create a Session
3730 			StrLower(username);
3731 			s = NewServerSessionEx(c->Cedar, c, hub, username, policy, c->IsInProc,
3732 				(c->IsInProc && IsZero(assigned_ipc_mac_address, 6) == false) ? assigned_ipc_mac_address : NULL);
3733 
3734 			s->EnableUdpRecovery = enable_udp_recovery;
3735 			s->LocalHostSession = local_host_session;
3736 			s->NormalClient = true;
3737 
3738 			IPToStr(s->ClientIP, sizeof(s->ClientIP), &c->ClientIp);
3739 
3740 			if (c->FirstSock->IsRUDPSocket)
3741 			{
3742 				// R-UDP session
3743 				s->IsRUDPSession = true;
3744 				s->RUdpMss = c->FirstSock->RUDP_OptimizedMss;
3745 				Debug("Optimized MSS Value for R-UDP: %u\n", s->RUdpMss);
3746 				AddProtocolDetailsKeyValueInt(s->ProtocolDetails, sizeof(s->ProtocolDetails),
3747 					"RUDP_MSS", s->RUdpMss);
3748 			}
3749 
3750 			if (enable_bulk_on_rudp)
3751 			{
3752 				// Allow bulk transfer on R-UDP
3753 				s->EnableBulkOnRUDP = true;
3754 				s->EnableHMacOnBulkOfRUDP = enable_hmac_on_bulk_of_rudp;
3755 			}
3756 
3757 			s->IsAzureSession = c->FirstSock->IsReverseAcceptedSocket;
3758 
3759 			StrCpy(s->UnderlayProtocol, sizeof(s->UnderlayProtocol), c->FirstSock->UnderlayProtocol);
3760 
3761 			AddProtocolDetailsStr(s->ProtocolDetails, sizeof(s->ProtocolDetails), c->FirstSock->ProtocolDetails);
3762 
3763 			if (server != NULL)
3764 			{
3765 				s->NoSendSignature = server->NoSendSignature;
3766 			}
3767 
3768 			if (c->IsInProc)
3769 			{
3770 				s->NoSendSignature = true;
3771 			}
3772 
3773 			if (c->IsInProc && StrCmpi(c->InProcPrefix, OPENVPN_IPC_POSTFIX_L3) == 0)
3774 			{
3775 				// OpenVPN L3 session
3776 				s->IsOpenVPNL3Session = true;
3777 			}
3778 
3779 			if (c->IsInProc && StrCmpi(c->InProcPrefix, OPENVPN_IPC_POSTFIX_L2) == 0)
3780 			{
3781 				// OpenVPN L2 session
3782 				s->IsOpenVPNL2Session = true;
3783 			}
3784 
3785 			// Determine whether the use of UDP acceleration mode
3786 			if (use_udp_acceleration_client)
3787 			{
3788 				s->UseUdpAcceleration = true;
3789 
3790 				s->UdpAccelFastDisconnectDetect = support_udp_accel_fast_disconnect_detect;
3791 
3792 				// TODO: determine UDP Accel version
3793 				udp_acceleration_version = 1;
3794 				if (client_udp_acceleration_max_version >= 2)
3795 				{
3796 					udp_acceleration_version = 2;
3797 				}
3798 			}
3799 
3800 			// TODO: determine RUDP Bulk version
3801 			if (client_rudp_bulk_max_version >= 2)
3802 			{
3803 				rudp_bulk_version = 2;
3804 			}
3805 
3806 			s->BulkOnRUDPVersion = rudp_bulk_version;
3807 
3808 			if (s->EnableBulkOnRUDP)
3809 			{
3810 				AddProtocolDetailsKeyValueInt(s->ProtocolDetails, sizeof(s->ProtocolDetails),
3811 					"RUDP_Bulk_Ver",
3812 					s->BulkOnRUDPVersion);
3813 			}
3814 
3815 			if (hub->Option != NULL && hub->Option->DisableUdpAcceleration)
3816 			{
3817 				s->UseUdpAcceleration = false;
3818 			}
3819 
3820 			if (IsZeroIP(&c->FirstSock->Reverse_MyServerGlobalIp) == false &&
3821 				CmpIpAddr(&c->FirstSock->Reverse_MyServerGlobalIp, &c->FirstSock->RemoteIP) == 0)
3822 			{
3823 				// Disable forcibly the UDP acceleration mode if VPN Server and VPN Client
3824 				// are in same LAN in the case of using VPN Azure.
3825 				// (Or this may cause infinite loop of packet)
3826 				s->UseUdpAcceleration = false;
3827 			}
3828 
3829 			if (s->UseUdpAcceleration)
3830 			{
3831 				s->UseHMacOnUdpAcceleration = use_hmac_on_udp_acceleration;
3832 			}
3833 
3834 			Debug("UseUdpAcceleration = %u\n", s->UseUdpAcceleration);
3835 			Debug("UseHMacOnUdpAcceleration = %u\n", s->UseHMacOnUdpAcceleration);
3836 			Debug("UdpAccelerationVersion = %u\n", s->UdpAccelerationVersion);
3837 
3838 			if (s->UseUdpAcceleration)
3839 			{
3840 				bool no_nat_t = false;
3841 
3842 
3843 				// Initialize the UDP acceleration function
3844 				s->UdpAccel = NewUdpAccel(c->Cedar, (c->FirstSock->IsRUDPSocket ? NULL : &c->FirstSock->LocalIP), false, c->FirstSock->IsRUDPSocket, no_nat_t);
3845 				if (s->UdpAccel == NULL)
3846 				{
3847 					s->UseUdpAcceleration = false;
3848 					Debug("NewUdpAccel Failed.\n");
3849 				}
3850 				else
3851 				{
3852 					s->UdpAccel->Version = udp_acceleration_version;
3853 
3854 					if (UdpAccelInitServer(s->UdpAccel,
3855 						s->UdpAccel->Version == 2 ? udp_acceleration_client_key_v2 : udp_acceleration_client_key,
3856 						&udp_acceleration_client_ip, udp_acceleration_client_port,
3857 						&c->FirstSock->RemoteIP) == false)
3858 					{
3859 						Debug("UdpAccelInitServer Failed.\n");
3860 						s->UseUdpAcceleration = false;
3861 					}
3862 
3863 					s->UdpAccel->FastDetect = s->UdpAccelFastDisconnectDetect;
3864 
3865 					if (use_encrypt == false)
3866 					{
3867 						s->UdpAccel->PlainTextMode = true;
3868 					}
3869 
3870 					s->UdpAccel->UseHMac = s->UseHMacOnUdpAcceleration;
3871 
3872 					AddProtocolDetailsKeyValueInt(s->ProtocolDetails, sizeof(s->ProtocolDetails),
3873 						"UDPAccel_Ver",
3874 						s->UdpAccel->Version);
3875 
3876 					if (s->UdpAccel->Version >= 2)
3877 					{
3878 						AddProtocolDetailsStr(s->ProtocolDetails, sizeof(s->ProtocolDetails),
3879 							Aead_ChaCha20Poly1305_Ietf_IsOpenSSL() ?
3880 							"ChachaPoly_OpenSSL" : "ChachaPoly_Self");
3881 					}
3882 
3883 					AddProtocolDetailsKeyValueInt(s->ProtocolDetails, sizeof(s->ProtocolDetails),
3884 						"UDPAccel_MSS",
3885 						UdpAccelCalcMss(s->UdpAccel));
3886 				}
3887 			}
3888 
3889 			s->UseClientLicense = use_client_license;
3890 			s->UseBridgeLicense = use_bridge_license;
3891 
3892 			s->AdjustMss = adjust_mss;
3893 			if (s->AdjustMss != 0)
3894 			{
3895 				Debug("AdjustMSS: %u\n", s->AdjustMss);
3896 				AddProtocolDetailsKeyValueInt(s->ProtocolDetails, sizeof(s->ProtocolDetails),
3897 					"AdjustMSS", s->AdjustMss);
3898 			}
3899 
3900 			s->IsBridgeMode = (policy->NoBridge == false) || (policy->NoRouting == false);
3901 			s->IsMonitorMode = policy->MonitorPort;
3902 
3903 			// Decide whether IPv6 session
3904 			s->IPv6Session = false;
3905 
3906 			if (node.ClientIpAddress == 0)
3907 			{
3908 				s->IPv6Session = true;
3909 			}
3910 
3911 			if (use_bridge_license)
3912 			{
3913 				Inc(s->Cedar->AssignedBridgeLicense);
3914 			}
3915 
3916 			if (use_client_license)
3917 			{
3918 				Inc(s->Cedar->AssignedClientLicense);
3919 			}
3920 
3921 			if (server != NULL)
3922 			{
3923 				// Update the total allocation of the number of licenses for Server structure
3924 				if (server->ServerType == SERVER_TYPE_STANDALONE)
3925 				{
3926 					// Update only stand-alone mode
3927 					// (Periodically poll in the cluster controller mode)
3928 					server->CurrentAssignedClientLicense = Count(s->Cedar->AssignedClientLicense);
3929 					server->CurrentAssignedBridgeLicense = Count(s->Cedar->AssignedBridgeLicense);
3930 				}
3931 			}
3932 
3933 			if (StrLen(sessionname) != 0)
3934 			{
3935 				// Specify the session name
3936 				Free(s->Name);
3937 				s->Name = CopyStr(sessionname);
3938 			}
3939 
3940 			{
3941 				char ip[128];
3942 				IPToStr(ip, sizeof(ip), &c->FirstSock->RemoteIP);
3943 				HLog(hub, "LH_NEW_SESSION", c->Name, s->Name, ip, c->FirstSock->RemotePort,
3944 					c->FirstSock->UnderlayProtocol,
3945 					c->FirstSock->ProtocolDetails);
3946 			}
3947 
3948 			c->Session = s;
3949 			s->AdministratorMode = admin_mode;
3950 			StrCpy(s->UserNameReal, sizeof(s->UserNameReal), username_real);
3951 			StrCpy(s->GroupName, sizeof(s->GroupName), groupname);
3952 
3953 			// Get the session key
3954 			Copy(session_key, s->SessionKey, SHA1_SIZE);
3955 
3956 			// Set the parameters
3957 			s->MaxConnection = max_connection;
3958 			s->UseEncrypt = use_encrypt;
3959 			if (s->UseEncrypt && use_fast_rc4)
3960 			{
3961 				s->UseFastRC4 = use_fast_rc4;
3962 			}
3963 			s->UseCompress = use_compress;
3964 			s->HalfConnection = half_connection;
3965 			s->Timeout = timeout;
3966 			s->QoS = qos;
3967 			s->NoReconnectToSession = no_reconnect_to_session;
3968 
3969 			s->VLanId = policy->VLanId;
3970 
3971 			// User name
3972 			s->Username = CopyStr(username);
3973 
3974 			HLog(hub, "LH_SET_SESSION", s->Name, s->MaxConnection,
3975 				s->UseEncrypt ? _UU("L_YES") : _UU("L_NO"),
3976 				s->UseCompress ? _UU("L_YES") : _UU("L_NO"),
3977 				s->HalfConnection ? _UU("L_YES") : _UU("L_NO"),
3978 				s->Timeout / 1000);
3979 
3980 			msg = GetHubMsg(hub);
3981 
3982 			// Suppress client update notification flag
3983 			if (hub->Option != NULL)
3984 			{
3985 				suppress_client_update_notification = hub->Option->SuppressClientUpdateNotification;
3986 			}
3987 		}
3988 		Unlock(hub->lock);
3989 
3990 		// Send a Welcome packet to the client
3991 		p = PackWelcome(s);
3992 
3993 		PackAddBool(p, "suppress_client_update_notification", suppress_client_update_notification);
3994 
3995 		if (s->InProcMode)
3996 		{
3997 			if (IsZero(mschap_v2_server_response_20, sizeof(mschap_v2_server_response_20)) == false)
3998 			{
3999 				// MS-CHAPv2 Response
4000 				PackAddData(p, "IpcMsChapV2ServerResponse", mschap_v2_server_response_20, sizeof(mschap_v2_server_response_20));
4001 			}
4002 		}
4003 
4004 		if (true)
4005 		{
4006 			// A message to be displayed in the VPN Client (Will not be displayed if the VPN Gate Virtual HUB)
4007 			char *utf;
4008 			wchar_t winver_msg_client[3800];
4009 			wchar_t winver_msg_server[3800];
4010 			UINT tmpsize;
4011 			wchar_t *tmp;
4012 			RPC_WINVER server_winver;
4013 
4014 			GetWinVer(&server_winver);
4015 
4016 			Zero(winver_msg_client, sizeof(winver_msg_client));
4017 			Zero(winver_msg_server, sizeof(winver_msg_server));
4018 
4019 			if (IsSupportedWinVer(&winver) == false)
4020 			{
4021 				SYSTEMTIME st;
4022 
4023 				LocalTime(&st);
4024 
4025 				UniFormat(winver_msg_client, sizeof(winver_msg_client), _UU("WINVER_ERROR_FORMAT"),
4026 					_UU("WINVER_ERROR_PC_LOCAL"),
4027 					winver.Title,
4028 					_UU("WINVER_ERROR_VPNSERVER"),
4029 					SUPPORTED_WINDOWS_LIST,
4030 					_UU("WINVER_ERROR_PC_LOCAL"),
4031 					_UU("WINVER_ERROR_VPNSERVER"),
4032 					_UU("WINVER_ERROR_VPNSERVER"),
4033 					_UU("WINVER_ERROR_VPNSERVER"),
4034 					st.wYear, st.wMonth);
4035 			}
4036 
4037 			if (IsSupportedWinVer(&server_winver) == false)
4038 			{
4039 				SYSTEMTIME st;
4040 
4041 				LocalTime(&st);
4042 
4043 				UniFormat(winver_msg_server, sizeof(winver_msg_server), _UU("WINVER_ERROR_FORMAT"),
4044 					_UU("WINVER_ERROR_PC_REMOTE"),
4045 					server_winver.Title,
4046 					_UU("WINVER_ERROR_VPNSERVER"),
4047 					SUPPORTED_WINDOWS_LIST,
4048 					_UU("WINVER_ERROR_PC_REMOTE"),
4049 					_UU("WINVER_ERROR_VPNSERVER"),
4050 					_UU("WINVER_ERROR_VPNSERVER"),
4051 					_UU("WINVER_ERROR_VPNSERVER"),
4052 					st.wYear, st.wMonth);
4053 			}
4054 
4055 			tmpsize = UniStrSize(winver_msg_client) + UniStrSize(winver_msg_server) + UniStrSize(msg) + (16000 + 3000) * sizeof(wchar_t);
4056 
4057 			tmp = ZeroMalloc(tmpsize);
4058 
4059 			if (IsURLMsg(msg, NULL, 0) == false)
4060 			{
4061 
4062 				if (s != NULL && s->IsRUDPSession && c != NULL && StrCmpi(hub->Name, VG_HUBNAME) != 0)
4063 				{
4064 					// Show the warning message if the connection is made by NAT-T
4065 					wchar_t *tmp2;
4066 					UINT tmp2_size = 2400 * sizeof(wchar_t);
4067 					char local_name[128];
4068 					wchar_t local_name_2[128];
4069 					char local_name_3[128];
4070 
4071 					Zero(local_name, sizeof(local_name));
4072 					Zero(local_name_2, sizeof(local_name_2));
4073 					Zero(local_name_3, sizeof(local_name_3));
4074 
4075 					GetMachineName(local_name, sizeof(local_name));
4076 
4077 #ifdef	OS_WIN32
4078 					MsGetComputerNameFullEx(local_name_2, sizeof(local_name_2), true);
4079 
4080 					UniToStr(local_name_3, sizeof(local_name_3), local_name_2);
4081 
4082 					if (IsEmptyStr(local_name_3) == false)
4083 					{
4084 						StrCpy(local_name, sizeof(local_name), local_name_3);
4085 					}
4086 #endif	// OS_WIN32
4087 
4088 					tmp2 = ZeroMalloc(tmp2_size);
4089 					UniFormat(tmp2, tmp2_size, _UU(c->ClientBuild >= 9428 ? "NATT_MSG" : "NATT_MSG2"), local_name);
4090 
4091 					UniStrCat(tmp, tmpsize, tmp2);
4092 
4093 					Free(tmp2);
4094 				}
4095 
4096 				{
4097 					if (GetGlobalServerFlag(GSF_SHOW_OSS_MSG) != 0)
4098 					{
4099 						UniStrCat(tmp, tmpsize, _UU("OSS_MSG"));
4100 					}
4101 				}
4102 
4103 				{
4104 					UniStrCat(tmp, tmpsize, winver_msg_client);
4105 					UniStrCat(tmp, tmpsize, winver_msg_server);
4106 				}
4107 			}
4108 			UniStrCat(tmp, tmpsize, msg);
4109 
4110 			utf = CopyUniToUtf(tmp);
4111 
4112 			PackAddData(p, "Msg", utf, StrLen(utf));
4113 
4114 			Free(tmp);
4115 			Free(utf);
4116 		}
4117 
4118 		Free(msg);
4119 
4120 
4121 		if (s->UseFastRC4)
4122 		{
4123 			// Generate a RC4 key pair
4124 			GenerateRC4KeyPair(&key_pair);
4125 
4126 			// Add to Welcome packet
4127 			PackAddData(p, "rc4_key_client_to_server", key_pair.ClientToServerKey, sizeof(key_pair.ClientToServerKey));
4128 			PackAddData(p, "rc4_key_server_to_client", key_pair.ServerToClientKey, sizeof(key_pair.ServerToClientKey));
4129 			{
4130 				char key1[64], key2[64];
4131 				BinToStr(key1, sizeof(key1), key_pair.ClientToServerKey, 16);
4132 				BinToStr(key2, sizeof(key2), key_pair.ServerToClientKey, 16);
4133 				Debug(
4134 					"Client to Server Key: %s\n"
4135 					"Server to Client Key: %s\n",
4136 					key1, key2);
4137 			}
4138 		}
4139 
4140 		// Brand string for the connection limit
4141 		{
4142 			char *branded_cfroms = _SS("BRANDED_C_FROM_S");
4143 			if(StrLen(branded_cfroms) > 0)
4144 			{
4145 				PackAddStr(p, "branded_cfroms", branded_cfroms);
4146 			}
4147 		}
4148 
4149 		HttpServerSend(c->FirstSock, p);
4150 		FreePack(p);
4151 
4152 		// Receive a signature
4153 		Copy(&c->Session->NodeInfo, &node, sizeof(NODE_INFO));
4154 
4155 
4156 		{
4157 			wchar_t tmp[MAX_SIZE * 2];
4158 			NodeInfoToStr(tmp, sizeof(tmp), &s->NodeInfo);
4159 
4160 			HLog(hub, "LH_NODE_INFO", s->Name, tmp);
4161 
4162 			if (s->VLanId != 0)
4163 			{
4164 				HLog(hub, "LH_VLAN_ID", s->Name, s->VLanId);
4165 			}
4166 		}
4167 
4168 		// Shift the connection to the tunneling mode
4169 		StartTunnelingMode(c);
4170 
4171 		// Processing of half-connection mode
4172 		if (s->HalfConnection)
4173 		{
4174 			// The direction of the first socket is client to server
4175 			TCPSOCK *ts = (TCPSOCK *)LIST_DATA(c->Tcp->TcpSockList, 0);
4176 			ts->Direction = TCP_CLIENT_TO_SERVER;
4177 		}
4178 
4179 		if (s->UseFastRC4)
4180 		{
4181 			// Set the RC4 key information to the first TCP connection
4182 			TCPSOCK *ts = (TCPSOCK *)LIST_DATA(c->Tcp->TcpSockList, 0);
4183 			Copy(&ts->Rc4KeyPair, &key_pair, sizeof(RC4_KEY_PAIR));
4184 
4185 			InitTcpSockRc4Key(ts, true);
4186 		}
4187 
4188 		if (s->UseEncrypt && s->UseFastRC4 == false)
4189 		{
4190 			s->UseSSLDataEncryption = true;
4191 		}
4192 		else
4193 		{
4194 			s->UseSSLDataEncryption = false;
4195 		}
4196 
4197 		if (s->Hub->Type == HUB_TYPE_FARM_DYNAMIC && s->Cedar->Server != NULL && s->Cedar->Server->ServerType == SERVER_TYPE_FARM_CONTROLLER)
4198 		{
4199 			if (s->Hub->BeingOffline == false)
4200 			{
4201 				// Start the SecureNAT on the dynamic Virtual HUB
4202 				EnableSecureNATEx(s->Hub, false, true);
4203 
4204 				cluster_dynamic_secure_nat = true;
4205 			}
4206 		}
4207 
4208 		if (s->LocalHostSession)
4209 		{
4210 			// Update the local MAC address list
4211 			RefreshLocalMacAddressList();
4212 		}
4213 
4214 		// Discard the user list cache
4215 		DeleteAllUserListCache(hub->UserList);
4216 
4217 
4218 		// Main routine of the session
4219 		Debug("SessionMain()\n");
4220 		s->NumLoginIncrementUserObject = loggedin_user_object;
4221 		s->NumLoginIncrementHubObject = s->Hub;
4222 		s->NumLoginIncrementTick = Tick64() + (UINT64)NUM_LOGIN_INCREMENT_INTERVAL;
4223 		SessionMain(s);
4224 
4225 
4226 		// Discard the user list cache
4227 		DeleteAllUserListCache(hub->UserList);
4228 
4229 		// Decrement the current number of connections
4230 		Lock(s->Hub->lock);
4231 		{
4232 			if (use_bridge_license)
4233 			{
4234 				Dec(hub->NumSessionsBridge);
4235 			}
4236 
4237 			if (use_client_license)
4238 			{
4239 				Dec(hub->NumSessionsClient);
4240 			}
4241 
4242 			Dec(s->Hub->NumSessions);
4243 			Dec(s->Hub->Cedar->CurrentSessions);
4244 
4245 			// Decrement the number of licenses
4246 			if (use_bridge_license)
4247 			{
4248 				Dec(s->Cedar->AssignedBridgeLicense);
4249 			}
4250 
4251 			if (use_client_license)
4252 			{
4253 				Dec(s->Cedar->AssignedClientLicense);
4254 			}
4255 
4256 			if (server != NULL)
4257 			{
4258 				// Update the total allocation of the number of licenses for Server structure
4259 				if (server->ServerType == SERVER_TYPE_STANDALONE)
4260 				{
4261 					// Update only stand-alone mode
4262 					// (Periodically polled in the cluster controller mode)
4263 					server->CurrentAssignedClientLicense = Count(s->Cedar->AssignedClientLicense);
4264 					server->CurrentAssignedBridgeLicense = Count(s->Cedar->AssignedBridgeLicense);
4265 				}
4266 			}
4267 		}
4268 		Unlock(s->Hub->lock);
4269 
4270 		PrintSessionTotalDataSize(s);
4271 
4272 		HLog(s->Hub, "LH_END_SESSION", s->Name, s->TotalSendSizeReal, s->TotalRecvSizeReal);
4273 
4274 		if (cluster_dynamic_secure_nat && s->Hub->BeingOffline == false)
4275 		{
4276 			// Stop the SecureNAT on the dynamic Virtual HUB
4277 			EnableSecureNATEx(s->Hub, false, true);
4278 		}
4279 
4280 		if (s->UdpAccel != NULL)
4281 		{
4282 			// Release the UDP acceleration
4283 			FreeUdpAccel(s->UdpAccel);
4284 			s->UdpAccel = NULL;
4285 		}
4286 
4287 		ReleaseSession(s);
4288 
4289 		ret = true;
4290 		c->Err = ERR_SESSION_REMOVED;
4291 
4292 		ReleaseHub(hub);
4293 
4294 		goto CLEANUP;
4295 	}
4296 	else if (StrCmpi(method, "additional_connect") == 0)
4297 	{
4298 		SOCK *sock;
4299 		TCPSOCK *ts;
4300 		UINT dummy;
4301 
4302 		c->Type = CONNECTION_TYPE_ADDITIONAL;
4303 
4304 		// Additional connection
4305 		// Read the session key
4306 		if (GetSessionKeyFromPack(p, session_key, &dummy) == false)
4307 		{
4308 			FreePack(p);
4309 			c->Err = ERR_PROTOCOL_ERROR;
4310 			goto CLEANUP;
4311 		}
4312 
4313 		FreePack(p);
4314 
4315 		// Get the session from the session key
4316 		s = GetSessionFromKey(c->Cedar, session_key);
4317 		if (s == NULL || s->Halt || s->NoReconnectToSession)
4318 		{
4319 			// Session can not be found, or re-connection is prohibited
4320 			Debug("Session Not Found.\n");
4321 			c->Err = ERR_SESSION_TIMEOUT;
4322 			goto CLEANUP;
4323 		}
4324 
4325 		// Session is found
4326 		Debug("Session Found: %s\n", s->Name);
4327 		// Check the protocol of session
4328 		c->Err = 0;
4329 		Lock(s->lock);
4330 		{
4331 			if (s->Connection->Protocol != CONNECTION_TCP)
4332 			{
4333 				c->Err = ERR_INVALID_PROTOCOL;
4334 			}
4335 		}
4336 		Unlock(s->lock);
4337 		// Check the current number of connections of the session
4338 		Lock(s->Connection->lock);
4339 		if (c->Err == 0)
4340 		{
4341 			if (Count(s->Connection->CurrentNumConnection) > s->MaxConnection)
4342 			{
4343 				c->Err = ERR_TOO_MANY_CONNECTION;
4344 			}
4345 		}
4346 		if (c->Err != 0)
4347 		{
4348 			Unlock(s->Connection->lock);
4349 			if (c->Err == ERR_TOO_MANY_CONNECTION)
4350 			{
4351 				Debug("Session TOO MANY CONNECTIONS !!: %u\n",
4352 					Count(s->Connection->CurrentNumConnection));
4353 			}
4354 			else
4355 			{
4356 				Debug("Session Invalid Protocol.\n");
4357 			}
4358 			ReleaseSession(s);
4359 			goto CLEANUP;
4360 		}
4361 
4362 		// Generate a high-speed RC4 encryption key
4363 		if (s->UseFastRC4)
4364 		{
4365 			GenerateRC4KeyPair(&key_pair);
4366 		}
4367 
4368 		// Add the socket of this connection to the connection list of the session (TCP)
4369 		sock = c->FirstSock;
4370 
4371 		if (sock->IsRUDPSocket && sock->BulkRecvKey != NULL && sock->BulkSendKey != NULL)
4372 		{
4373 			if (s->BulkRecvKeySize != 0 && s->BulkSendKeySize != 0)
4374 			{
4375 				// Restore R-UDP bulk send/recv keys for additional connections
4376 				Copy(sock->BulkRecvKey->Data, s->BulkRecvKey, s->BulkRecvKeySize);
4377 				sock->BulkRecvKey->Size = s->BulkRecvKeySize;
4378 				Copy(sock->BulkSendKey->Data, s->BulkSendKey, s->BulkSendKeySize);
4379 				sock->BulkSendKey->Size = s->BulkSendKeySize;
4380 
4381 				if (false)
4382 				{
4383 					char tmp1[128];
4384 					char tmp2[128];
4385 					BinToStr(tmp1, sizeof(tmp1), s->BulkRecvKey, s->BulkRecvKeySize);
4386 					BinToStr(tmp2, sizeof(tmp2), s->BulkSendKey, s->BulkSendKeySize);
4387 					Debug("Restore: s->BulkRecvKey->Size = %u, s->BulkSendKey->Size = %u\n",
4388 						s->BulkRecvKeySize, s->BulkSendKeySize);
4389 					Debug("Restore:\n%s\n%s\n\n", tmp1, tmp2);
4390 				}
4391 			}
4392 		}
4393 
4394 		ts = NewTcpSock(sock);
4395 		SetTimeout(sock, CONNECTING_TIMEOUT);
4396 		direction = TCP_BOTH;
4397 		LockList(s->Connection->Tcp->TcpSockList);
4398 		{
4399 			if (s->HalfConnection)
4400 			{
4401 				// In half-connection, directions of the TCP connections are automatically
4402 				// adjusted by examining all current direction of the TCP connections
4403 				UINT i, c2s, s2c;
4404 				c2s = s2c = 0;
4405 				for (i = 0;i < LIST_NUM(s->Connection->Tcp->TcpSockList);i++)
4406 				{
4407 					TCPSOCK *ts = (TCPSOCK *)LIST_DATA(s->Connection->Tcp->TcpSockList, i);
4408 					if (ts->Direction == TCP_SERVER_TO_CLIENT)
4409 					{
4410 						s2c++;
4411 					}
4412 					else
4413 					{
4414 						c2s++;
4415 					}
4416 				}
4417 				if (s2c > c2s)
4418 				{
4419 					direction = TCP_CLIENT_TO_SERVER;
4420 				}
4421 				else
4422 				{
4423 					direction = TCP_SERVER_TO_CLIENT;
4424 				}
4425 				Debug("%u/%u\n", s2c, c2s);
4426 				ts->Direction = direction;
4427 			}
4428 		}
4429 		UnlockList(s->Connection->Tcp->TcpSockList);
4430 
4431 		if (s->UseFastRC4)
4432 		{
4433 			// Set the RC4 key information
4434 			Copy(&ts->Rc4KeyPair, &key_pair, sizeof(RC4_KEY_PAIR));
4435 
4436 			InitTcpSockRc4Key(ts, true);
4437 		}
4438 
4439 		// Return a success result
4440 		p = PackError(ERR_NO_ERROR);
4441 		PackAddInt(p, "direction", direction);
4442 
4443 		if (s->UseFastRC4)
4444 		{
4445 			// Add a RC4 key information
4446 			PackAddData(p, "rc4_key_client_to_server", key_pair.ClientToServerKey, sizeof(key_pair.ClientToServerKey));
4447 			PackAddData(p, "rc4_key_server_to_client", key_pair.ServerToClientKey, sizeof(key_pair.ServerToClientKey));
4448 			{
4449 				char key1[64], key2[64];
4450 				BinToStr(key1, sizeof(key1), key_pair.ClientToServerKey, 16);
4451 				BinToStr(key2, sizeof(key2), key_pair.ServerToClientKey, 16);
4452 				Debug(
4453 					"Client to Server Key: %s\n"
4454 					"Server to Client Key: %s\n",
4455 					key1, key2);
4456 			}
4457 		}
4458 
4459 		HttpServerSend(c->FirstSock, p);
4460 		FreePack(p);
4461 
4462 		SetTimeout(sock, INFINITE);
4463 
4464 		LockList(s->Connection->Tcp->TcpSockList);
4465 		{
4466 			Add(s->Connection->Tcp->TcpSockList, ts);
4467 		}
4468 		UnlockList(s->Connection->Tcp->TcpSockList);
4469 
4470 		// Increment the number of connections
4471 		Inc(s->Connection->CurrentNumConnection);
4472 		Debug("TCP Connection Incremented: %u\n", Count(s->Connection->CurrentNumConnection));
4473 
4474 		// Issue the Cancel of session
4475 		Cancel(s->Cancel1);
4476 
4477 		Unlock(s->Connection->lock);
4478 
4479 		c->flag1 = true;
4480 
4481 		ReleaseSession(s);
4482 
4483 		return true;
4484 	}
4485 	else if (StrCmpi(method, "enum_hub") == 0)
4486 	{
4487 		// Enumerate the Virtual HUB
4488 		UINT i, num;
4489 		LIST *o;
4490 		o = NewListFast(NULL);
4491 
4492 		c->Type = CONNECTION_TYPE_ENUM_HUB;
4493 
4494 		FreePack(p);
4495 		p = NewPack();
4496 		LockList(c->Cedar->HubList);
4497 		{
4498 			num = LIST_NUM(c->Cedar->HubList);
4499 			for (i = 0;i < num;i++)
4500 			{
4501 				HUB *h = LIST_DATA(c->Cedar->HubList, i);
4502 				if (h->Option != NULL && h->Option->NoEnum == false)
4503 				{
4504 					Insert(o, CopyStr(h->Name));
4505 				}
4506 			}
4507 		}
4508 		UnlockList(c->Cedar->HubList);
4509 
4510 		num = LIST_NUM(o);
4511 		for (i = 0;i < num;i++)
4512 		{
4513 			char *name = LIST_DATA(o, i);
4514 			PackAddStrEx(p, "HubName", name, i, num);
4515 			Free(name);
4516 		}
4517 		ReleaseList(o);
4518 		PackAddInt(p, "NumHub", num);
4519 
4520 		HttpServerSend(c->FirstSock, p);
4521 		FreePack(p);
4522 		FreePack(HttpServerRecv(c->FirstSock));
4523 		c->Err = 0;
4524 
4525 		SLog(c->Cedar, "LS_ENUM_HUB", c->Name, num);
4526 
4527 		error_detail = "enum_hub";
4528 
4529 		goto CLEANUP;
4530 	}
4531 	else if (StrCmpi(method, "farm_connect") == 0)
4532 	{
4533 		// Server farm connection request
4534 		CEDAR *cedar = c->Cedar;
4535 		c->Type = CONNECTION_TYPE_FARM_RPC;
4536 		c->Err = 0;
4537 		if (c->Cedar->Server == NULL)
4538 		{
4539 			// Unsupported
4540 			c->Err = ERR_NOT_FARM_CONTROLLER;
4541 		}
4542 		else
4543 		{
4544 			SERVER *s = c->Cedar->Server;
4545 			if (s->ServerType != SERVER_TYPE_FARM_CONTROLLER || s->FarmControllerInited == false)
4546 			{
4547 				// Not a farm controller
4548 				SLog(c->Cedar, "LS_FARM_ACCEPT_1", c->Name);
4549 				c->Err = ERR_NOT_FARM_CONTROLLER;
4550 			}
4551 			else
4552 			{
4553 				UCHAR check_secure_password[SHA1_SIZE];
4554 				UCHAR secure_password[SHA1_SIZE];
4555 				// User authentication
4556 				SecurePassword(check_secure_password, s->HashedPassword, c->Random);
4557 				if (PackGetDataSize(p, "SecurePassword") == sizeof(secure_password))
4558 				{
4559 					PackGetData(p, "SecurePassword", secure_password);
4560 				}
4561 				else
4562 				{
4563 					Zero(secure_password, sizeof(secure_password));
4564 				}
4565 
4566 				if (Cmp(secure_password, check_secure_password, SHA1_SIZE) != 0)
4567 				{
4568 					// Password is different
4569 					SLog(c->Cedar, "LS_FARM_ACCEPT_2", c->Name);
4570 					c->Err = ERR_ACCESS_DENIED;
4571 				}
4572 				else
4573 				{
4574 					// Get the certificate
4575 					BUF *b;
4576 					X *server_x;
4577 
4578 					SLog(c->Cedar, "LS_FARM_ACCEPT_3", c->Name);
4579 					b = PackGetBuf(p, "ServerCert");
4580 					if (b == NULL)
4581 					{
4582 						c->Err = ERR_PROTOCOL_ERROR;
4583 					}
4584 					else
4585 					{
4586 						server_x = BufToX(b, false);
4587 						FreeBuf(b);
4588 						if (server_x == NULL)
4589 						{
4590 							c->Err = ERR_PROTOCOL_ERROR;
4591 						}
4592 						else
4593 						{
4594 							UINT ip;
4595 							UINT point;
4596 							char hostname[MAX_SIZE];
4597 
4598 #ifdef	OS_WIN32
4599 							MsSetThreadPriorityRealtime();
4600 #endif	// OS_WIN32
4601 
4602 							SetTimeout(c->FirstSock, SERVER_CONTROL_TCP_TIMEOUT);
4603 
4604 							ip = PackGetIp32(p, "PublicIp");
4605 							point = PackGetInt(p, "Point");
4606 							if (PackGetStr(p, "HostName", hostname, sizeof(hostname)))
4607 							{
4608 								UINT num_port = PackGetIndexCount(p, "PublicPort");
4609 								if (num_port >= 1 && num_port <= MAX_PUBLIC_PORT_NUM)
4610 								{
4611 									UINT *ports = ZeroMalloc(sizeof(UINT) * num_port);
4612 									UINT i;
4613 
4614 									for (i = 0;i < num_port;i++)
4615 									{
4616 										ports[i] = PackGetIntEx(p, "PublicPort", i);
4617 									}
4618 
4619 									SiFarmServ(s, c->FirstSock, server_x, ip, num_port, ports, hostname, point,
4620 										PackGetInt(p, "Weight"), PackGetInt(p, "MaxSessions"));
4621 
4622 									Free(ports);
4623 								}
4624 							}
4625 
4626 							FreeX(server_x);
4627 						}
4628 					}
4629 				}
4630 			}
4631 		}
4632 		FreePack(p);
4633 		goto CLEANUP;
4634 	}
4635 	else if (StrCmpi(method, "admin") == 0 && c->Cedar->Server != NULL)
4636 	{
4637 		UINT err;
4638 		// Administrative RPC connection request
4639 		c->Type = CONNECTION_TYPE_ADMIN_RPC;
4640 		err = AdminAccept(c, p);
4641 		FreePack(p);
4642 		if (err != ERR_NO_ERROR)
4643 		{
4644 			PACK *p = PackError(err);
4645 			HttpServerSend(c->FirstSock, p);
4646 			FreePack(p);
4647 		}
4648 
4649 		error_detail = "admin_rpc";
4650 
4651 		goto CLEANUP;
4652 	}
4653 	else if (StrCmpi(method, "password") == 0)
4654 	{
4655 		UINT err;
4656 		// Password change request
4657 		c->Type = CONNECTION_TYPE_PASSWORD;
4658 		err = ChangePasswordAccept(c, p);
4659 		FreePack(p);
4660 
4661 		p = PackError(err);
4662 		HttpServerSend(c->FirstSock, p);
4663 		FreePack(p);
4664 
4665 		error_detail = "change_password";
4666 
4667 		goto CLEANUP;
4668 	}
4669 	else
4670 	{
4671 		// Unknown method
4672 		FreePack(p);
4673 		c->Err = ERR_PROTOCOL_ERROR;
4674 
4675 		error_detail = "unknown_method";
4676 
4677 		goto CLEANUP;
4678 	}
4679 
4680 CLEANUP:
4681 	// Release the user object
4682 	if (loggedin_user_object != NULL)
4683 	{
4684 		ReleaseUser(loggedin_user_object);
4685 	}
4686 
4687 
4688 	// Error packet transmission
4689 	if (supress_return_pack_error == false)
4690 	{
4691 		p = PackError(c->Err);
4692 		PackAddBool(p, "no_save_password", no_save_password);
4693 		HttpServerSend(c->FirstSock, p);
4694 		FreePack(p);
4695 	}
4696 
4697 	FreePack(HttpServerRecv(c->FirstSock));
4698 
4699 	SleepThread(25);
4700 
4701 	SLog(c->Cedar, "LS_CONNECTION_ERROR", c->Name, GetUniErrorStr(c->Err), c->Err);
4702 
4703 	if (release_me_eap_client != NULL)
4704 	{
4705 		ReleaseEapClient(release_me_eap_client);
4706 	}
4707 
4708 	return ret;
4709 }
4710 
4711 
4712 // Create a Node information
CreateNodeInfo(NODE_INFO * info,CONNECTION * c)4713 void CreateNodeInfo(NODE_INFO *info, CONNECTION *c)
4714 {
4715 	SESSION *s;
4716 	OS_INFO *os;
4717 	char *product_id;
4718 	IP ip;
4719 	bool is_vgc = false;
4720 	// Validate arguments
4721 	if (c == NULL)
4722 	{
4723 		return;
4724 	}
4725 
4726 	s = c->Session;
4727 	os = GetOsInfo();
4728 
4729 
4730 
4731 	Zero(info, sizeof(NODE_INFO));
4732 
4733 	// Client product name
4734 	StrCpy(info->ClientProductName, sizeof(info->ClientProductName), c->ClientStr);
4735 	// Client version
4736 	info->ClientProductVer = Endian32(c->ClientVer);
4737 	// Client build number
4738 	info->ClientProductBuild = Endian32(c->ClientBuild);
4739 
4740 	// Server product name
4741 	StrCpy(info->ServerProductName, sizeof(info->ServerProductName), c->ServerStr);
4742 	// Server version
4743 	info->ServerProductVer = Endian32(c->ServerVer);
4744 	// Server build number
4745 	info->ServerProductBuild = Endian32(c->ServerBuild);
4746 
4747 	// Client OS name
4748 	StrCpy(info->ClientOsName, sizeof(info->ClientOsName), os->OsProductName);
4749 	// Client OS version
4750 	StrCpy(info->ClientOsVer, sizeof(info->ClientOsVer), os->OsVersion);
4751 	// Client OS Product ID
4752 	product_id = OSGetProductId();
4753 	StrCpy(info->ClientOsProductId, sizeof(info->ClientOsProductId), product_id);
4754 	Free(product_id);
4755 
4756 	// Client host name
4757 #ifndef	OS_WIN32
4758 	GetMachineName(info->ClientHostname, sizeof(info->ClientHostname));
4759 #else	// OS_WIN32
4760 	if (true)
4761 	{
4762 		wchar_t namew[256];
4763 		char namea[256];
4764 
4765 		Zero(namew, sizeof(namew));
4766 		MsGetComputerNameFullEx(namew, sizeof(namew), true);
4767 
4768 		Zero(namea, sizeof(namea));
4769 		UniToStr(namea, sizeof(namea), namew);
4770 
4771 		if (IsEmptyStr(namea))
4772 		{
4773 			GetMachineName(namea, sizeof(namea));
4774 		}
4775 
4776 		StrCpy(info->ClientHostname, sizeof(info->ClientHostname), namea);
4777 
4778 	}
4779 #endif	// OS_WIN32
4780 	// Client IP address
4781 	if (IsIP6(&c->FirstSock->LocalIP) == false)
4782 	{
4783 		info->ClientIpAddress = IPToUINT(&c->FirstSock->LocalIP);
4784 	}
4785 	else
4786 	{
4787 		Copy(info->ClientIpAddress6, c->FirstSock->LocalIP.ipv6_addr, sizeof(info->ClientIpAddress6));
4788 	}
4789 	// Client port number
4790 	info->ClientPort = Endian32(c->FirstSock->LocalPort);
4791 
4792 	// Server host name
4793 	StrCpy(info->ServerHostname, sizeof(info->ServerHostname), c->ServerName);
4794 	// Server IP address
4795 	if (GetIP(&ip, info->ServerHostname))
4796 	{
4797 		if (IsIP6(&ip) == false)
4798 		{
4799 			info->ServerIpAddress = IPToUINT(&ip);
4800 		}
4801 		else
4802 		{
4803 			Copy(info->ServerIpAddress6, ip.ipv6_addr, sizeof(info->ServerIpAddress6));
4804 		}
4805 	}
4806 	// Server port number
4807 	info->ServerPort = Endian32(c->ServerPort);
4808 
4809 	if (s->ClientOption->ProxyType == PROXY_SOCKS || s->ClientOption->ProxyType == PROXY_HTTP)
4810 	{
4811 		// Proxy host name
4812 		StrCpy(info->ProxyHostname, sizeof(info->ProxyHostname), s->ClientOption->ProxyName);
4813 
4814 		// Proxy Server IP Address
4815 		if (IsIP6(&c->FirstSock->RemoteIP) == false)
4816 		{
4817 			info->ProxyIpAddress = IPToUINT(&c->FirstSock->RemoteIP);
4818 		}
4819 		else
4820 		{
4821 			Copy(&info->ProxyIpAddress6, c->FirstSock->RemoteIP.ipv6_addr, sizeof(info->ProxyIpAddress6));
4822 		}
4823 
4824 		info->ProxyPort = Endian32(c->FirstSock->RemotePort);
4825 	}
4826 
4827 	// HUB name
4828 	StrCpy(info->HubName, sizeof(info->HubName), s->ClientOption->HubName);
4829 
4830 	// Unique ID
4831 	Copy(info->UniqueId, c->Cedar->UniqueId, sizeof(info->UniqueId));
4832 }
4833 
4834 // Connect a socket additionally
ClientAdditionalConnectToServer(CONNECTION * c)4835 SOCK *ClientAdditionalConnectToServer(CONNECTION *c)
4836 {
4837 	SOCK *s;
4838 	// Validate arguments
4839 	if (c == NULL)
4840 	{
4841 		return NULL;
4842 	}
4843 
4844 	// Socket connection
4845 	s = ClientConnectGetSocket(c, true, (c->DontUseTls1 ? false : true));
4846 	if (s == NULL)
4847 	{
4848 		// Connection failure
4849 		return NULL;
4850 	}
4851 
4852 	// Add the socket to the list
4853 	LockList(c->ConnectingSocks);
4854 	{
4855 		Add(c->ConnectingSocks, s);
4856 		AddRef(s->ref);
4857 	}
4858 	UnlockList(c->ConnectingSocks);
4859 
4860 	if (c->Session->Halt)
4861 	{
4862 		// Stop
4863 		Disconnect(s);
4864 		LockList(c->ConnectingSocks);
4865 		{
4866 			if (Delete(c->ConnectingSocks, s))
4867 			{
4868 				ReleaseSock(s);
4869 			}
4870 		}
4871 		UnlockList(c->ConnectingSocks);
4872 		ReleaseSock(s);
4873 		return NULL;
4874 	}
4875 
4876 	// Time-out
4877 	SetTimeout(s, CONNECTING_TIMEOUT);
4878 
4879 	// Start the SSL communication
4880 	if (StartSSLEx(s, NULL, NULL, (c->DontUseTls1 ? false : true), 0, c->ServerName) == false)
4881 	{
4882 		// SSL communication failure
4883 		Disconnect(s);
4884 		LockList(c->ConnectingSocks);
4885 		{
4886 			if (Delete(c->ConnectingSocks, s))
4887 			{
4888 				ReleaseSock(s);
4889 			}
4890 		}
4891 		UnlockList(c->ConnectingSocks);
4892 		ReleaseSock(s);
4893 		return NULL;
4894 	}
4895 
4896 	// Check the certificate
4897 	if (CompareX(s->RemoteX, c->ServerX) == false)
4898 	{
4899 		// The certificate is invalid
4900 		Disconnect(s);
4901 		c->Session->SessionTimeOuted = true;
4902 	}
4903 
4904 	return s;
4905 }
4906 
4907 // Remove the key and certificate in the secure device
SecureDelete(UINT device_id,char * pin,char * cert_name,char * key_name)4908 UINT SecureDelete(UINT device_id, char *pin, char *cert_name, char *key_name)
4909 {
4910 	SECURE *sec;
4911 	// Validate arguments
4912 	if (pin == NULL || device_id == 0)
4913 	{
4914 		return ERR_INTERNAL_ERROR;
4915 	}
4916 
4917 	// Open the device
4918 	sec = OpenSec(device_id);
4919 	if (sec == NULL)
4920 	{
4921 		return ERR_SECURE_DEVICE_OPEN_FAILED;
4922 	}
4923 
4924 	// Open the session
4925 	if (OpenSecSession(sec, 0) == false)
4926 	{
4927 		CloseSec(sec);
4928 		return ERR_SECURE_DEVICE_OPEN_FAILED;
4929 	}
4930 
4931 	// Login
4932 	if (LoginSec(sec, pin) == false)
4933 	{
4934 		CloseSecSession(sec);
4935 		CloseSec(sec);
4936 		return ERR_SECURE_PIN_LOGIN_FAILED;
4937 	}
4938 
4939 	// Delete the certificate
4940 	if (cert_name != NULL)
4941 	{
4942 		DeleteSecCert(sec, cert_name);
4943 	}
4944 
4945 	// Delete the Private key
4946 	if (key_name != NULL)
4947 	{
4948 		DeleteSecKey(sec, key_name);
4949 	}
4950 
4951 	// Log out
4952 	LogoutSec(sec);
4953 
4954 	// Close the session
4955 	CloseSecSession(sec);
4956 
4957 	// Close the device
4958 	CloseSec(sec);
4959 
4960 	return ERR_NO_ERROR;
4961 }
4962 
4963 // Enumerate certificates and keys in the secure device
SecureEnum(UINT device_id,char * pin,TOKEN_LIST ** cert_list,TOKEN_LIST ** key_list)4964 UINT SecureEnum(UINT device_id, char *pin, TOKEN_LIST **cert_list, TOKEN_LIST **key_list)
4965 {
4966 	SECURE *sec;
4967 	LIST *o;
4968 	LIST *cert_name_list, *key_name_list;
4969 	// Validate arguments
4970 	if (pin == NULL || device_id == 0 || cert_list == NULL || key_list == NULL)
4971 	{
4972 		return ERR_INTERNAL_ERROR;
4973 	}
4974 
4975 	// Open the device
4976 	sec = OpenSec(device_id);
4977 	if (sec == NULL)
4978 	{
4979 		return ERR_SECURE_DEVICE_OPEN_FAILED;
4980 	}
4981 
4982 	// Open the session
4983 	if (OpenSecSession(sec, 0) == false)
4984 	{
4985 		CloseSec(sec);
4986 		return ERR_SECURE_DEVICE_OPEN_FAILED;
4987 	}
4988 
4989 	// Login
4990 	if (LoginSec(sec, pin) == false)
4991 	{
4992 		CloseSecSession(sec);
4993 		CloseSec(sec);
4994 		return ERR_SECURE_PIN_LOGIN_FAILED;
4995 	}
4996 
4997 	// Enumerate objects
4998 	if ((o = EnumSecObject(sec)) != NULL)
4999 	{
5000 		UINT i;
5001 
5002 		cert_name_list = NewList(CompareStr);
5003 		key_name_list = NewList(CompareStr);
5004 
5005 		for (i = 0;i < LIST_NUM(o);i++)
5006 		{
5007 			SEC_OBJ *obj = LIST_DATA(o, i);
5008 
5009 			if (obj->Type == SEC_X)
5010 			{
5011 				Add(cert_name_list, CopyStr(obj->Name));
5012 			}
5013 			else if (obj->Type == SEC_K)
5014 			{
5015 				Add(key_name_list, CopyStr(obj->Name));
5016 			}
5017 		}
5018 
5019 		Sort(cert_name_list);
5020 		Sort(key_name_list);
5021 
5022 		*cert_list = ListToTokenList(cert_name_list);
5023 		*key_list = ListToTokenList(key_name_list);
5024 
5025 		// Release the memory
5026 		FreeStrList(cert_name_list);
5027 		FreeStrList(key_name_list);
5028 		FreeEnumSecObject(o);
5029 	}
5030 	else
5031 	{
5032 		*cert_list = NullToken();
5033 		*key_list = NullToken();
5034 	}
5035 
5036 	// Log out
5037 	LogoutSec(sec);
5038 
5039 	// Close the session
5040 	CloseSecSession(sec);
5041 
5042 	// Close the device
5043 	CloseSec(sec);
5044 
5045 	return ERR_NO_ERROR;
5046 }
5047 
5048 // Record the certificate and key to secure device
SecureWrite(UINT device_id,char * cert_name,X * x,char * key_name,K * k,char * pin)5049 UINT SecureWrite(UINT device_id, char *cert_name, X *x, char *key_name, K *k, char *pin)
5050 {
5051 	SECURE *sec;
5052 	bool failed;
5053 	// Validate arguments
5054 	if (pin == NULL || device_id == 0 || cert_name == NULL || x == NULL || key_name == NULL || k == NULL)
5055 	{
5056 		return ERR_INTERNAL_ERROR;
5057 	}
5058 
5059 	// Open the device
5060 	sec = OpenSec(device_id);
5061 	if (sec == NULL)
5062 	{
5063 		return ERR_SECURE_DEVICE_OPEN_FAILED;
5064 	}
5065 
5066 	// Open the session
5067 	if (OpenSecSession(sec, 0) == false)
5068 	{
5069 		CloseSec(sec);
5070 		return ERR_SECURE_DEVICE_OPEN_FAILED;
5071 	}
5072 
5073 	// Login
5074 	if (LoginSec(sec, pin) == false)
5075 	{
5076 		CloseSecSession(sec);
5077 		CloseSec(sec);
5078 		return ERR_SECURE_PIN_LOGIN_FAILED;
5079 	}
5080 
5081 	// Registration
5082 	failed = false;
5083 
5084 	// Register the certificate
5085 	if (WriteSecCert(sec, true, cert_name, x) == false)
5086 	{
5087 		failed = true;
5088 	}
5089 
5090 	// Register the private key
5091 	if (WriteSecKey(sec, true, key_name, k) == false)
5092 	{
5093 		failed = true;
5094 	}
5095 
5096 	// Log out
5097 	LogoutSec(sec);
5098 
5099 	// Close the session
5100 	CloseSecSession(sec);
5101 
5102 	// Close the device
5103 	CloseSec(sec);
5104 
5105 	if (failed == false)
5106 	{
5107 		// Success
5108 		return ERR_NO_ERROR;
5109 	}
5110 	else
5111 	{
5112 		// Failure
5113 		return ERR_SECURE_CANT_WRITE;
5114 	}
5115 }
5116 
5117 // Attempt to sign by the secure device
SecureSign(SECURE_SIGN * sign,UINT device_id,char * pin)5118 UINT SecureSign(SECURE_SIGN *sign, UINT device_id, char *pin)
5119 {
5120 	SECURE *sec;
5121 	X *x;
5122 	// Validate arguments
5123 	if (sign == false || pin == NULL || device_id == 0)
5124 	{
5125 		return ERR_INTERNAL_ERROR;
5126 	}
5127 
5128 	// Open the device
5129 	sec = OpenSec(device_id);
5130 	if (sec == NULL)
5131 	{
5132 		return ERR_SECURE_DEVICE_OPEN_FAILED;
5133 	}
5134 
5135 	// Open the session
5136 	if (OpenSecSession(sec, 0) == false)
5137 	{
5138 		CloseSec(sec);
5139 		return ERR_SECURE_DEVICE_OPEN_FAILED;
5140 	}
5141 
5142 	// Login
5143 	if (LoginSec(sec, pin) == false)
5144 	{
5145 		CloseSecSession(sec);
5146 		CloseSec(sec);
5147 		return ERR_SECURE_PIN_LOGIN_FAILED;
5148 	}
5149 
5150 	// Read the certificate
5151 	x = ReadSecCert(sec, sign->SecurePublicCertName);
5152 	if (x == NULL)
5153 	{
5154 		LogoutSec(sec);
5155 		CloseSecSession(sec);
5156 		CloseSec(sec);
5157 		return ERR_SECURE_NO_CERT;
5158 	}
5159 
5160 	// Sign by the private key
5161 	if (SignSec(sec, sign->SecurePrivateKeyName, sign->Signature, sign->Random, SHA1_SIZE) == false)
5162 	{
5163 		// Signing failure
5164 		FreeX(x);
5165 		LogoutSec(sec);
5166 		CloseSecSession(sec);
5167 		CloseSec(sec);
5168 		return ERR_SECURE_NO_PRIVATE_KEY;
5169 	}
5170 
5171 	// Convert the certificate to buffer
5172 	sign->ClientCert = x;
5173 
5174 	// Log out
5175 	LogoutSec(sec);
5176 
5177 	// Close the session
5178 	CloseSecSession(sec);
5179 
5180 	// Close the device
5181 	CloseSec(sec);
5182 
5183 	// Success
5184 	return ERR_NO_ERROR;
5185 }
5186 
5187 // Client connects to the server additionally
ClientAdditionalConnect(CONNECTION * c,THREAD * t)5188 bool ClientAdditionalConnect(CONNECTION *c, THREAD *t)
5189 {
5190 	SOCK *s;
5191 	PACK *p;
5192 	TCPSOCK *ts;
5193 	UINT err;
5194 	UINT direction;
5195 	RC4_KEY_PAIR key_pair;
5196 	// Validate arguments
5197 	if (c == NULL)
5198 	{
5199 		return false;
5200 	}
5201 
5202 	// Socket connection to the server
5203 	s = ClientAdditionalConnectToServer(c);
5204 	if (s == NULL)
5205 	{
5206 		// Failed to connect socket
5207 		return false;
5208 	}
5209 
5210 	if (c->Halt)
5211 	{
5212 		goto CLEANUP;
5213 	}
5214 
5215 	// Send a signature
5216 	Debug("Uploading Signature...\n");
5217 	if (ClientUploadSignature(s) == false)
5218 	{
5219 		goto CLEANUP;
5220 	}
5221 
5222 	if (c->Halt)
5223 	{
5224 		// Stop
5225 		goto CLEANUP;
5226 	}
5227 
5228 	// Receive a Hello packet
5229 	Debug("Downloading Hello...\n");
5230 	if (ClientDownloadHello(c, s) == false)
5231 	{
5232 		goto CLEANUP;
5233 	}
5234 
5235 	if (c->Halt)
5236 	{
5237 		// Stop
5238 		goto CLEANUP;
5239 	}
5240 
5241 	// Send a authentication data for the additional connection
5242 	if (ClientUploadAuth2(c, s) == false)
5243 	{
5244 		// Disconnected
5245 		goto CLEANUP;
5246 	}
5247 
5248 	// Receive a response
5249 	p = HttpClientRecv(s);
5250 	if (p == NULL)
5251 	{
5252 		// Disconnected
5253 		goto CLEANUP;
5254 	}
5255 
5256 	err = GetErrorFromPack(p);
5257 	direction = PackGetInt(p, "direction");
5258 
5259 	if (c->Session->UseFastRC4)
5260 	{
5261 		// Get the RC4 key information
5262 		if (PackGetDataSize(p, "rc4_key_client_to_server") == 16)
5263 		{
5264 			PackGetData(p, "rc4_key_client_to_server", key_pair.ClientToServerKey);
5265 		}
5266 		if (PackGetDataSize(p, "rc4_key_server_to_client") == 16)
5267 		{
5268 			PackGetData(p, "rc4_key_server_to_client", key_pair.ServerToClientKey);
5269 		}
5270 		{
5271 			char key1[64], key2[64];
5272 			BinToStr(key1, sizeof(key1), key_pair.ClientToServerKey, 16);
5273 			BinToStr(key2, sizeof(key2), key_pair.ServerToClientKey, 16);
5274 			Debug(
5275 				"Client to Server Key: %s\n"
5276 				"Server to Client Key: %s\n",
5277 				key1, key2);
5278 		}
5279 	}
5280 
5281 	FreePack(p);
5282 	p = NULL;
5283 
5284 	if (err != 0)
5285 	{
5286 		// Error has occurred
5287 		Debug("Additional Connect Error: %u\n", err);
5288 		if (err == ERR_SESSION_TIMEOUT || err == ERR_INVALID_PROTOCOL)
5289 		{
5290 			// We shall re-connection because it is a fatal error
5291 			c->Session->SessionTimeOuted = true;
5292 		}
5293 		goto CLEANUP;
5294 	}
5295 
5296 	Debug("Additional Connect Succeed!\n");
5297 
5298 	if (s->IsRUDPSocket && s->BulkRecvKey != NULL && s->BulkSendKey != NULL)
5299 	{
5300 		// Restore R-UDP bulk send/recv keys for additional connections
5301 		if (c->Session->BulkRecvKeySize != 0 && c->Session->BulkSendKeySize != 0)
5302 		{
5303 			Copy(s->BulkRecvKey->Data, c->Session->BulkRecvKey, c->Session->BulkRecvKeySize);
5304 			s->BulkRecvKey->Size = c->Session->BulkRecvKeySize;
5305 
5306 			Copy(s->BulkSendKey->Data, c->Session->BulkSendKey, c->Session->BulkSendKeySize);
5307 			s->BulkSendKey->Size = c->Session->BulkSendKeySize;
5308 
5309 			if (false)
5310 			{
5311 				char tmp1[128];
5312 				char tmp2[128];
5313 				BinToStr(tmp1, sizeof(tmp1), s->BulkRecvKey->Data, s->BulkRecvKey->Size);
5314 				BinToStr(tmp2, sizeof(tmp2), s->BulkSendKey->Data, s->BulkSendKey->Size);
5315 				Debug("Restore: s->BulkRecvKey->Size = %u, s->BulkSendKey->Size = %u\n",
5316 					s->BulkRecvKey->Size, s->BulkSendKey->Size);
5317 				Debug("Restore:\n%s\n%s\n\n", tmp1, tmp2);
5318 			}
5319 		}
5320 	}
5321 
5322 	// Success the additional connection
5323 	// Add to the TcpSockList of the connection
5324 	ts = NewTcpSock(s);
5325 
5326 	if (c->ServerMode == false)
5327 	{
5328 		if (c->Session->ClientOption->ConnectionDisconnectSpan != 0)
5329 		{
5330 			ts->DisconnectTick = Tick64() + c->Session->ClientOption->ConnectionDisconnectSpan * (UINT64)1000;
5331 		}
5332 	}
5333 
5334 	LockList(c->Tcp->TcpSockList);
5335 	{
5336 		ts->Direction = direction;
5337 		Add(c->Tcp->TcpSockList, ts);
5338 	}
5339 	UnlockList(c->Tcp->TcpSockList);
5340 	Debug("TCP Connection Incremented: %u\n", Count(c->CurrentNumConnection));
5341 
5342 	if (c->Session->HalfConnection)
5343 	{
5344 		Debug("New Half Connection: %s\n",
5345 			direction == TCP_SERVER_TO_CLIENT ? "TCP_SERVER_TO_CLIENT" : "TCP_CLIENT_TO_SERVER"
5346 			);
5347 	}
5348 
5349 	if (c->Session->UseFastRC4)
5350 	{
5351 		// Set the RC4 encryption key
5352 		Copy(&ts->Rc4KeyPair, &key_pair, sizeof(RC4_KEY_PAIR));
5353 
5354 		InitTcpSockRc4Key(ts, false);
5355 	}
5356 
5357 	// Issue the Cancel to the session
5358 	Cancel(c->Session->Cancel1);
5359 
5360 	// Remove the socket from the socket list of connected
5361 	LockList(c->ConnectingSocks);
5362 	{
5363 		if (Delete(c->ConnectingSocks, s))
5364 		{
5365 			ReleaseSock(s);
5366 		}
5367 	}
5368 	UnlockList(c->ConnectingSocks);
5369 	ReleaseSock(s);
5370 	return true;
5371 
5372 CLEANUP:
5373 	// Disconnection process
5374 	Disconnect(s);
5375 	LockList(c->ConnectingSocks);
5376 	{
5377 		if (Delete(c->ConnectingSocks, s))
5378 		{
5379 			ReleaseSock(s);
5380 
5381 		}
5382 	}
5383 	UnlockList(c->ConnectingSocks);
5384 	ReleaseSock(s);
5385 	return false;
5386 }
5387 
5388 // Secure device signing thread
ClientSecureSignThread(THREAD * thread,void * param)5389 void ClientSecureSignThread(THREAD *thread, void *param)
5390 {
5391 	SECURE_SIGN_THREAD_PROC *p = (SECURE_SIGN_THREAD_PROC *)param;
5392 	// Validate arguments
5393 	if (thread == NULL || param == NULL)
5394 	{
5395 		return;
5396 	}
5397 
5398 	NoticeThreadInit(thread);
5399 
5400 	p->Ok = p->SecureSignProc(p->Connection->Session, p->Connection, p->SecureSign);
5401 	p->UserFinished = true;
5402 }
5403 
5404 // Signing with the secure device
ClientSecureSign(CONNECTION * c,UCHAR * sign,UCHAR * random,X ** x)5405 bool ClientSecureSign(CONNECTION *c, UCHAR *sign, UCHAR *random, X **x)
5406 {
5407 	SECURE_SIGN_THREAD_PROC *p;
5408 	SECURE_SIGN *ss;
5409 	SESSION *s;
5410 	CLIENT_OPTION *o;
5411 	CLIENT_AUTH *a;
5412 	THREAD *thread;
5413 	UINT64 start;
5414 	bool ret;
5415 	// Validate arguments
5416 	if (c == NULL || sign == NULL || random == NULL || x == NULL)
5417 	{
5418 		return false;
5419 	}
5420 
5421 	s = c->Session;
5422 	o = s->ClientOption;
5423 	a = s->ClientAuth;
5424 
5425 	p = ZeroMalloc(sizeof(SECURE_SIGN_THREAD_PROC));
5426 	p->Connection = c;
5427 	ss = p->SecureSign = ZeroMallocEx(sizeof(SECURE_SIGN), true);
5428 	StrCpy(ss->SecurePrivateKeyName, sizeof(ss->SecurePrivateKeyName),
5429 		a->SecurePrivateKeyName);
5430 	StrCpy(ss->SecurePublicCertName, sizeof(ss->SecurePublicCertName),
5431 		a->SecurePublicCertName);
5432 	ss->UseSecureDeviceId = c->Cedar->Client->UseSecureDeviceId;
5433 	Copy(ss->Random, random, SHA1_SIZE);
5434 
5435 #ifdef	OS_WIN32
5436 	ss->BitmapId = CmGetSecureBitmapId(c->ServerName);
5437 #endif	// OS_WIN32
5438 
5439 	p->SecureSignProc = a->SecureSignProc;
5440 
5441 	// Create a thread
5442 	thread = NewThread(ClientSecureSignThread, p);
5443 	WaitThreadInit(thread);
5444 
5445 	// Poll every 0.5 seconds until signing is completed or canceled
5446 	start = Tick64();
5447 	while (true)
5448 	{
5449 		if ((Tick64() - start) > CONNECTING_POOLING_SPAN)
5450 		{
5451 			// Send a NOOP periodically for disconnection prevention
5452 			start = Tick64();
5453 			ClientUploadNoop(c);
5454 		}
5455 		if (p->UserFinished)
5456 		{
5457 			// User selected
5458 			break;
5459 		}
5460 		WaitThread(thread, 500);
5461 	}
5462 	ReleaseThread(thread);
5463 
5464 	ret = p->Ok;
5465 
5466 	if (ret)
5467 	{
5468 		Copy(sign, ss->Signature, sizeof(ss->Signature));
5469 		*x = ss->ClientCert;
5470 	}
5471 
5472 	Free(p->SecureSign);
5473 	Free(p);
5474 
5475 	return ret;
5476 }
5477 
5478 // Server certificate confirmation thread
ClientCheckServerCertThread(THREAD * thread,void * param)5479 void ClientCheckServerCertThread(THREAD *thread, void *param)
5480 {
5481 	CHECK_CERT_THREAD_PROC *p = (CHECK_CERT_THREAD_PROC *)param;
5482 	// Validate arguments
5483 	if (thread == NULL || param == NULL)
5484 	{
5485 		return;
5486 	}
5487 
5488 	// Notify the completion of initialization
5489 	NoticeThreadInit(thread);
5490 
5491 	// Query for the selection to the user
5492 	p->Ok = p->CheckCertProc(p->Connection->Session, p->Connection, p->ServerX, &p->Exipred);
5493 	p->UserSelected = true;
5494 }
5495 
5496 // Client verify the certificate of the server
ClientCheckServerCert(CONNECTION * c,bool * expired)5497 bool ClientCheckServerCert(CONNECTION *c, bool *expired)
5498 {
5499 	CLIENT_AUTH *auth;
5500 	X *x;
5501 	CHECK_CERT_THREAD_PROC *p;
5502 	THREAD *thread;
5503 	CEDAR *cedar;
5504 	bool ret;
5505 	UINT64 start;
5506 	// Validate arguments
5507 	if (c == NULL)
5508 	{
5509 		return false;
5510 	}
5511 
5512 	if (expired != NULL)
5513 	{
5514 		*expired = false;
5515 	}
5516 
5517 	auth = c->Session->ClientAuth;
5518 	cedar = c->Cedar;
5519 
5520 	if (auth->CheckCertProc == NULL && c->Session->LinkModeClient == false)
5521 	{
5522 		// No checking function
5523 		return true;
5524 	}
5525 
5526 	if (c->Session->LinkModeClient && c->Session->Link->CheckServerCert == false)
5527 	{
5528 		// It's in cascade connection mode, but do not check the server certificate
5529 		return true;
5530 	}
5531 
5532 	if (c->UseTicket)
5533 	{
5534 		// Check the certificate of the redirected VPN server
5535 		if (CompareX(c->FirstSock->RemoteX, c->ServerX) == false)
5536 		{
5537 			return false;
5538 		}
5539 		else
5540 		{
5541 			return true;
5542 		}
5543 	}
5544 
5545 	x = CloneX(c->FirstSock->RemoteX);
5546 	if (x == NULL)
5547 	{
5548 		// Strange error occurs
5549 		return false;
5550 	}
5551 
5552 	if (CheckXDateNow(x))
5553 	{
5554 		// Check whether it is signed by the root certificate to trust
5555 		if (c->Session->LinkModeClient == false)
5556 		{
5557 			// Normal VPN Client mode
5558 			if (CheckSignatureByCa(cedar, x))
5559 			{
5560 				// This certificate can be trusted because it is signed
5561 				FreeX(x);
5562 				return true;
5563 			}
5564 		}
5565 		else
5566 		{
5567 			// Cascade connection mode
5568 			if (CheckSignatureByCaLinkMode(c->Session, x))
5569 			{
5570 				// This certificate can be trusted because it is signed
5571 				FreeX(x);
5572 				return true;
5573 			}
5574 		}
5575 	}
5576 
5577 	if (c->Session->LinkModeClient)
5578 	{
5579 		if (CheckXDateNow(x))
5580 		{
5581 			Lock(c->Session->Link->lock);
5582 			{
5583 				if (c->Session->Link->ServerCert != NULL)
5584 				{
5585 					if (CompareX(c->Session->Link->ServerCert, x))
5586 					{
5587 						Unlock(c->Session->Link->lock);
5588 						// Exactly match the certificate that is registered in the cascade configuration
5589 						FreeX(x);
5590 						return true;
5591 					}
5592 				}
5593 			}
5594 			Unlock(c->Session->Link->lock);
5595 		}
5596 		else
5597 		{
5598 			if (expired != NULL)
5599 			{
5600 				*expired = true;
5601 			}
5602 		}
5603 
5604 		// Verification failure at this point in the case of cascade connection mode
5605 		FreeX(x);
5606 		return false;
5607 	}
5608 
5609 	p = ZeroMalloc(sizeof(CHECK_CERT_THREAD_PROC));
5610 	p->ServerX = x;
5611 	p->CheckCertProc = auth->CheckCertProc;
5612 	p->Connection = c;
5613 
5614 	// Create a thread
5615 	thread = NewThread(ClientCheckServerCertThread, p);
5616 	WaitThreadInit(thread);
5617 
5618 	// Poll at 0.5-second intervals until the user selects whether the connection
5619 	start = Tick64();
5620 	while (true)
5621 	{
5622 		if ((Tick64() - start) > CONNECTING_POOLING_SPAN)
5623 		{
5624 			// Send a NOOP periodically for disconnection prevention
5625 			start = Tick64();
5626 			ClientUploadNoop(c);
5627 		}
5628 		if (p->UserSelected)
5629 		{
5630 			// User-selected
5631 			break;
5632 		}
5633 		WaitThread(thread, 500);
5634 	}
5635 
5636 	if (expired != NULL)
5637 	{
5638 		*expired = p->Exipred;
5639 	}
5640 
5641 	ret = p->Ok;
5642 	FreeX(p->ServerX);
5643 	Free(p);
5644 	ReleaseThread(thread);
5645 
5646 	return ret;
5647 }
5648 
5649 // Client connects to the server
ClientConnect(CONNECTION * c)5650 bool ClientConnect(CONNECTION *c)
5651 {
5652 	bool ret = false;
5653 	bool ok = false;
5654 	UINT err;
5655 	SOCK *s;
5656 	PACK *p = NULL;
5657 	UINT session_key_32;
5658 	SESSION *sess;
5659 	char session_name[MAX_SESSION_NAME_LEN + 1];
5660 	char connection_name[MAX_CONNECTION_NAME_LEN + 1];
5661 	UCHAR session_key[SHA1_SIZE];
5662 	RC4_KEY_PAIR key_pair;
5663 	POLICY *policy;
5664 	bool expired = false;
5665 	IP server_ip;
5666 	// Validate arguments
5667 	if (c == NULL)
5668 	{
5669 		return false;
5670 	}
5671 
5672 	sess = c->Session;
5673 
5674 	PrintStatus(sess, L"init");
5675 	PrintStatus(sess, _UU("STATUS_1"));
5676 
5677 REDIRECTED:
5678 
5679 	// [Connecting]
5680 	c->Status = CONNECTION_STATUS_CONNECTING;
5681 	c->Session->ClientStatus = CLIENT_STATUS_CONNECTING;
5682 
5683 	s = ClientConnectToServer(c);
5684 	if (s == NULL)
5685 	{
5686 		PrintStatus(sess, L"free");
5687 		return false;
5688 	}
5689 
5690 	Copy(&server_ip, &s->RemoteIP, sizeof(IP));
5691 
5692 	if (c->Halt)
5693 	{
5694 		// Stop
5695 		c->Err = ERR_USER_CANCEL;
5696 		goto CLEANUP;
5697 	}
5698 
5699 	// [Negotiating]
5700 	c->Session->ClientStatus = CLIENT_STATUS_NEGOTIATION;
5701 
5702 	// Initialize the UDP acceleration function
5703 	if (sess->ClientOption != NULL && sess->ClientOption->NoUdpAcceleration == false)
5704 	{
5705 		if (sess->ClientOption->ProxyType == PROXY_DIRECT)
5706 		{
5707 			if (s->Type == SOCK_TCP)
5708 			{
5709 				if (sess->UdpAccel == NULL)
5710 				{
5711 					bool no_nat_t = false;
5712 
5713 					if (sess->ClientOption->PortUDP != 0)
5714 					{
5715 						// There is no need for NAT-T treatment on my part if the UDP port on the other end is known beforehand
5716 						no_nat_t = true;
5717 					}
5718 
5719 
5720 					sess->UdpAccel = NewUdpAccel(c->Cedar, &s->LocalIP, true, true, no_nat_t);
5721 				}
5722 			}
5723 		}
5724 	}
5725 
5726 	// Send a signature
5727 	Debug("Uploading Signature...\n");
5728 	if (ClientUploadSignature(s) == false)
5729 	{
5730 		c->Err = ERR_DISCONNECTED;
5731 		goto CLEANUP;
5732 	}
5733 
5734 	if (c->Halt)
5735 	{
5736 		// Stop
5737 		c->Err = ERR_USER_CANCEL;
5738 		goto CLEANUP;
5739 	}
5740 
5741 	PrintStatus(sess, _UU("STATUS_5"));
5742 
5743 	// Receive a Hello packet
5744 	Debug("Downloading Hello...\n");
5745 	if (ClientDownloadHello(c, s) == false)
5746 	{
5747 		goto CLEANUP;
5748 	}
5749 
5750 	if (c->Session->ClientOption != NULL && c->Session->ClientOption->FromAdminPack)
5751 	{
5752 		if (IsAdminPackSupportedServerProduct(c->ServerStr) == false)
5753 		{
5754 			c->Err = ERR_NOT_ADMINPACK_SERVER;
5755 			goto CLEANUP;
5756 		}
5757 	}
5758 
5759 	if (c->Halt)
5760 	{
5761 		// Stop
5762 		c->Err = ERR_USER_CANCEL;
5763 		goto CLEANUP;
5764 	}
5765 
5766 	Debug("Server Version : %u\n"
5767 		"Server String  : %s\n"
5768 		"Server Build   : %u\n"
5769 		"Client Version : %u\n"
5770 		"Client String  : %s\n"
5771 		"Client Build   : %u\n",
5772 		c->ServerVer, c->ServerStr, c->ServerBuild,
5773 		c->ClientVer, c->ClientStr, c->ClientBuild);
5774 
5775 	// During user authentication
5776 	c->Session->ClientStatus = CLIENT_STATUS_AUTH;
5777 
5778 	// Verify the server certificate by the client
5779 	if (ClientCheckServerCert(c, &expired) == false)
5780 	{
5781 		if (expired == false)
5782 		{
5783 			c->Err = ERR_CERT_NOT_TRUSTED;
5784 		}
5785 		else
5786 		{
5787 			c->Err = ERR_SERVER_CERT_EXPIRES;
5788 		}
5789 
5790 		if (c->Session->LinkModeClient == false && c->Err == ERR_CERT_NOT_TRUSTED)
5791 		{
5792 			c->Session->ForceStopFlag = true;
5793 		}
5794 
5795 		goto CLEANUP;
5796 	}
5797 
5798 	PrintStatus(sess, _UU("STATUS_6"));
5799 
5800 	// Send the authentication data
5801 	if (ClientUploadAuth(c) == false)
5802 	{
5803 		goto CLEANUP;
5804 	}
5805 
5806 	if (c->Halt)
5807 	{
5808 		// Stop
5809 		c->Err = ERR_USER_CANCEL;
5810 		goto CLEANUP;
5811 	}
5812 
5813 	// Receive a Welcome packet
5814 	p = HttpClientRecv(s);
5815 	if (p == NULL)
5816 	{
5817 		c->Err = ERR_DISCONNECTED;
5818 		goto CLEANUP;
5819 	}
5820 
5821 	// Error checking
5822 	err = GetErrorFromPack(p);
5823 	if (err != 0)
5824 	{
5825 		// An error has occured
5826 		c->Err = err;
5827 		c->ClientConnectError_NoSavePassword = PackGetBool(p, "no_save_password");
5828 		goto CLEANUP;
5829 	}
5830 
5831 	// Branding string check for the connection limit
5832 	{
5833 		char tmp[20];
5834 		char *branded_cfroms = _SS("BRANDED_C_FROM_S");
5835 		PackGetStr(p, "branded_cfroms", tmp, sizeof(tmp));
5836 
5837 		if(StrLen(branded_cfroms) > 0 && StrCmpi(branded_cfroms, tmp) != 0)
5838 		{
5839 			c->Err = ERR_BRANDED_C_FROM_S;
5840 			goto CLEANUP;
5841 		}
5842 	}
5843 
5844 	if (c->Cedar->Server == NULL)
5845 	{
5846 		// Suppress client notification flag
5847 		if (PackIsValueExists(p, "suppress_client_update_notification"))
5848 		{
5849 			bool suppress_client_update_notification = PackGetBool(p, "suppress_client_update_notification");
5850 
5851 #ifdef	OS_WIN32
5852 			MsRegWriteIntEx2(REG_LOCAL_MACHINE, PROTO_SUPPRESS_CLIENT_UPDATE_NOTIFICATION_REGKEY, PROTO_SUPPRESS_CLIENT_UPDATE_NOTIFICATION_REGVALUE,
5853 				(suppress_client_update_notification ? 1 : 0), false, true);
5854 #endif	// OS_WIN32
5855 		}
5856 	}
5857 
5858 	if (true)
5859 	{
5860 		// Message retrieval
5861 		UINT utf_size;
5862 		char *utf;
5863 		wchar_t *msg;
5864 
5865 		utf_size = PackGetDataSize(p, "Msg");
5866 		utf = ZeroMalloc(utf_size + 8);
5867 		PackGetData(p, "Msg", utf);
5868 
5869 		msg = CopyUtfToUni(utf);
5870 
5871 		if (IsEmptyUniStr(msg) == false)
5872 		{
5873 			if (c->Session->Client_Message != NULL)
5874 			{
5875 				Free(c->Session->Client_Message);
5876 			}
5877 
5878 			c->Session->Client_Message = msg;
5879 		}
5880 		else
5881 		{
5882 			Free(msg);
5883 		}
5884 
5885 		Free(utf);
5886 	}
5887 
5888 	if (PackGetInt(p, "Redirect") != 0)
5889 	{
5890 		UINT i;
5891 		UINT ip;
5892 		UINT num_port;
5893 		UINT *ports;
5894 		UINT use_port = 0;
5895 		UINT current_port = c->ServerPort;
5896 		UCHAR ticket[SHA1_SIZE];
5897 		X *server_cert;
5898 		BUF *b;
5899 
5900 		// Redirect mode
5901 		PrintStatus(sess, _UU("STATUS_8"));
5902 
5903 		ip = PackGetIp32(p, "Ip");
5904 		num_port = MAX(MIN(PackGetIndexCount(p, "Port"), MAX_PUBLIC_PORT_NUM), 1);
5905 		ports = ZeroMalloc(sizeof(UINT) * num_port);
5906 		for (i = 0;i < num_port;i++)
5907 		{
5908 			ports[i] = PackGetIntEx(p, "Port", i);
5909 		}
5910 
5911 		// Select a port number
5912 		for (i = 0;i < num_port;i++)
5913 		{
5914 			if (ports[i] == current_port)
5915 			{
5916 				use_port = current_port;
5917 			}
5918 		}
5919 		if (use_port == 0)
5920 		{
5921 			use_port = ports[0];
5922 		}
5923 
5924 		Free(ports);
5925 
5926 		if (PackGetDataSize(p, "Ticket") == SHA1_SIZE)
5927 		{
5928 			PackGetData(p, "Ticket", ticket);
5929 		}
5930 
5931 		b = PackGetBuf(p, "Cert");
5932 		if (b != NULL)
5933 		{
5934 			server_cert = BufToX(b, false);
5935 			FreeBuf(b);
5936 		}
5937 
5938 		if (c->ServerX != NULL)
5939 		{
5940 			FreeX(c->ServerX);
5941 		}
5942 		c->ServerX = server_cert;
5943 
5944 		IPToStr32(c->ServerName, sizeof(c->ServerName), ip);
5945 		c->ServerPort = use_port;
5946 
5947 		c->UseTicket = true;
5948 		Copy(c->Ticket, ticket, SHA1_SIZE);
5949 
5950 		FreePack(p);
5951 
5952 		p = NewPack();
5953 		HttpClientSend(s, p);
5954 		FreePack(p);
5955 
5956 		p = NULL;
5957 
5958 		c->FirstSock = NULL;
5959 		Disconnect(s);
5960 		ReleaseSock(s);
5961 		s = NULL;
5962 
5963 		goto REDIRECTED;
5964 	}
5965 
5966 	PrintStatus(sess, _UU("STATUS_7"));
5967 
5968 	// Parse the Welcome packet
5969 	if (ParseWelcomeFromPack(p, session_name, sizeof(session_name),
5970 		connection_name, sizeof(connection_name), &policy) == false)
5971 	{
5972 		// Parsing failure
5973 		c->Err = ERR_PROTOCOL_ERROR;
5974 		goto CLEANUP;
5975 	}
5976 
5977 	// Get the session key
5978 	if (GetSessionKeyFromPack(p, session_key, &session_key_32) == false)
5979 	{
5980 		// Acquisition failure
5981 		Free(policy);
5982 		policy = NULL;
5983 		c->Err = ERR_PROTOCOL_ERROR;
5984 		goto CLEANUP;
5985 	}
5986 
5987 	Copy(c->Session->SessionKey, session_key, SHA1_SIZE);
5988 	c->Session->SessionKey32 = session_key_32;
5989 
5990 	// Save the contents of the Welcome packet
5991 	Debug("session_name: %s, connection_name: %s\n",
5992 		session_name, connection_name);
5993 
5994 	Lock(c->Session->lock);
5995 	{
5996 		// Deploy and update connection parameters
5997 		sess->EnableUdpRecovery = PackGetBool(p, "enable_udp_recovery");
5998 		c->Session->MaxConnection = PackGetInt(p, "max_connection");
5999 
6000 		if (sess->EnableUdpRecovery == false)
6001 		{
6002 			c->Session->MaxConnection = MIN(c->Session->MaxConnection, c->Session->ClientOption->MaxConnection);
6003 		}
6004 
6005 		c->Session->MaxConnection = MIN(c->Session->MaxConnection, MAX_TCP_CONNECTION);
6006 		c->Session->MaxConnection = MAX(c->Session->MaxConnection, 1);
6007 		c->Session->UseCompress = PackGetInt(p, "use_compress") == 0 ? false : true;
6008 		c->Session->UseEncrypt = PackGetInt(p, "use_encrypt") == 0 ? false : true;
6009 		c->Session->NoSendSignature = PackGetBool(p, "no_send_signature");
6010 		if (c->Session->UseEncrypt)
6011 		{
6012 			c->Session->UseFastRC4 = PackGetInt(p, "use_fast_rc4") == 0 ? false : true;
6013 		}
6014 		c->Session->HalfConnection = PackGetInt(p, "half_connection") == 0 ? false : true;
6015 		c->Session->IsAzureSession = PackGetInt(p, "is_azure_session") == 0 ? false : true;
6016 		c->Session->Timeout = PackGetInt(p, "timeout");
6017 		c->Session->QoS = PackGetInt(p, "qos") == 0 ? false : true;
6018 		if (c->Session->QoS)
6019 		{
6020 			c->Session->MaxConnection = MAX(c->Session->MaxConnection, (UINT)(c->Session->HalfConnection ? 4 : 2));
6021 		}
6022 		c->Session->VLanId = PackGetInt(p, "vlan_id");
6023 
6024 		// R-UDP Session ?
6025 		c->Session->IsRUDPSession = s->IsRUDPSocket;
6026 
6027 		ZeroIP4(&c->Session->AzureRealServerGlobalIp);
6028 
6029 		if (c->Session->IsAzureSession)
6030 		{
6031 			// Disable the life parameter of the connection in the case of VPN Azure relayed session
6032 			c->Session->ClientOption->ConnectionDisconnectSpan = 0;
6033 
6034 			// Get the AzureRealServerGlobalIp the case of VPN Azure relayed
6035 			PackGetIp(p, "azure_real_server_global_ip", &c->Session->AzureRealServerGlobalIp);
6036 		}
6037 
6038 		if (c->Session->IsRUDPSession)
6039 		{
6040 			// Disable the life parameter of the connection in the case of R-UDP session
6041 			c->Session->ClientOption->ConnectionDisconnectSpan = 0;
6042 
6043 			// Disable QoS, etc. in the case of R-UDP session
6044 			c->Session->QoS = false;
6045 			c->Session->HalfConnection = false;
6046 
6047 			if (c->Session->EnableUdpRecovery == false)
6048 			{
6049 				// Set the number of connection to 1 if UDP recovery is not supported
6050 				c->Session->MaxConnection = 1;
6051 			}
6052 		}
6053 
6054 		// Physical communication protocol
6055 		StrCpy(c->Session->UnderlayProtocol, sizeof(c->Session->UnderlayProtocol), s->UnderlayProtocol);
6056 
6057 		AddProtocolDetailsStr(c->Session->ProtocolDetails, sizeof(c->Session->ProtocolDetails), s->ProtocolDetails);
6058 
6059 		if (c->Session->IsAzureSession)
6060 		{
6061 			StrCpy(c->Session->UnderlayProtocol, sizeof(c->Session->UnderlayProtocol), SOCK_UNDERLAY_AZURE);
6062 
6063 			AddProtocolDetailsStr(c->Session->ProtocolDetails, sizeof(c->Session->ProtocolDetails),
6064 				"VPNAzure");
6065 		}
6066 
6067 		if (c->Protocol == CONNECTION_UDP)
6068 		{
6069 			// In the case of UDP protocol, receive the key from the server
6070 			if (PackGetDataSize(p, "udp_send_key") == sizeof(c->Session->UdpSendKey))
6071 			{
6072 				PackGetData(p, "udp_send_key", c->Session->UdpSendKey);
6073 			}
6074 
6075 			if (PackGetDataSize(p, "udp_recv_key") == sizeof(c->Session->UdpRecvKey))
6076 			{
6077 				PackGetData(p, "udp_recv_key", c->Session->UdpRecvKey);
6078 			}
6079 		}
6080 
6081 		if (c->Session->UseFastRC4)
6082 		{
6083 			// Get the RC4 key information
6084 			if (PackGetDataSize(p, "rc4_key_client_to_server") == 16)
6085 			{
6086 				PackGetData(p, "rc4_key_client_to_server", key_pair.ClientToServerKey);
6087 			}
6088 			if (PackGetDataSize(p, "rc4_key_server_to_client") == 16)
6089 			{
6090 				PackGetData(p, "rc4_key_server_to_client", key_pair.ServerToClientKey);
6091 			}
6092 			{
6093 				char key1[64], key2[64];
6094 				BinToStr(key1, sizeof(key1), key_pair.ClientToServerKey, 16);
6095 				BinToStr(key2, sizeof(key2), key_pair.ServerToClientKey, 16);
6096 				Debug(
6097 					"Client to Server Key: %s\n"
6098 					"Server to Client Key: %s\n",
6099 					key1, key2);
6100 			}
6101 		}
6102 
6103 		sess->EnableBulkOnRUDP = false;
6104 		sess->EnableHMacOnBulkOfRUDP = false;
6105 		if (s != NULL && s->IsRUDPSocket && s->BulkRecvKey != NULL && s->BulkSendKey != NULL)
6106 		{
6107 			// Bulk transfer on R-UDP
6108 			sess->EnableHMacOnBulkOfRUDP = PackGetBool(p, "enable_hmac_on_bulk_of_rudp");
6109 			sess->BulkOnRUDPVersion = PackGetInt(p, "rudp_bulk_version");
6110 
6111 			if (PackGetBool(p, "enable_bulk_on_rudp"))
6112 			{
6113 				// Receive the key
6114 				UCHAR key_send[RUDP_BULK_KEY_SIZE_MAX];
6115 				UCHAR key_recv[RUDP_BULK_KEY_SIZE_MAX];
6116 
6117 				UINT key_size = SHA1_SIZE;
6118 
6119 				if (sess->BulkOnRUDPVersion == 2)
6120 				{
6121 					key_size = RUDP_BULK_KEY_SIZE_V2;
6122 				}
6123 
6124 				if (PackGetData2(p, "bulk_on_rudp_send_key", key_send, key_size) &&
6125 					PackGetData2(p, "bulk_on_rudp_recv_key", key_recv, key_size))
6126 				{
6127 					sess->EnableBulkOnRUDP = true;
6128 
6129 					Copy(s->BulkSendKey->Data, key_send, key_size);
6130 					Copy(s->BulkRecvKey->Data, key_recv, key_size);
6131 
6132 					s->BulkSendKey->Size = key_size;
6133 					s->BulkRecvKey->Size = key_size;
6134 
6135 					// Backup R-UDP bulk send/recv keys for additional connections
6136 					Copy(sess->BulkSendKey, s->BulkSendKey->Data, s->BulkSendKey->Size);
6137 					sess->BulkSendKeySize = s->BulkSendKey->Size;
6138 
6139 					Copy(sess->BulkRecvKey, s->BulkRecvKey->Data, s->BulkRecvKey->Size);
6140 					sess->BulkRecvKeySize = s->BulkRecvKey->Size;
6141 
6142 					if (false)
6143 					{
6144 						char tmp1[128];
6145 						char tmp2[128];
6146 						BinToStr(tmp1, sizeof(tmp1), sess->BulkRecvKey, sess->BulkSendKeySize);
6147 						BinToStr(tmp2, sizeof(tmp2), sess->BulkSendKey, sess->BulkRecvKeySize);
6148 						Debug("Backup: sess->BulkRecvKeySize = %u, sess->BulkSendKeySize = %u\n",
6149 							sess->BulkRecvKeySize, sess->BulkSendKeySize);
6150 						Debug("Backup:\n%s\n%s\n\n", tmp1, tmp2);
6151 					}
6152 
6153 					AddProtocolDetailsKeyValueInt(sess->ProtocolDetails, sizeof(sess->ProtocolDetails),
6154 						"RUDP_Bulk_Ver",
6155 						sess->BulkOnRUDPVersion);
6156 				}
6157 			}
6158 		}
6159 
6160 		Debug("EnableBulkOnRUDP = %u\n", sess->EnableBulkOnRUDP);
6161 		Debug("EnableHMacOnBulkOfRUDP = %u\n", sess->EnableHMacOnBulkOfRUDP);
6162 		Debug("EnableUdpRecovery = %u\n", sess->EnableUdpRecovery);
6163 		Debug("BulkOnRUDPVersion = %u\n", sess->BulkOnRUDPVersion);
6164 
6165 		sess->UseUdpAcceleration = false;
6166 		sess->IsUsingUdpAcceleration = false;
6167 		sess->UseHMacOnUdpAcceleration = false;
6168 
6169 		if (sess->UdpAccel != NULL)
6170 		{
6171 			sess->UdpAccel->UseHMac = false;
6172 
6173 			sess->UdpAccelFastDisconnectDetect = false;
6174 
6175 			if (PackGetBool(p, "use_udp_acceleration"))
6176 			{
6177 				UINT udp_acceleration_version = PackGetInt(p, "udp_acceleration_version");
6178 				IP udp_acceleration_server_ip;
6179 
6180 				if (udp_acceleration_version == 0)
6181 				{
6182 					udp_acceleration_version = 1;
6183 				}
6184 
6185 				sess->UdpAccelFastDisconnectDetect = PackGetBool(p, "udp_accel_fast_disconnect_detect");
6186 
6187 				if (PackGetIp(p, "udp_acceleration_server_ip", &udp_acceleration_server_ip))
6188 				{
6189 					UINT udp_acceleration_server_port = PackGetInt(p, "udp_acceleration_server_port");
6190 
6191 					if (IsZeroIp(&udp_acceleration_server_ip))
6192 					{
6193 						Copy(&udp_acceleration_server_ip, &s->RemoteIP, sizeof(IP));
6194 					}
6195 
6196 					if (udp_acceleration_server_port != 0)
6197 					{
6198 						UCHAR udp_acceleration_server_key[UDP_ACCELERATION_COMMON_KEY_SIZE_V1];
6199 						UCHAR udp_acceleration_server_key_v2[UDP_ACCELERATION_COMMON_KEY_SIZE_V2];
6200 						UINT server_cookie = PackGetInt(p, "udp_acceleration_server_cookie");
6201 						UINT client_cookie = PackGetInt(p, "udp_acceleration_client_cookie");
6202 						bool encryption = PackGetBool(p, "udp_acceleration_use_encryption");
6203 
6204 						Zero(udp_acceleration_server_key, sizeof(udp_acceleration_server_key));
6205 						Zero(udp_acceleration_server_key_v2, sizeof(udp_acceleration_server_key_v2));
6206 
6207 						PackGetData2(p, "udp_acceleration_server_key", udp_acceleration_server_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1);
6208 						PackGetData2(p, "udp_acceleration_server_key_v2", udp_acceleration_server_key_v2, UDP_ACCELERATION_COMMON_KEY_SIZE_V2);
6209 
6210 						if (server_cookie != 0 && client_cookie != 0)
6211 						{
6212 							IP remote_ip;
6213 
6214 							Copy(&remote_ip, &s->RemoteIP, sizeof(IP));
6215 
6216 							if (IsZeroIp(&c->Session->AzureRealServerGlobalIp) == false)
6217 							{
6218 								Copy(&remote_ip, &c->Session->AzureRealServerGlobalIp, sizeof(IP));
6219 							}
6220 
6221 							sess->UdpAccel->Version = 1;
6222 							if (udp_acceleration_version == 2)
6223 							{
6224 								sess->UdpAccel->Version = 2;
6225 							}
6226 
6227 							if (UdpAccelInitClient(sess->UdpAccel,
6228 								sess->UdpAccel->Version == 2 ? udp_acceleration_server_key_v2 : udp_acceleration_server_key,
6229 								&udp_acceleration_server_ip, udp_acceleration_server_port,
6230 								server_cookie, client_cookie, &remote_ip) == false)
6231 							{
6232 								Debug("UdpAccelInitClient failed.\n");
6233 							}
6234 							else
6235 							{
6236 								sess->UseUdpAcceleration = true;
6237 
6238 								sess->UdpAccel->FastDetect = sess->UdpAccelFastDisconnectDetect;
6239 
6240 								sess->UdpAccel->PlainTextMode = !encryption;
6241 
6242 								sess->UseHMacOnUdpAcceleration = PackGetBool(p, "use_hmac_on_udp_acceleration");
6243 
6244 								if (sess->UseHMacOnUdpAcceleration)
6245 								{
6246 									sess->UdpAccel->UseHMac = true;
6247 								}
6248 
6249 								AddProtocolDetailsKeyValueInt(sess->ProtocolDetails, sizeof(sess->ProtocolDetails),
6250 									"UDPAccel_Ver",
6251 									sess->UdpAccel->Version);
6252 
6253 								if (sess->UdpAccel->Version >= 2)
6254 								{
6255 									AddProtocolDetailsStr(sess->ProtocolDetails, sizeof(sess->ProtocolDetails),
6256 										Aead_ChaCha20Poly1305_Ietf_IsOpenSSL() ?
6257 										"ChachaPoly_OpenSSL" : "ChachaPoly_Self");
6258 								}
6259 
6260 								AddProtocolDetailsKeyValueInt(sess->ProtocolDetails, sizeof(sess->ProtocolDetails),
6261 									"UDPAccel_MSS",
6262 									UdpAccelCalcMss(sess->UdpAccel));
6263 							}
6264 						}
6265 					}
6266 				}
6267 			}
6268 		}
6269 	}
6270 	Unlock(c->Session->lock);
6271 
6272 	Debug("UseUdpAcceleration = %u\n", sess->UseUdpAcceleration);
6273 
6274 	if (sess->UseUdpAcceleration == false)
6275 	{
6276 		if (sess->UdpAccel != NULL)
6277 		{
6278 			FreeUdpAccel(sess->UdpAccel);
6279 			sess->UdpAccel = NULL;
6280 		}
6281 	}
6282 
6283 	Lock(c->lock);
6284 	{
6285 		if (c->Name != NULL)
6286 		{
6287 			Free(c->Name);
6288 		}
6289 		c->Name = CopyStr(connection_name);
6290 
6291 		// Save the name of a cryptographic algorithm
6292 		if (c->CipherName != NULL)
6293 		{
6294 			Free(c->CipherName);
6295 		}
6296 
6297 		c->CipherName = CopyStr(c->FirstSock->CipherName);
6298 	}
6299 	Unlock(c->lock);
6300 
6301 	Lock(c->Session->lock);
6302 	{
6303 		if (c->Session->Name != NULL)
6304 		{
6305 			Free(c->Session->Name);
6306 		}
6307 		c->Session->Name = CopyStr(session_name);
6308 
6309 		c->Session->Policy = policy;
6310 	}
6311 	Unlock(c->Session->lock);
6312 
6313 	// Discard the Welcome packet
6314 	FreePack(p);
6315 	p = NULL;
6316 
6317 
6318 	// Connection establishment
6319 	c->Session->ClientStatus = CLIENT_STATUS_ESTABLISHED;
6320 
6321 	// Save the server certificate
6322 	if (c->ServerX == NULL)
6323 	{
6324 		c->ServerX = CloneX(c->FirstSock->RemoteX);
6325 	}
6326 
6327 	PrintStatus(sess, _UU("STATUS_9"));
6328 
6329 	// Shift the connection to the tunneling mode
6330 	StartTunnelingMode(c);
6331 	s = NULL;
6332 
6333 	if (c->Session->HalfConnection)
6334 	{
6335 		// Processing in the case of half-connection
6336 		TCPSOCK *ts = (TCPSOCK *)LIST_DATA(c->Tcp->TcpSockList, 0);
6337 		ts->Direction = TCP_CLIENT_TO_SERVER;
6338 	}
6339 
6340 	if (c->Session->UseFastRC4)
6341 	{
6342 		// Set the high-speed RC4 encryption key
6343 		TCPSOCK *ts = (TCPSOCK *)LIST_DATA(c->Tcp->TcpSockList, 0);
6344 		Copy(&ts->Rc4KeyPair, &key_pair, sizeof(key_pair));
6345 
6346 		InitTcpSockRc4Key(ts, false);
6347 	}
6348 
6349 	// SSL encryption flag
6350 	if (c->Session->UseEncrypt && c->Session->UseFastRC4 == false)
6351 	{
6352 		c->Session->UseSSLDataEncryption = true;
6353 	}
6354 	else
6355 	{
6356 		c->Session->UseSSLDataEncryption = false;
6357 	}
6358 
6359 	PrintStatus(sess, L"free");
6360 
6361 	CLog(c->Cedar->Client, "LC_CONNECT_2", c->Session->ClientOption->AccountName,
6362 		session_name);
6363 
6364 	if (c->Session->LinkModeClient && c->Session->Link != NULL)
6365 	{
6366 		HLog(c->Session->Link->Hub, "LH_CONNECT_2", c->Session->ClientOption->AccountName, session_name);
6367 	}
6368 
6369 	// Main routine of the session
6370 	SessionMain(c->Session);
6371 
6372 	ok = true;
6373 
6374 	if (c->Err == ERR_USER_CANCEL)
6375 	{
6376 		ret = true;
6377 	}
6378 
6379 CLEANUP:
6380 	c->FirstSock = NULL;
6381 
6382 	if (sess->UdpAccel != NULL)
6383 	{
6384 		FreeUdpAccel(sess->UdpAccel);
6385 		sess->UdpAccel = NULL;
6386 	}
6387 
6388 	if (p != NULL)
6389 	{
6390 		FreePack(p);
6391 	}
6392 
6393 	Disconnect(s);
6394 	ReleaseSock(s);
6395 
6396 	Debug("Error: %u\n", c->Err);
6397 
6398 	if (ok == false)
6399 	{
6400 		PrintStatus(sess, L"free");
6401 	}
6402 
6403 	return ret;
6404 }
6405 
6406 // Parse the Welcome packet
ParseWelcomeFromPack(PACK * p,char * session_name,UINT session_name_size,char * connection_name,UINT connection_name_size,POLICY ** policy)6407 bool ParseWelcomeFromPack(PACK *p, char *session_name, UINT session_name_size,
6408 						  char *connection_name, UINT connection_name_size,
6409 						  POLICY **policy)
6410 {
6411 	// Validate arguments
6412 	if (p == NULL || session_name == NULL || connection_name == NULL || policy == NULL)
6413 	{
6414 		return false;
6415 	}
6416 
6417 	// Session name
6418 	if (PackGetStr(p, "session_name", session_name, session_name_size) == false)
6419 	{
6420 		return false;
6421 	}
6422 
6423 	// Connection name
6424 	if (PackGetStr(p, "connection_name", connection_name, connection_name_size) == false)
6425 	{
6426 		return false;
6427 	}
6428 
6429 	// Policy
6430 	*policy = PackGetPolicy(p);
6431 	if (*policy == NULL)
6432 	{
6433 		return false;
6434 	}
6435 
6436 	return true;
6437 }
6438 
6439 // Generate the Welcome packet
PackWelcome(SESSION * s)6440 PACK *PackWelcome(SESSION *s)
6441 {
6442 	PACK *p;
6443 	// Validate arguments
6444 	if (s == NULL)
6445 	{
6446 		return NULL;
6447 	}
6448 
6449 	p = NewPack();
6450 
6451 	// Session name
6452 	PackAddStr(p, "session_name", s->Name);
6453 
6454 	// Connection name
6455 	PackAddStr(p, "connection_name", s->Connection->Name);
6456 
6457 	// Parameters
6458 	PackAddInt(p, "max_connection", s->MaxConnection);
6459 	PackAddInt(p, "use_encrypt", s->UseEncrypt == false ? 0 : 1);
6460 	PackAddInt(p, "use_fast_rc4", s->UseFastRC4 == false ? 0 : 1);
6461 	PackAddInt(p, "use_compress", s->UseCompress == false ? 0 : 1);
6462 	PackAddInt(p, "half_connection", s->HalfConnection == false ? 0 : 1);
6463 	PackAddInt(p, "timeout", s->Timeout);
6464 	PackAddInt(p, "qos", s->QoS ? 1 : 0);
6465 	PackAddInt(p, "is_azure_session", s->IsAzureSession);
6466 
6467 	// Session key
6468 	PackAddData(p, "session_key", s->SessionKey, SHA1_SIZE);
6469 	PackAddInt(p, "session_key_32", s->SessionKey32);
6470 
6471 	// Policy
6472 	PackAddPolicy(p, s->Policy);
6473 
6474 	// VLAN ID
6475 	PackAddInt(p, "vlan_id", s->VLanId);
6476 
6477 	if (s->Connection->Protocol == CONNECTION_UDP)
6478 	{
6479 		// In the case of UDP protocol, generate 2 pairs of key
6480 		Rand(s->UdpSendKey, sizeof(s->UdpSendKey));
6481 		Rand(s->UdpRecvKey, sizeof(s->UdpRecvKey));
6482 
6483 		// Send to client by exchanging 2 keys
6484 		PackAddData(p, "udp_send_key", s->UdpRecvKey, sizeof(s->UdpRecvKey));
6485 		PackAddData(p, "udp_recv_key", s->UdpSendKey, sizeof(s->UdpSendKey));
6486 	}
6487 
6488 	// no_send_signature
6489 	if (s->NoSendSignature)
6490 	{
6491 		PackAddBool(p, "no_send_signature", true);
6492 	}
6493 
6494 	if (s->InProcMode)
6495 	{
6496 		// MAC address for IPC
6497 		PackAddData(p, "IpcMacAddress", s->IpcMacAddress, 6);
6498 
6499 		// Virtual HUB name
6500 		PackAddStr(p, "IpcHubName", s->Hub->Name);
6501 
6502 		// Shared Buffer
6503 		s->IpcSessionSharedBuffer = NewSharedBuffer(NULL, sizeof(IPC_SESSION_SHARED_BUFFER_DATA));
6504 		AddRef(s->IpcSessionSharedBuffer->Ref);
6505 
6506 		s->IpcSessionShared = s->IpcSessionSharedBuffer->Data;
6507 
6508 		PackAddInt64(p, "IpcSessionSharedBuffer", (UINT64)s->IpcSessionSharedBuffer);
6509 	}
6510 
6511 	if (s->UdpAccel != NULL)
6512 	{
6513 		// UDP acceleration function
6514 		PackAddBool(p, "use_udp_acceleration", true);
6515 		PackAddInt(p, "udp_acceleration_version", s->UdpAccel->Version);
6516 		PackAddIp(p, "udp_acceleration_server_ip", &s->UdpAccel->MyIp);
6517 		PackAddInt(p, "udp_acceleration_server_port", s->UdpAccel->MyPort);
6518 		PackAddData(p, "udp_acceleration_server_key", s->UdpAccel->MyKey, UDP_ACCELERATION_COMMON_KEY_SIZE_V1);
6519 		PackAddData(p, "udp_acceleration_server_key_v2", s->UdpAccel->MyKey_V2, UDP_ACCELERATION_COMMON_KEY_SIZE_V2);
6520 		PackAddInt(p, "udp_acceleration_server_cookie", s->UdpAccel->MyCookie);
6521 		PackAddInt(p, "udp_acceleration_client_cookie", s->UdpAccel->YourCookie);
6522 		PackAddBool(p, "udp_acceleration_use_encryption", !s->UdpAccel->PlainTextMode);
6523 		PackAddBool(p, "use_hmac_on_udp_acceleration", s->UdpAccel->UseHMac);
6524 		PackAddBool(p, "udp_accel_fast_disconnect_detect", s->UdpAccelFastDisconnectDetect);
6525 	}
6526 
6527 	if (s->EnableBulkOnRUDP)
6528 	{
6529 		// Allow bulk transfer on R-UDP
6530 		PackAddBool(p, "enable_bulk_on_rudp", true);
6531 		PackAddBool(p, "enable_hmac_on_bulk_of_rudp", s->EnableHMacOnBulkOfRUDP);
6532 		PackAddInt(p, "rudp_bulk_version", s->BulkOnRUDPVersion);
6533 
6534 		if (s->BulkOnRUDPVersion == 2)
6535 		{
6536 			PackAddData(p, "bulk_on_rudp_send_key", s->Connection->FirstSock->BulkRecvKey->Data, RUDP_BULK_KEY_SIZE_V2);
6537 			s->Connection->FirstSock->BulkRecvKey->Size = RUDP_BULK_KEY_SIZE_V2;
6538 
6539 			PackAddData(p, "bulk_on_rudp_recv_key", s->Connection->FirstSock->BulkSendKey->Data, RUDP_BULK_KEY_SIZE_V2);
6540 			s->Connection->FirstSock->BulkSendKey->Size = RUDP_BULK_KEY_SIZE_V2;
6541 		}
6542 		else
6543 		{
6544 			PackAddData(p, "bulk_on_rudp_send_key", s->Connection->FirstSock->BulkRecvKey->Data, SHA1_SIZE);
6545 			s->Connection->FirstSock->BulkRecvKey->Size = SHA1_SIZE;
6546 
6547 			PackAddData(p, "bulk_on_rudp_recv_key", s->Connection->FirstSock->BulkSendKey->Data, SHA1_SIZE);
6548 			s->Connection->FirstSock->BulkSendKey->Size = SHA1_SIZE;
6549 		}
6550 
6551 		// Backup R-UDP bulk send/recv keys for additional connections
6552 		Copy(s->BulkSendKey, s->Connection->FirstSock->BulkSendKey->Data,
6553 			s->Connection->FirstSock->BulkSendKey->Size);
6554 
6555 		s->BulkSendKeySize = s->Connection->FirstSock->BulkSendKey->Size;
6556 
6557 		Copy(s->BulkRecvKey, s->Connection->FirstSock->BulkRecvKey->Data,
6558 			s->Connection->FirstSock->BulkRecvKey->Size);
6559 
6560 		s->BulkRecvKeySize = s->Connection->FirstSock->BulkRecvKey->Size;
6561 
6562 		if (false)
6563 		{
6564 			char tmp1[128];
6565 			char tmp2[128];
6566 			BinToStr(tmp1, sizeof(tmp1), s->BulkRecvKey, s->BulkSendKeySize);
6567 			BinToStr(tmp2, sizeof(tmp2), s->BulkSendKey, s->BulkRecvKeySize);
6568 			Debug("Backup: s->BulkRecvKeySize = %u, s->BulkSendKeySize = %u\n",
6569 				s->BulkRecvKeySize, s->BulkSendKeySize);
6570 			Debug("Backup:\n%s\n%s\n\n", tmp1, tmp2);
6571 		}
6572 	}
6573 
6574 	if (s->IsAzureSession)
6575 	{
6576 		if (s->Connection != NULL && s->Connection->FirstSock != NULL)
6577 		{
6578 			SOCK *sock = s->Connection->FirstSock;
6579 
6580 			PackAddIp(p, "azure_real_server_global_ip", &sock->Reverse_MyServerGlobalIp);
6581 		}
6582 	}
6583 
6584 	PackAddBool(p, "enable_udp_recovery", s->EnableUdpRecovery);
6585 
6586 	return p;
6587 }
6588 
6589 #define	PACK_ADD_POLICY_BOOL(name, value)	\
6590 	PackAddBool(p, "policy:" name, y->value == false ? 0 : 1)
6591 #define	PACK_ADD_POLICY_UINT(name, value)	\
6592 	PackAddInt(p, "policy:" name, y->value)
6593 #define	PACK_GET_POLICY_BOOL(name, value)	\
6594 	y->value = (PackGetBool(p, "policy:" name))
6595 #define	PACK_GET_POLICY_UINT(name, value)	\
6596 	y->value = PackGetInt(p, "policy:" name)
6597 
6598 // Get a PACK from the session key
GetSessionKeyFromPack(PACK * p,UCHAR * session_key,UINT * session_key_32)6599 bool GetSessionKeyFromPack(PACK *p, UCHAR *session_key, UINT *session_key_32)
6600 {
6601 	// Validate arguments
6602 	if (p == NULL || session_key == NULL || session_key_32 == NULL)
6603 	{
6604 		return false;
6605 	}
6606 
6607 	if (PackGetDataSize(p, "session_key") != SHA1_SIZE)
6608 	{
6609 		return false;
6610 	}
6611 	if (PackGetData(p, "session_key", session_key) == false)
6612 	{
6613 		return false;
6614 	}
6615 	*session_key_32 = PackGetInt(p, "session_key_32");
6616 
6617 	return true;
6618 }
6619 
6620 // Get the policy from the PACK
PackGetPolicy(PACK * p)6621 POLICY *PackGetPolicy(PACK *p)
6622 {
6623 	POLICY *y;
6624 	// Validate arguments
6625 	if (p == NULL)
6626 	{
6627 		return NULL;
6628 	}
6629 
6630 	y = ZeroMalloc(sizeof(POLICY));
6631 
6632 	// Bool value
6633 	// Ver 2
6634 	PACK_GET_POLICY_BOOL("Access", Access);
6635 	PACK_GET_POLICY_BOOL("DHCPFilter", DHCPFilter);
6636 	PACK_GET_POLICY_BOOL("DHCPNoServer", DHCPNoServer);
6637 	PACK_GET_POLICY_BOOL("DHCPForce", DHCPForce);
6638 	PACK_GET_POLICY_BOOL("NoBridge", NoBridge);
6639 	PACK_GET_POLICY_BOOL("NoRouting", NoRouting);
6640 	PACK_GET_POLICY_BOOL("PrivacyFilter", PrivacyFilter);
6641 	PACK_GET_POLICY_BOOL("NoServer", NoServer);
6642 	PACK_GET_POLICY_BOOL("CheckMac", CheckMac);
6643 	PACK_GET_POLICY_BOOL("CheckIP", CheckIP);
6644 	PACK_GET_POLICY_BOOL("ArpDhcpOnly", ArpDhcpOnly);
6645 	PACK_GET_POLICY_BOOL("MonitorPort", MonitorPort);
6646 	PACK_GET_POLICY_BOOL("NoBroadcastLimiter", NoBroadcastLimiter);
6647 	PACK_GET_POLICY_BOOL("FixPassword", FixPassword);
6648 	PACK_GET_POLICY_BOOL("NoQoS", NoQoS);
6649 	// Ver 3
6650 	PACK_GET_POLICY_BOOL("RSandRAFilter", RSandRAFilter);
6651 	PACK_GET_POLICY_BOOL("RAFilter", RAFilter);
6652 	PACK_GET_POLICY_BOOL("DHCPv6Filter", DHCPv6Filter);
6653 	PACK_GET_POLICY_BOOL("DHCPv6NoServer", DHCPv6NoServer);
6654 	PACK_GET_POLICY_BOOL("NoRoutingV6", NoRoutingV6);
6655 	PACK_GET_POLICY_BOOL("CheckIPv6", CheckIPv6);
6656 	PACK_GET_POLICY_BOOL("NoServerV6", NoServerV6);
6657 	PACK_GET_POLICY_BOOL("NoSavePassword", NoSavePassword);
6658 	PACK_GET_POLICY_BOOL("FilterIPv4", FilterIPv4);
6659 	PACK_GET_POLICY_BOOL("FilterIPv6", FilterIPv6);
6660 	PACK_GET_POLICY_BOOL("FilterNonIP", FilterNonIP);
6661 	PACK_GET_POLICY_BOOL("NoIPv6DefaultRouterInRA", NoIPv6DefaultRouterInRA);
6662 	PACK_GET_POLICY_BOOL("NoIPv6DefaultRouterInRAWhenIPv6", NoIPv6DefaultRouterInRAWhenIPv6);
6663 
6664 	// UINT value
6665 	// Ver 2
6666 	PACK_GET_POLICY_UINT("MaxConnection", MaxConnection);
6667 	PACK_GET_POLICY_UINT("TimeOut", TimeOut);
6668 	PACK_GET_POLICY_UINT("MaxMac", MaxMac);
6669 	PACK_GET_POLICY_UINT("MaxIP", MaxIP);
6670 	PACK_GET_POLICY_UINT("MaxUpload", MaxUpload);
6671 	PACK_GET_POLICY_UINT("MaxDownload", MaxDownload);
6672 	PACK_GET_POLICY_UINT("MultiLogins", MultiLogins);
6673 	// Ver 3
6674 	PACK_GET_POLICY_UINT("MaxIPv6", MaxIPv6);
6675 	PACK_GET_POLICY_UINT("AutoDisconnect", AutoDisconnect);
6676 	PACK_GET_POLICY_UINT("VLanId", VLanId);
6677 
6678 	// Ver 3 flag
6679 	PACK_GET_POLICY_BOOL("Ver3", Ver3);
6680 
6681 	return y;
6682 }
6683 
6684 // Insert the policy into the PACK
PackAddPolicy(PACK * p,POLICY * y)6685 void PackAddPolicy(PACK *p, POLICY *y)
6686 {
6687 	// Validate arguments
6688 	if (p == NULL || y == NULL)
6689 	{
6690 		return;
6691 	}
6692 
6693 	// Bool value
6694 	// Ver 2
6695 	PACK_ADD_POLICY_BOOL("Access", Access);
6696 	PACK_ADD_POLICY_BOOL("DHCPFilter", DHCPFilter);
6697 	PACK_ADD_POLICY_BOOL("DHCPNoServer", DHCPNoServer);
6698 	PACK_ADD_POLICY_BOOL("DHCPForce", DHCPForce);
6699 	PACK_ADD_POLICY_BOOL("NoBridge", NoBridge);
6700 	PACK_ADD_POLICY_BOOL("NoRouting", NoRouting);
6701 	PACK_ADD_POLICY_BOOL("PrivacyFilter", PrivacyFilter);
6702 	PACK_ADD_POLICY_BOOL("NoServer", NoServer);
6703 	PACK_ADD_POLICY_BOOL("CheckMac", CheckMac);
6704 	PACK_ADD_POLICY_BOOL("CheckIP", CheckIP);
6705 	PACK_ADD_POLICY_BOOL("ArpDhcpOnly", ArpDhcpOnly);
6706 	PACK_ADD_POLICY_BOOL("MonitorPort", MonitorPort);
6707 	PACK_ADD_POLICY_BOOL("NoBroadcastLimiter", NoBroadcastLimiter);
6708 	PACK_ADD_POLICY_BOOL("FixPassword", FixPassword);
6709 	PACK_ADD_POLICY_BOOL("NoQoS", NoQoS);
6710 	// Ver 3
6711 	PACK_ADD_POLICY_BOOL("RSandRAFilter", RSandRAFilter);
6712 	PACK_ADD_POLICY_BOOL("RAFilter", RAFilter);
6713 	PACK_ADD_POLICY_BOOL("DHCPv6Filter", DHCPv6Filter);
6714 	PACK_ADD_POLICY_BOOL("DHCPv6NoServer", DHCPv6NoServer);
6715 	PACK_ADD_POLICY_BOOL("NoRoutingV6", NoRoutingV6);
6716 	PACK_ADD_POLICY_BOOL("CheckIPv6", CheckIPv6);
6717 	PACK_ADD_POLICY_BOOL("NoServerV6", NoServerV6);
6718 	PACK_ADD_POLICY_BOOL("NoSavePassword", NoSavePassword);
6719 	PACK_ADD_POLICY_BOOL("FilterIPv4", FilterIPv4);
6720 	PACK_ADD_POLICY_BOOL("FilterIPv6", FilterIPv6);
6721 	PACK_ADD_POLICY_BOOL("FilterNonIP", FilterNonIP);
6722 	PACK_ADD_POLICY_BOOL("NoIPv6DefaultRouterInRA", NoIPv6DefaultRouterInRA);
6723 	PACK_ADD_POLICY_BOOL("NoIPv6DefaultRouterInRAWhenIPv6", NoIPv6DefaultRouterInRAWhenIPv6);
6724 
6725 	// UINT value
6726 	// Ver 2
6727 	PACK_ADD_POLICY_UINT("MaxConnection", MaxConnection);
6728 	PACK_ADD_POLICY_UINT("TimeOut", TimeOut);
6729 	PACK_ADD_POLICY_UINT("MaxMac", MaxMac);
6730 	PACK_ADD_POLICY_UINT("MaxIP", MaxIP);
6731 	PACK_ADD_POLICY_UINT("MaxUpload", MaxUpload);
6732 	PACK_ADD_POLICY_UINT("MaxDownload", MaxDownload);
6733 	PACK_ADD_POLICY_UINT("MultiLogins", MultiLogins);
6734 	// Ver 3
6735 	PACK_ADD_POLICY_UINT("MaxIPv6", MaxIPv6);
6736 	PACK_ADD_POLICY_UINT("AutoDisconnect", AutoDisconnect);
6737 	PACK_ADD_POLICY_UINT("VLanId", VLanId);
6738 
6739 	// Ver 3 flag
6740 	PackAddBool(p, "policy:Ver3", true);
6741 }
6742 
6743 // Upload the authentication data for the additional connection
ClientUploadAuth2(CONNECTION * c,SOCK * s)6744 bool ClientUploadAuth2(CONNECTION *c, SOCK *s)
6745 {
6746 	PACK *p = NULL;
6747 	// Validate arguments
6748 	if (c == NULL)
6749 	{
6750 		return false;
6751 	}
6752 
6753 	p = PackAdditionalConnect(c->Session->SessionKey);
6754 
6755 	PackAddClientVersion(p, c);
6756 
6757 	if (HttpClientSend(s, p) == false)
6758 	{
6759 		FreePack(p);
6760 		return false;
6761 	}
6762 	FreePack(p);
6763 
6764 	return true;
6765 }
6766 
6767 // Send a NOOP
ClientUploadNoop(CONNECTION * c)6768 void ClientUploadNoop(CONNECTION *c)
6769 {
6770 	PACK *p;
6771 	// Validate arguments
6772 	if (c == NULL)
6773 	{
6774 		return;
6775 	}
6776 
6777 	p = PackError(0);
6778 	PackAddInt(p, "noop", 1);
6779 	HttpClientSend(c->FirstSock, p);
6780 	FreePack(p);
6781 
6782 	p = HttpClientRecv(c->FirstSock);
6783 	if (p != NULL)
6784 	{
6785 		FreePack(p);
6786 	}
6787 }
6788 
6789 // Add client version information to the PACK
PackAddClientVersion(PACK * p,CONNECTION * c)6790 void PackAddClientVersion(PACK *p, CONNECTION *c)
6791 {
6792 	// Validate arguments
6793 	if (p == NULL || c == NULL)
6794 	{
6795 		return;
6796 	}
6797 
6798 	PackAddStr(p, "client_str", c->ClientStr);
6799 	PackAddInt(p, "client_ver", c->ClientVer);
6800 	PackAddInt(p, "client_build", c->ClientBuild);
6801 }
6802 
6803 // Upload the certificate data for the new connection
ClientUploadAuth(CONNECTION * c)6804 bool ClientUploadAuth(CONNECTION *c)
6805 {
6806 	PACK *p = NULL;
6807 	CLIENT_AUTH *a;
6808 	CLIENT_OPTION *o;
6809 	X *x;
6810 	bool ret;
6811 	NODE_INFO info;
6812 	UCHAR secure_password[SHA1_SIZE];
6813 	UCHAR sign[4096 / 8];
6814 	UCHAR unique[SHA1_SIZE];
6815 	RPC_WINVER v;
6816 	// Validate arguments
6817 	if (c == NULL)
6818 	{
6819 		return false;
6820 	}
6821 
6822 	Zero(sign, sizeof(sign));
6823 
6824 	a = c->Session->ClientAuth;
6825 	o = c->Session->ClientOption;
6826 
6827 	if (c->UseTicket == false)
6828 	{
6829 		switch (a->AuthType)
6830 		{
6831 		case CLIENT_AUTHTYPE_ANONYMOUS:
6832 			// Anonymous authentication
6833 			p = PackLoginWithAnonymous(o->HubName, a->Username);
6834 			break;
6835 
6836 		case CLIENT_AUTHTYPE_PASSWORD:
6837 			// Password authentication
6838 			SecurePassword(secure_password, a->HashedPassword, c->Random);
6839 			p = PackLoginWithPassword(o->HubName, a->Username, secure_password);
6840 			break;
6841 
6842 		case CLIENT_AUTHTYPE_PLAIN_PASSWORD:
6843 			// Plaintext password authentication
6844 			p = PackLoginWithPlainPassword(o->HubName, a->Username, a->PlainPassword);
6845 			break;
6846 
6847 		case CLIENT_AUTHTYPE_CERT:
6848 			// Certificate authentication
6849 			if (a->ClientX != NULL && a->ClientX->is_compatible_bit &&
6850 				a->ClientX->bits != 0 && (a->ClientX->bits / 8) <= sizeof(sign))
6851 			{
6852 				if (RsaSignEx(sign, c->Random, SHA1_SIZE, a->ClientK, a->ClientX->bits))
6853 				{
6854 					p = PackLoginWithCert(o->HubName, a->Username, a->ClientX, sign, a->ClientX->bits / 8);
6855 					c->ClientX = CloneX(a->ClientX);
6856 				}
6857 			}
6858 			break;
6859 
6860 		case CLIENT_AUTHTYPE_SECURE:
6861 			// Authentication by secure device
6862 			if (ClientSecureSign(c, sign, c->Random, &x))
6863 			{
6864 				p = PackLoginWithCert(o->HubName, a->Username, x, sign, x->bits / 8);
6865 				c->ClientX = CloneX(x);
6866 				FreeX(x);
6867 			}
6868 			else
6869 			{
6870 				c->Err = ERR_SECURE_DEVICE_OPEN_FAILED;
6871 				c->Session->ForceStopFlag = true;
6872 			}
6873 			break;
6874 		}
6875 	}
6876 	else
6877 	{
6878 		// Ticket
6879 		p = NewPack();
6880 		PackAddStr(p, "method", "login");
6881 		PackAddStr(p, "hubname", o->HubName);
6882 		PackAddStr(p, "username", a->Username);
6883 		PackAddInt(p, "authtype", AUTHTYPE_TICKET);
6884 		PackAddData(p, "ticket", c->Ticket, SHA1_SIZE);
6885 	}
6886 
6887 	if (p == NULL)
6888 	{
6889 		// Error
6890 		if (c->Err != ERR_SECURE_DEVICE_OPEN_FAILED)
6891 		{
6892 			c->Err = ERR_PROTOCOL_ERROR;
6893 		}
6894 		return false;
6895 	}
6896 
6897 	PackAddClientVersion(p, c);
6898 
6899 	// Protocol
6900 	PackAddInt(p, "protocol", c->Protocol);
6901 
6902 	// Version, etc.
6903 	PackAddStr(p, "hello", c->ClientStr);
6904 	PackAddInt(p, "version", c->ClientVer);
6905 	PackAddInt(p, "build", c->ClientBuild);
6906 	PackAddInt(p, "client_id", c->Cedar->ClientId);
6907 
6908 	// The maximum number of connections
6909 	PackAddInt(p, "max_connection", o->MaxConnection);
6910 	// Flag to use of cryptography
6911 	PackAddInt(p, "use_encrypt", o->UseEncrypt == false ? 0 : 1);
6912 	// Fast encryption using flag
6913 	//	PackAddInt(p, "use_fast_rc4", o->UseFastRC4 == false ? 0 : 1);
6914 	// Data compression flag
6915 	PackAddInt(p, "use_compress", o->UseCompress == false ? 0 : 1);
6916 	// Half connection flag
6917 	PackAddInt(p, "half_connection", o->HalfConnection == false ? 0 : 1);
6918 
6919 	// Bridge / routing mode flag
6920 	PackAddBool(p, "require_bridge_routing_mode", o->RequireBridgeRoutingMode);
6921 
6922 	// Monitor mode flag
6923 	PackAddBool(p, "require_monitor_mode", o->RequireMonitorMode);
6924 
6925 	// VoIP / QoS flag
6926 	PackAddBool(p, "qos", o->DisableQoS ? false : true);
6927 
6928 	// Bulk transfer support
6929 	PackAddBool(p, "support_bulk_on_rudp", true);
6930 	PackAddBool(p, "support_hmac_on_bulk_of_rudp", true);
6931 
6932 	// UDP recovery support
6933 	PackAddBool(p, "support_udp_recovery", true);
6934 
6935 	// Unique ID
6936 	GenerateMachineUniqueHash(unique);
6937 	PackAddData(p, "unique_id", unique, SHA1_SIZE);
6938 
6939 	// UDP acceleration function using flag
6940 	if (o->NoUdpAcceleration == false && c->Session->UdpAccel != NULL)
6941 	{
6942 		IP my_ip;
6943 
6944 		Zero(&my_ip, sizeof(my_ip));
6945 
6946 		PackAddBool(p, "use_udp_acceleration", true);
6947 
6948 		PackAddInt(p, "udp_acceleration_version", c->Session->UdpAccel->Version);
6949 
6950 		Copy(&my_ip, &c->Session->UdpAccel->MyIp, sizeof(IP));
6951 		if (IsLocalHostIP(&my_ip))
6952 		{
6953 			if (IsIP4(&my_ip))
6954 			{
6955 				ZeroIP4(&my_ip);
6956 			}
6957 			else
6958 			{
6959 				ZeroIP6(&my_ip);
6960 			}
6961 		}
6962 
6963 		PackAddIp(p, "udp_acceleration_client_ip", &my_ip);
6964 		PackAddInt(p, "udp_acceleration_client_port", c->Session->UdpAccel->MyPort);
6965 		PackAddData(p, "udp_acceleration_client_key", c->Session->UdpAccel->MyKey, UDP_ACCELERATION_COMMON_KEY_SIZE_V1);
6966 		PackAddData(p, "udp_acceleration_client_key_v2", c->Session->UdpAccel->MyKey_V2, UDP_ACCELERATION_COMMON_KEY_SIZE_V2);
6967 		PackAddBool(p, "support_hmac_on_udp_acceleration", true);
6968 		PackAddBool(p, "support_udp_accel_fast_disconnect_detect", true);
6969 		PackAddInt(p, "udp_acceleration_max_version", 2);
6970 	}
6971 
6972 	PackAddInt(p, "rudp_bulk_max_version", 2);
6973 
6974 	// Brand string for the connection limit
6975 	{
6976 		char *branded_ctos = _SS("BRANDED_C_TO_S");
6977 		if(StrLen(branded_ctos) > 0)
6978 		{
6979 			PackAddStr(p, "branded_ctos", branded_ctos);
6980 		}
6981 	}
6982 
6983 	// Node information
6984 	CreateNodeInfo(&info, c);
6985 	OutRpcNodeInfo(p, &info);
6986 
6987 	// OS information
6988 	GetWinVer(&v);
6989 	OutRpcWinVer(p, &v);
6990 
6991 	ret = HttpClientSend(c->FirstSock, p);
6992 	if (ret == false)
6993 	{
6994 		c->Err = ERR_DISCONNECTED;
6995 	}
6996 
6997 	FreePack(p);
6998 
6999 	return ret;
7000 }
7001 
7002 // Upload the Hello packet
ServerUploadHello(CONNECTION * c)7003 bool ServerUploadHello(CONNECTION *c)
7004 {
7005 	PACK *p;
7006 	// Validate arguments
7007 	if (c == NULL)
7008 	{
7009 		return false;
7010 	}
7011 
7012 	// Random number generation
7013 	Rand(c->Random, SHA1_SIZE);
7014 
7015 	p = PackHello(c->Random, c->ServerVer, c->ServerBuild, c->ServerStr);
7016 	if (HttpServerSend(c->FirstSock, p) == false)
7017 	{
7018 		FreePack(p);
7019 		c->Err = ERR_DISCONNECTED;
7020 		return false;
7021 	}
7022 
7023 	FreePack(p);
7024 
7025 	return true;
7026 }
7027 
7028 // Download the Hello packet
ClientDownloadHello(CONNECTION * c,SOCK * s)7029 bool ClientDownloadHello(CONNECTION *c, SOCK *s)
7030 {
7031 	PACK *p;
7032 	UINT err;
7033 	UCHAR random[SHA1_SIZE];
7034 	// Validate arguments
7035 	if (c == NULL)
7036 	{
7037 		return false;
7038 	}
7039 
7040 	// Data reception
7041 	p = HttpClientRecv(s);
7042 	if (p == NULL)
7043 	{
7044 		c->Err = ERR_SERVER_IS_NOT_VPN;
7045 		return false;
7046 	}
7047 
7048 	if (err = GetErrorFromPack(p))
7049 	{
7050 		// An error has occured
7051 		c->Err = err;
7052 		FreePack(p);
7053 		return false;
7054 	}
7055 
7056 	// Packet interpretation
7057 	if (GetHello(p, random, &c->ServerVer, &c->ServerBuild, c->ServerStr, sizeof(c->ServerStr)) == false)
7058 	{
7059 		c->Err = ERR_SERVER_IS_NOT_VPN;
7060 		FreePack(p);
7061 		return false;
7062 	}
7063 
7064 	if (c->FirstSock == s)
7065 	{
7066 		Copy(c->Random, random, SHA1_SIZE);
7067 	}
7068 
7069 	FreePack(p);
7070 
7071 	return true;
7072 }
7073 
7074 // Download the signature
ServerDownloadSignature(CONNECTION * c,char ** error_detail_str)7075 bool ServerDownloadSignature(CONNECTION *c, char **error_detail_str)
7076 {
7077 	HTTP_HEADER *h;
7078 	UCHAR *data;
7079 	UINT data_size;
7080 	SOCK *s;
7081 	UINT num = 0, max = 19;
7082 	SERVER *server;
7083 	char *vpn_http_target = HTTP_VPN_TARGET2;
7084 	bool check_hostname = false;
7085 	bool disable_json_api = false;
7086 	// Validate arguments
7087 	if (c == NULL)
7088 	{
7089 		return false;
7090 	}
7091 
7092 	server = c->Cedar->Server;
7093 
7094 	disable_json_api = server->DisableJsonRpcWebApi;
7095 
7096 
7097 
7098 
7099 
7100 	s = c->FirstSock;
7101 
7102 	while (true)
7103 	{
7104 		bool not_found_error = false;
7105 
7106 		num++;
7107 		if (num > max)
7108 		{
7109 			// Disconnect
7110 			Disconnect(s);
7111 			c->Err = ERR_CLIENT_IS_NOT_VPN;
7112 
7113 			*error_detail_str = "HTTP_TOO_MANY_REQUEST";
7114 			return false;
7115 		}
7116 		// Receive a header
7117 		h = RecvHttpHeader(s);
7118 		if (h == NULL)
7119 		{
7120 			c->Err = ERR_CLIENT_IS_NOT_VPN;
7121 			if (c->IsJsonRpc)
7122 			{
7123 				c->Err = ERR_DISCONNECTED;
7124 			}
7125 			return false;
7126 		}
7127 
7128 		if (check_hostname && (StrCmpi(h->Version, "HTTP/1.1") == 0 || StrCmpi(h->Version, "HTTP/1.2") == 0))
7129 		{
7130 			HTTP_VALUE *v;
7131 			char hostname[64];
7132 
7133 			Zero(hostname, sizeof(hostname));
7134 
7135 			v = GetHttpValue(h, "Host");
7136 			if (v != NULL)
7137 			{
7138 				StrCpy(hostname, sizeof(hostname), v->Data);
7139 			}
7140 
7141 			if (IsEmptyStr(hostname))
7142 			{
7143 				// Invalid hostname
7144 				HttpSendInvalidHostname(s, h->Target);
7145 				FreeHttpHeader(h);
7146 				c->Err = ERR_CLIENT_IS_NOT_VPN;
7147 				*error_detail_str = "Invalid_hostname";
7148 				return false;
7149 			}
7150 		}
7151 
7152 
7153 
7154 
7155 		// Interpret
7156 		if (StrCmpi(h->Method, "POST") == 0)
7157 		{
7158 			// Receive the data since it's POST
7159 			data_size = GetContentLength(h);
7160 
7161 			if (disable_json_api == false)
7162 			{
7163 				if (StrCmpi(h->Target, "/api") == 0 || StrCmpi(h->Target, "/api/") == 0)
7164 				{
7165 					c->IsJsonRpc = true;
7166 					c->Type = CONNECTION_TYPE_ADMIN_RPC;
7167 
7168 					JsonRpcProcPost(c, s, h, data_size);
7169 
7170 					FreeHttpHeader(h);
7171 
7172 					if (c->JsonRpcAuthed)
7173 					{
7174 						num = 0;
7175 					}
7176 
7177 					continue;
7178 				}
7179 				else if (StartWith(h->Target, "/admin"))
7180 				{
7181 					c->IsJsonRpc = true;
7182 					c->Type = CONNECTION_TYPE_ADMIN_RPC;
7183 
7184 					AdminWebProcPost(c, s, h, data_size, h->Target);
7185 
7186 					FreeHttpHeader(h);
7187 
7188 					if (c->JsonRpcAuthed)
7189 					{
7190 						num = 0;
7191 					}
7192 
7193 					continue;
7194 				}
7195 			}
7196 
7197 			if ((data_size > MAX_WATERMARK_SIZE || data_size < SizeOfWaterMark()) && (data_size != StrLen(HTTP_VPN_TARGET_POSTDATA)))
7198 			{
7199 				// Data is too large
7200 				HttpSendForbidden(s, h->Target, NULL);
7201 				FreeHttpHeader(h);
7202 				c->Err = ERR_CLIENT_IS_NOT_VPN;
7203 				*error_detail_str = "POST_Recv_TooLong";
7204 				return false;
7205 			}
7206 			data = Malloc(data_size);
7207 			if (RecvAll(s, data, data_size, s->SecureMode) == false)
7208 			{
7209 				// Data reception failure
7210 				Free(data);
7211 				FreeHttpHeader(h);
7212 				c->Err = ERR_DISCONNECTED;
7213 				*error_detail_str = "POST_Recv_Failed";
7214 				return false;
7215 			}
7216 			// Check the Target
7217 			if ((StrCmpi(h->Target, vpn_http_target) != 0) || not_found_error)
7218 			{
7219 				// Target is invalid
7220 				HttpSendNotFound(s, h->Target);
7221 				Free(data);
7222 				FreeHttpHeader(h);
7223 				*error_detail_str = "POST_Target_Wrong";
7224 			}
7225 			else
7226 			{
7227 				// Compare posted data with the WaterMark
7228 				if ((data_size == StrLen(HTTP_VPN_TARGET_POSTDATA) && (Cmp(data, HTTP_VPN_TARGET_POSTDATA, data_size) == 0))
7229 					|| ((data_size >= SizeOfWaterMark()) && Cmp(data, WaterMark, SizeOfWaterMark()) == 0))
7230 				{
7231 					// Check the WaterMark
7232 					Free(data);
7233 					FreeHttpHeader(h);
7234 					return true;
7235 				}
7236 				else
7237 				{
7238 					// WaterMark is incorrect
7239 					HttpSendForbidden(s, h->Target, NULL);
7240 					FreeHttpHeader(h);
7241 					*error_detail_str = "POST_WaterMark_Error";
7242 				}
7243 			}
7244 		}
7245 		else if (StrCmpi(h->Method, "OPTIONS") == 0)
7246 		{
7247 			if (disable_json_api == false)
7248 			{
7249 				if (StrCmpi(h->Target, "/api") == 0 || StrCmpi(h->Target, "/api/") == 0 || StartWith(h->Target, "/admin"))
7250 				{
7251 					c->IsJsonRpc = true;
7252 					c->Type = CONNECTION_TYPE_ADMIN_RPC;
7253 
7254 					JsonRpcProcOptions(c, s, h, h->Target);
7255 
7256 					FreeHttpHeader(h);
7257 
7258 					num = 0;
7259 
7260 					continue;
7261 				}
7262 			}
7263 		}
7264 		else if (StrCmpi(h->Method, "SSTP_DUPLEX_POST") == 0 && (server->DisableSSTPServer == false || s->IsReverseAcceptedSocket
7265 			) &&
7266 			GetServerCapsBool(server, "b_support_sstp") && GetNoSstp() == false)
7267 		{
7268 			// SSTP client is connected
7269 			c->WasSstp = true;
7270 
7271 			if (StrCmpi(h->Target, SSTP_URI) == 0)
7272 			{
7273 				bool sstp_ret;
7274 				// Accept the SSTP connection
7275 				c->Type = CONNECTION_TYPE_SSTP;
7276 
7277 				sstp_ret = AcceptSstp(c);
7278 
7279 				c->Err = ERR_DISCONNECTED;
7280 				FreeHttpHeader(h);
7281 
7282 				if (sstp_ret)
7283 				{
7284 					*error_detail_str = "";
7285 				}
7286 				else
7287 				{
7288 					*error_detail_str = "SSTP_ABORT";
7289 				}
7290 
7291 				return false;
7292 			}
7293 			else
7294 			{
7295 				// URI is invalid
7296 				HttpSendNotFound(s, h->Target);
7297 				*error_detail_str = "SSTP_URL_WRONG";
7298 			}
7299 
7300 			FreeHttpHeader(h);
7301 		}
7302 		else
7303 		{
7304 			// This should not be a VPN client, but interpret a bit more
7305 			if (StrCmpi(h->Method, "GET") != 0 && StrCmpi(h->Method, "HEAD") != 0
7306 				 && StrCmpi(h->Method, "POST") != 0)
7307 			{
7308 				// Unsupported method calls
7309 				HttpSendNotImplemented(s, h->Method, h->Target, h->Version);
7310 				*error_detail_str = "HTTP_BAD_METHOD";
7311 			}
7312 			else
7313 			{
7314 
7315 				if (StrCmpi(h->Target, "/") == 0)
7316 				{
7317 					// Root directory
7318 					SERVER *s = c->Cedar->Server;
7319 
7320 					*error_detail_str = "HTTP_ROOT";
7321 
7322 					{
7323 						BUF *b = NULL;
7324 
7325 						if (disable_json_api == false)
7326 						{
7327 							b = ReadDump("|wwwroot\\index.html");
7328 						}
7329 
7330 						if (b != NULL)
7331 						{
7332 							FreeHttpHeader(h);
7333 							h = NewHttpHeader("HTTP/1.1", "202", "OK");
7334 							AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE4));
7335 							AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
7336 							AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
7337 
7338 							PostHttp(c->FirstSock, h, b->Buf, b->Size);
7339 
7340 							FreeBuf(b);
7341 						}
7342 						else
7343 						{
7344 							HttpSendForbidden(c->FirstSock, h->Target, "");
7345 						}
7346 					}
7347 				}
7348 				else
7349 				{
7350 					bool b = false;
7351 
7352 					// Show the WebUI if the configuration allow to use the WebUI
7353 					if (c->Cedar->Server != NULL && c->Cedar->Server->UseWebUI)
7354 					{
7355 						WU_WEBPAGE *page;
7356 
7357 						// Show the WebUI
7358 						page = WuGetPage(h->Target, c->Cedar->WebUI);
7359 
7360 						if (page != NULL)
7361 						{
7362 							PostHttp(s, page->header, page->data, page->size);
7363 							b = true;
7364 							WuFreeWebPage(page);
7365 						}
7366 
7367 					}
7368 
7369 					if (c->FirstSock->RemoteIP.addr[0] == 127)
7370 					{
7371 						if (StrCmpi(h->Target, HTTP_SAITAMA) == 0)
7372 						{
7373 							// Saitama (joke)
7374 							FreeHttpHeader(h);
7375 							h = NewHttpHeader("HTTP/1.1", "202", "OK");
7376 							AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE3));
7377 							AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
7378 							AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
7379 							PostHttp(s, h, Saitama, SizeOfSaitama());
7380 							b = true;
7381 						}
7382 						else if (StartWith(h->Target, HTTP_PICTURES))
7383 						{
7384 							BUF *buf;
7385 
7386 							// Lots of photos
7387 							buf = ReadDump("|Pictures.mht");
7388 
7389 							if (buf != NULL)
7390 							{
7391 								FreeHttpHeader(h);
7392 								h = NewHttpHeader("HTTP/1.1", "202", "OK");
7393 								AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE5));
7394 								AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
7395 								AddHttpValue(h, NewHttpValue("Keep-Alive", HTTP_KEEP_ALIVE));
7396 								PostHttp(s, h, buf->Buf, buf->Size);
7397 								b = true;
7398 
7399 								FreeBuf(buf);
7400 							}
7401 						}
7402 					}
7403 
7404 					if (b == false)
7405 					{
7406 						if (disable_json_api == false)
7407 						{
7408 							if (StartWith(h->Target, "/api?") || StartWith(h->Target, "/api/") || StrCmpi(h->Target, "/api") == 0)
7409 							{
7410 								c->IsJsonRpc = true;
7411 								c->Type = CONNECTION_TYPE_ADMIN_RPC;
7412 
7413 								JsonRpcProcGet(c, s, h, h->Target);
7414 
7415 								if (c->JsonRpcAuthed)
7416 								{
7417 									num = 0;
7418 								}
7419 
7420 								FreeHttpHeader(h);
7421 
7422 								continue;
7423 							}
7424 							else if (StartWith(h->Target, "/admin"))
7425 							{
7426 								c->IsJsonRpc = true;
7427 								c->Type = CONNECTION_TYPE_ADMIN_RPC;
7428 
7429 								AdminWebProcGet(c, s, h, h->Target);
7430 
7431 								if (c->JsonRpcAuthed)
7432 								{
7433 									num = 0;
7434 								}
7435 
7436 								FreeHttpHeader(h);
7437 
7438 								continue;
7439 							}
7440 						}
7441 
7442 						if (false) // TODO
7443 						{
7444 							if (StrCmpi(h->Target, "/mvpn") == 0 || StrCmpi(h->Target, "/mvpn/") == 0)
7445 							{
7446 								MvpnProcGet(c, s, h, h->Target);
7447 
7448 								FreeHttpHeader(h);
7449 								continue;
7450 							}
7451 						}
7452 					}
7453 
7454 					if (b == false)
7455 					{
7456 						// Not Found
7457 						HttpSendNotFound(s, h->Target);
7458 
7459 						*error_detail_str = "HTTP_NOT_FOUND";
7460 					}
7461 				}
7462 			}
7463 			FreeHttpHeader(h);
7464 		}
7465 	}
7466 }
7467 
7468 // Upload a signature
ClientUploadSignature(SOCK * s)7469 bool ClientUploadSignature(SOCK *s)
7470 {
7471 	HTTP_HEADER *h;
7472 	UINT water_size, rand_size;
7473 	UCHAR *water;
7474 	char ip_str[128];
7475 	// Validate arguments
7476 	if (s == NULL)
7477 	{
7478 		return false;
7479 	}
7480 
7481 	IPToStr(ip_str, sizeof(ip_str), &s->RemoteIP);
7482 
7483 	h = NewHttpHeader("POST", HTTP_VPN_TARGET2, "HTTP/1.1");
7484 	AddHttpValue(h, NewHttpValue("Host", ip_str));
7485 	AddHttpValue(h, NewHttpValue("Content-Type", HTTP_CONTENT_TYPE3));
7486 	AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
7487 
7488 
7489 
7490 	// Generate a watermark
7491 	rand_size = Rand32() % (HTTP_PACK_RAND_SIZE_MAX * 2);
7492 	water_size = SizeOfWaterMark() + rand_size;
7493 	water = Malloc(water_size);
7494 	Copy(water, WaterMark, SizeOfWaterMark());
7495 	Rand(&water[SizeOfWaterMark()], rand_size);
7496 
7497 	// Upload the watermark data
7498 	if (PostHttp(s, h, water, water_size) == false)
7499 	{
7500 		Free(water);
7501 		FreeHttpHeader(h);
7502 		return false;
7503 	}
7504 
7505 	Free(water);
7506 	FreeHttpHeader(h);
7507 
7508 	return true;
7509 }
7510 
7511 // Establish a connection to the server
ClientConnectToServer(CONNECTION * c)7512 SOCK *ClientConnectToServer(CONNECTION *c)
7513 {
7514 	SOCK *s = NULL;
7515 	X *x = NULL;
7516 	K *k = NULL;
7517 	// Validate arguments
7518 	if (c == NULL)
7519 	{
7520 		return NULL;
7521 	}
7522 
7523 	if (c->Halt)
7524 	{
7525 		c->Err = ERR_USER_CANCEL;
7526 		return NULL;
7527 	}
7528 
7529 	// Get the socket by connecting
7530 	s = ClientConnectGetSocket(c, false, (c->DontUseTls1 ? false : true));
7531 	if (s == NULL)
7532 	{
7533 		// Connection failure
7534 		return NULL;
7535 	}
7536 
7537 	c->FirstSock = s;
7538 
7539 	if (c->Halt)
7540 	{
7541 		c->Err = ERR_USER_CANCEL;
7542 		ReleaseSock(s);
7543 		c->FirstSock = NULL;
7544 		return NULL;
7545 	}
7546 
7547 	// Time-out
7548 	SetTimeout(s, CONNECTING_TIMEOUT);
7549 
7550 	// Start the SSL communication
7551 	if (StartSSLEx(s, x, k, (c->DontUseTls1 ? false : true), 0, c->ServerName) == false)
7552 	{
7553 		// SSL communication start failure
7554 		Disconnect(s);
7555 		ReleaseSock(s);
7556 		c->FirstSock = NULL;
7557 		c->Err = ERR_SERVER_IS_NOT_VPN;
7558 		return NULL;
7559 	}
7560 
7561 	if (s->RemoteX == NULL)
7562 	{
7563 		// SSL communication start failure
7564 		Disconnect(s);
7565 		ReleaseSock(s);
7566 		c->FirstSock = NULL;
7567 		c->Err = ERR_SERVER_IS_NOT_VPN;
7568 		return NULL;
7569 	}
7570 
7571 	return s;
7572 }
7573 
7574 // Return a socket by connecting to the server
ClientConnectGetSocket(CONNECTION * c,bool additional_connect,bool no_tls)7575 SOCK *ClientConnectGetSocket(CONNECTION *c, bool additional_connect, bool no_tls)
7576 {
7577 	SOCK *s = NULL;
7578 	CLIENT_OPTION *o;
7579 	char *host_for_direct_connection;
7580 	UINT port_for_direct_connection;
7581 	wchar_t tmp[MAX_SIZE];
7582 	SESSION *sess;
7583 	volatile bool *cancel_flag = NULL;
7584 	void *hWnd;
7585 	UINT nat_t_err = 0;
7586 	bool is_additonal_rudp_session = false;
7587 	UCHAR uc = 0;
7588 	IP ret_ip;
7589 	// Validate arguments
7590 	if (c == NULL)
7591 	{
7592 		return NULL;
7593 	}
7594 
7595 	Zero(&ret_ip, sizeof(IP));
7596 
7597 	sess = c->Session;
7598 
7599 	if (sess != NULL)
7600 	{
7601 		cancel_flag = &sess->CancelConnect;
7602 		is_additonal_rudp_session = sess->IsRUDPSession;
7603 	}
7604 
7605 	hWnd = c->hWndForUI;
7606 
7607 	o = c->Session->ClientOption;
7608 
7609 	if (additional_connect)
7610 	{
7611 		if (sess != NULL)
7612 		{
7613 			Copy(&ret_ip, &sess->ServerIP_CacheForNextConnect, sizeof(IP));
7614 		}
7615 	}
7616 
7617 	if (c->RestoreServerNameAndPort && additional_connect)
7618 	{
7619 		// Restore to the original server name and port number
7620 		c->RestoreServerNameAndPort = false;
7621 
7622 		if (StrCmpi(c->ServerName, o->Hostname) != 0)
7623 		{
7624 			StrCpy(c->ServerName, sizeof(c->ServerName), o->Hostname);
7625 			Zero(&ret_ip, sizeof(IP));
7626 		}
7627 
7628 		c->ServerPort = o->Port;
7629 	}
7630 
7631 	host_for_direct_connection = c->ServerName;
7632 	port_for_direct_connection = c->ServerPort;
7633 
7634 	switch (o->ProxyType)
7635 	{
7636 	case PROXY_DIRECT:	// TCP/IP
7637 		UniFormat(tmp, sizeof(tmp), _UU("STATUS_4"), c->ServerName);
7638 		PrintStatus(sess, tmp);
7639 		// Production job
7640 		if (o->PortUDP == 0)
7641 		{
7642 			{
7643 				// If additional_connect == false, enable trying to NAT-T connection
7644 				// If additional_connect == true, follow the IsRUDPSession setting in this session
7645 				s = TcpIpConnectEx(host_for_direct_connection, port_for_direct_connection,
7646 					(bool *)cancel_flag, hWnd, &nat_t_err, (additional_connect ? (!is_additonal_rudp_session) : false),
7647 					true, no_tls, &ret_ip);
7648 			}
7649 		}
7650 		else
7651 		{
7652 			// Mode to connect with R-UDP directly without using NAT-T server when using UDP
7653 			IP ip;
7654 
7655 			Zero(&ip, sizeof(ip));
7656 
7657 			StrToIP(&ip, o->Hostname);
7658 
7659 
7660 			s = NewRUDPClientDirect(VPN_RUDP_SVC_NAME, &ip, o->PortUDP, &nat_t_err,
7661 				TIMEOUT_TCP_PORT_CHECK, (bool *)cancel_flag, NULL, NULL, 0, false);
7662 
7663 			if (s != NULL)
7664 			{
7665 				StrCpy(s->UnderlayProtocol, sizeof(s->UnderlayProtocol), SOCK_UNDERLAY_NAT_T);
7666 				AddProtocolDetailsStr(s->UnderlayProtocol, sizeof(s->UnderlayProtocol), "NAT-T");
7667 			}
7668 		}
7669 		if (s == NULL)
7670 		{
7671 			// Connection failure
7672 			if (nat_t_err != RUDP_ERROR_NAT_T_TWO_OR_MORE)
7673 			{
7674 				c->Err = ERR_CONNECT_FAILED;
7675 			}
7676 			else
7677 			{
7678 				c->Err = ERR_NAT_T_TWO_OR_MORE;
7679 			}
7680 			return NULL;
7681 		}
7682 		break;
7683 
7684 	case PROXY_HTTP:	// HTTP Proxy
7685 		host_for_direct_connection = o->ProxyName;
7686 		port_for_direct_connection = o->ProxyPort;
7687 
7688 		UniFormat(tmp, sizeof(tmp), _UU("STATUS_2"), c->ServerName, o->ProxyName);
7689 		PrintStatus(sess, tmp);
7690 
7691 
7692 		// Proxy connection
7693 		s = ProxyConnectEx(c, host_for_direct_connection, port_for_direct_connection,
7694 			c->ServerName, c->ServerPort, o->ProxyUsername, o->ProxyPassword,
7695 			additional_connect, (bool *)cancel_flag, hWnd);
7696 		if (s == NULL)
7697 		{
7698 			// Connection failure
7699 			return NULL;
7700 		}
7701 		break;
7702 
7703 	case PROXY_SOCKS:	// SOCKS Proxy
7704 		host_for_direct_connection = o->ProxyName;
7705 
7706 		port_for_direct_connection = o->ProxyPort;
7707 
7708 		UniFormat(tmp, sizeof(tmp), _UU("STATUS_2"), c->ServerName, o->ProxyName);
7709 		PrintStatus(sess, tmp);
7710 
7711 
7712 		// SOCKS connection
7713 		s = SocksConnectEx2(c, host_for_direct_connection, port_for_direct_connection,
7714 			c->ServerName, c->ServerPort, o->ProxyUsername,
7715 			additional_connect, (bool *)cancel_flag, hWnd, 0, &ret_ip);
7716 		if (s == NULL)
7717 		{
7718 			// Connection failure
7719 			return NULL;
7720 		}
7721 		break;
7722 	}
7723 
7724 	if (s == NULL)
7725 	{
7726 		// Connection failure
7727 		c->Err = ERR_CONNECT_FAILED;
7728 	}
7729 	else
7730 	{
7731 		// Success to connect
7732 		// Keep a note of the IP address
7733 		if (additional_connect == false || IsZeroIP(&s->RemoteIP))
7734 		{
7735 			if (((s->IsRUDPSocket || s->IPv6) && IsZeroIP(&s->RemoteIP) == false && o->ProxyType == PROXY_DIRECT) || GetIP(&c->Session->ServerIP, host_for_direct_connection) == false)
7736 			{
7737 				Copy(&c->Session->ServerIP, &s->RemoteIP, sizeof(IP));
7738 			}
7739 		}
7740 
7741 		if (IsZeroIP(&ret_ip) == false)
7742 		{
7743 			if (c->Session != NULL)
7744 			{
7745 				if (additional_connect == false)
7746 				{
7747 					Copy(&c->Session->ServerIP_CacheForNextConnect, &ret_ip, sizeof(IP));
7748 
7749 					Debug("Saved ServerIP_CacheForNextConnect: %s = %r\n", c->ServerName, &ret_ip);
7750 				}
7751 			}
7752 		}
7753 	}
7754 
7755 	return s;
7756 }
7757 
7758 // Connect via SOCKS
SocksConnect(CONNECTION * c,char * proxy_host_name,UINT proxy_port,char * server_host_name,UINT server_port,char * username,bool additional_connect)7759 SOCK *SocksConnect(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
7760 				   char *server_host_name, UINT server_port,
7761 				   char *username, bool additional_connect)
7762 {
7763 	return SocksConnectEx(c, proxy_host_name, proxy_port,
7764 		server_host_name, server_port, username, additional_connect, NULL, NULL);
7765 }
SocksConnectEx(CONNECTION * c,char * proxy_host_name,UINT proxy_port,char * server_host_name,UINT server_port,char * username,bool additional_connect,bool * cancel_flag,void * hWnd)7766 SOCK *SocksConnectEx(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
7767 				   char *server_host_name, UINT server_port,
7768 				   char *username, bool additional_connect,
7769 				   bool *cancel_flag, void *hWnd)
7770 {
7771 	return SocksConnectEx2(c, proxy_host_name, proxy_port,
7772 		server_host_name, server_port, username, additional_connect, cancel_flag,
7773 		hWnd, 0, NULL);
7774 }
SocksConnectEx2(CONNECTION * c,char * proxy_host_name,UINT proxy_port,char * server_host_name,UINT server_port,char * username,bool additional_connect,bool * cancel_flag,void * hWnd,UINT timeout,IP * ret_ip)7775 SOCK *SocksConnectEx2(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
7776 				   char *server_host_name, UINT server_port,
7777 				   char *username, bool additional_connect,
7778 				   bool *cancel_flag, void *hWnd, UINT timeout, IP *ret_ip)
7779 {
7780 	SOCK *s = NULL;
7781 	IP ip;
7782 	// Validate arguments
7783 	if (c == NULL || proxy_host_name == NULL || proxy_port == 0 || server_host_name == NULL
7784 		|| server_port == 0)
7785 	{
7786 		c->Err = ERR_PROXY_CONNECT_FAILED;
7787 		return NULL;
7788 	}
7789 
7790 	// Get the IP address of the destination server
7791 	if (GetIP(&ip, server_host_name) == false)
7792 	{
7793 		// Failure
7794 		c->Err = ERR_CONNECT_FAILED;
7795 		return NULL;
7796 	}
7797 
7798 	if (c->Halt)
7799 	{
7800 		// Stop
7801 		c->Err = ERR_USER_CANCEL;
7802 		return NULL;
7803 	}
7804 
7805 	// Connection
7806 	s = TcpConnectEx3(proxy_host_name, proxy_port, timeout, cancel_flag, hWnd, true, NULL, false, false, ret_ip);
7807 	if (s == NULL)
7808 	{
7809 		// Failure
7810 		c->Err = ERR_PROXY_CONNECT_FAILED;
7811 		return NULL;
7812 	}
7813 
7814 	// Timeout setting
7815 	SetTimeout(s, MIN(CONNECTING_TIMEOUT_PROXY, (timeout == 0 ? INFINITE : timeout)));
7816 
7817 	if (additional_connect == false)
7818 	{
7819 		c->FirstSock = s;
7820 	}
7821 
7822 	// Request packet transmission
7823 	if (SocksSendRequestPacket(c, s, server_port, &ip, username) == false)
7824 	{
7825 		// Failure
7826 		if (additional_connect == false)
7827 		{
7828 			c->FirstSock = NULL;
7829 		}
7830 		Disconnect(s);
7831 		ReleaseSock(s);
7832 		return NULL;
7833 	}
7834 
7835 	// Receive a response packet
7836 	if (SocksRecvResponsePacket(c, s) == false)
7837 	{
7838 		// Failure
7839 		if (additional_connect == false)
7840 		{
7841 			c->FirstSock = NULL;
7842 		}
7843 		Disconnect(s);
7844 		ReleaseSock(s);
7845 		return NULL;
7846 	}
7847 
7848 	SetTimeout(s, INFINITE);
7849 
7850 	return s;
7851 }
7852 
7853 // Receive a SOCKS response packet
SocksRecvResponsePacket(CONNECTION * c,SOCK * s)7854 bool SocksRecvResponsePacket(CONNECTION *c, SOCK *s)
7855 {
7856 	BUF *b;
7857 	UINT size = 8;
7858 	UCHAR tmp[8];
7859 	UCHAR vn, cd;
7860 	// Validate arguments
7861 	if (c == NULL || s == NULL)
7862 	{
7863 		return false;
7864 	}
7865 
7866 	if (RecvAll(s, tmp, sizeof(tmp), false) == false)
7867 	{
7868 		c->Err = ERR_DISCONNECTED;
7869 		return false;
7870 	}
7871 
7872 	b = NewBuf();
7873 	WriteBuf(b, tmp, sizeof(tmp));
7874 	SeekBuf(b, 0, 0);
7875 
7876 	ReadBuf(b, &vn, 1);
7877 	ReadBuf(b, &cd, 1);
7878 
7879 	FreeBuf(b);
7880 
7881 	if (vn != 0)
7882 	{
7883 		c->Err = ERR_PROXY_ERROR;
7884 		return false;
7885 	}
7886 
7887 	switch (cd)
7888 	{
7889 	case 90:
7890 		// Success
7891 		return true;
7892 
7893 	case 93:
7894 		// Authentication failure
7895 		c->Err = ERR_PROXY_AUTH_FAILED;
7896 		return false;
7897 
7898 	default:
7899 		// Connection to the server failure
7900 		c->Err = ERR_CONNECT_FAILED;
7901 		return false;
7902 	}
7903 }
7904 
7905 // Send a SOCKS request packet
SocksSendRequestPacket(CONNECTION * c,SOCK * s,UINT dest_port,IP * dest_ip,char * userid)7906 bool SocksSendRequestPacket(CONNECTION *c, SOCK *s, UINT dest_port, IP *dest_ip, char *userid)
7907 {
7908 	BUF *b;
7909 	UCHAR vn, cd;
7910 	USHORT port;
7911 	UINT ip;
7912 	bool ret;
7913 	// Validate arguments
7914 	if (s == NULL || dest_port == 0 || dest_ip == NULL || c == NULL)
7915 	{
7916 		return false;
7917 	}
7918 	if (userid == NULL)
7919 	{
7920 		userid = "";
7921 	}
7922 
7923 	b = NewBuf();
7924 	vn = 4;
7925 	cd = 1;
7926 	WriteBuf(b, &vn, 1);
7927 	WriteBuf(b, &cd, 1);
7928 	port = Endian16((USHORT)dest_port);
7929 	ip = IPToUINT(dest_ip);
7930 	WriteBuf(b, &port, 2);
7931 	WriteBuf(b, &ip, 4);
7932 	WriteBuf(b, userid, StrLen(userid) + 1);
7933 
7934 	ret = SendAll(s, b->Buf, b->Size, false);
7935 	if (ret == false)
7936 	{
7937 		c->Err = ERR_DISCONNECTED;
7938 	}
7939 
7940 	FreeBuf(b);
7941 
7942 	return ret;
7943 }
7944 
7945 // Connect through a proxy
ProxyConnect(CONNECTION * c,char * proxy_host_name,UINT proxy_port,char * server_host_name,UINT server_port,char * username,char * password,bool additional_connect)7946 SOCK *ProxyConnect(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
7947 				   char *server_host_name, UINT server_port,
7948 				   char *username, char *password, bool additional_connect)
7949 {
7950 	return ProxyConnectEx(c, proxy_host_name, proxy_port,
7951 		server_host_name, server_port, username, password, additional_connect, NULL, NULL);
7952 }
ProxyConnectEx(CONNECTION * c,char * proxy_host_name,UINT proxy_port,char * server_host_name,UINT server_port,char * username,char * password,bool additional_connect,bool * cancel_flag,void * hWnd)7953 SOCK *ProxyConnectEx(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
7954 				   char *server_host_name, UINT server_port,
7955 				   char *username, char *password, bool additional_connect,
7956 				   bool *cancel_flag, void *hWnd)
7957 {
7958 	return ProxyConnectEx2(c, proxy_host_name, proxy_port,
7959 		server_host_name, server_port, username, password, additional_connect,
7960 		cancel_flag, hWnd, 0);
7961 }
ProxyConnectEx2(CONNECTION * c,char * proxy_host_name,UINT proxy_port,char * server_host_name,UINT server_port,char * username,char * password,bool additional_connect,bool * cancel_flag,void * hWnd,UINT timeout)7962 SOCK *ProxyConnectEx2(CONNECTION *c, char *proxy_host_name, UINT proxy_port,
7963 				   char *server_host_name, UINT server_port,
7964 				   char *username, char *password, bool additional_connect,
7965 				   bool *cancel_flag, void *hWnd, UINT timeout)
7966 {
7967 	SOCK *s = NULL;
7968 	bool use_auth = false;
7969 	char tmp[MAX_SIZE];
7970 	char auth_tmp_str[MAX_SIZE], auth_b64_str[MAX_SIZE * 2];
7971 	char basic_str[MAX_SIZE * 2];
7972 	UINT http_error_code;
7973 	HTTP_HEADER *h;
7974 	char server_host_name_tmp[256];
7975 	UINT i, len;
7976 	// Validate arguments
7977 	if (c == NULL || proxy_host_name == NULL || proxy_port == 0 || server_host_name == NULL ||
7978 		server_port == 0)
7979 	{
7980 		c->Err = ERR_PROXY_CONNECT_FAILED;
7981 		return NULL;
7982 	}
7983 	if (username != NULL && password != NULL &&
7984 		(StrLen(username) != 0 || StrLen(password) != 0))
7985 	{
7986 		use_auth = true;
7987 	}
7988 
7989 	if (c->Halt)
7990 	{
7991 		// Stop
7992 		c->Err = ERR_USER_CANCEL;
7993 		return NULL;
7994 	}
7995 
7996 	Zero(server_host_name_tmp, sizeof(server_host_name_tmp));
7997 	StrCpy(server_host_name_tmp, sizeof(server_host_name_tmp), server_host_name);
7998 
7999 	len = StrLen(server_host_name_tmp);
8000 
8001 	for (i = 0;i < len;i++)
8002 	{
8003 		if (server_host_name_tmp[i] == '/')
8004 		{
8005 			server_host_name_tmp[i] = 0;
8006 		}
8007 	}
8008 
8009 	// Connection
8010 	s = TcpConnectEx3(proxy_host_name, proxy_port, timeout, cancel_flag, hWnd, true, NULL, false, false, NULL);
8011 	if (s == NULL)
8012 	{
8013 		// Failure
8014 		c->Err = ERR_PROXY_CONNECT_FAILED;
8015 		return NULL;
8016 	}
8017 
8018 	// Timeout setting
8019 	SetTimeout(s, MIN(CONNECTING_TIMEOUT_PROXY, (timeout == 0 ? INFINITE : timeout)));
8020 
8021 	if (additional_connect == false)
8022 	{
8023 		c->FirstSock = s;
8024 	}
8025 
8026 	// HTTP header generation
8027 	if (IsStrIPv6Address(server_host_name_tmp))
8028 	{
8029 		IP ip;
8030 		char iptmp[MAX_PATH];
8031 
8032 		StrToIP(&ip, server_host_name_tmp);
8033 		IPToStr(iptmp, sizeof(iptmp), &ip);
8034 
8035 		Format(tmp, sizeof(tmp), "[%s]:%u", iptmp, server_port);
8036 	}
8037 	else
8038 	{
8039 		Format(tmp, sizeof(tmp), "%s:%u", server_host_name_tmp, server_port);
8040 	}
8041 
8042 	h = NewHttpHeader("CONNECT", tmp, "HTTP/1.0");
8043 	AddHttpValue(h, NewHttpValue("User-Agent", (c->Cedar == NULL ? DEFAULT_USER_AGENT : c->Cedar->HttpUserAgent)));
8044 	AddHttpValue(h, NewHttpValue("Host", server_host_name_tmp));
8045 	AddHttpValue(h, NewHttpValue("Content-Length", "0"));
8046 	AddHttpValue(h, NewHttpValue("Proxy-Connection", "Keep-Alive"));
8047 	AddHttpValue(h, NewHttpValue("Pragma", "no-cache"));
8048 
8049 	if (use_auth)
8050 	{
8051 		wchar_t tmp[MAX_SIZE];
8052 		UniFormat(tmp, sizeof(tmp), _UU("STATUS_3"), server_host_name_tmp);
8053 		// Generate the authentication string
8054 		Format(auth_tmp_str, sizeof(auth_tmp_str), "%s:%s",
8055 			username, password);
8056 
8057 		// Base64 encode
8058 		Zero(auth_b64_str, sizeof(auth_b64_str));
8059 		Encode64(auth_b64_str, auth_tmp_str);
8060 		Format(basic_str, sizeof(basic_str), "Basic %s", auth_b64_str);
8061 
8062 		AddHttpValue(h, NewHttpValue("Proxy-Authorization", basic_str));
8063 	}
8064 
8065 	// Transmission
8066 	if (SendHttpHeader(s, h) == false)
8067 	{
8068 		// Failure
8069 		if (additional_connect == false)
8070 		{
8071 			c->FirstSock = NULL;
8072 		}
8073 		FreeHttpHeader(h);
8074 		Disconnect(s);
8075 		ReleaseSock(s);
8076 		c->Err = ERR_PROXY_ERROR;
8077 		return NULL;
8078 	}
8079 
8080 	FreeHttpHeader(h);
8081 
8082 	if (c->Halt)
8083 	{
8084 		// Stop
8085 		if (additional_connect == false)
8086 		{
8087 			c->FirstSock = NULL;
8088 		}
8089 		Disconnect(s);
8090 		ReleaseSock(s);
8091 		c->Err = ERR_USER_CANCEL;
8092 		return NULL;
8093 	}
8094 
8095 	// Receive the results
8096 	h = RecvHttpHeader(s);
8097 	if (h == NULL)
8098 	{
8099 		// Failure
8100 		if (additional_connect == false)
8101 		{
8102 			c->FirstSock = NULL;
8103 		}
8104 		FreeHttpHeader(h);
8105 		Disconnect(s);
8106 		ReleaseSock(s);
8107 		c->Err = ERR_PROXY_ERROR;
8108 		return NULL;
8109 	}
8110 
8111 	http_error_code = 0;
8112 	if (StrLen(h->Method) == 8)
8113 	{
8114 		if (Cmp(h->Method, "HTTP/1.", 7) == 0)
8115 		{
8116 			http_error_code = ToInt(h->Target);
8117 		}
8118 	}
8119 	FreeHttpHeader(h);
8120 
8121 	// Check the code
8122 	switch (http_error_code)
8123 	{
8124 	case 401:
8125 	case 403:
8126 	case 407:
8127 		// Authentication failure
8128 		if (additional_connect == false)
8129 		{
8130 			c->FirstSock = NULL;
8131 		}
8132 		Disconnect(s);
8133 		ReleaseSock(s);
8134 		c->Err = ERR_PROXY_AUTH_FAILED;
8135 		return NULL;
8136 
8137 	default:
8138 		if ((http_error_code / 100) == 2)
8139 		{
8140 			// Success
8141 			SetTimeout(s, INFINITE);
8142 			return s;
8143 		}
8144 		else
8145 		{
8146 			// Receive an unknown result
8147 			if (additional_connect == false)
8148 			{
8149 				c->FirstSock = NULL;
8150 			}
8151 			Disconnect(s);
8152 			ReleaseSock(s);
8153 			c->Err = ERR_PROXY_ERROR;
8154 			return NULL;
8155 		}
8156 	}
8157 }
8158 
8159 // TCP connection function
TcpConnectEx2(char * hostname,UINT port,UINT timeout,bool * cancel_flag,void * hWnd,bool try_start_ssl,bool ssl_no_tls)8160 SOCK *TcpConnectEx2(char *hostname, UINT port, UINT timeout, bool *cancel_flag, void *hWnd, bool try_start_ssl, bool ssl_no_tls)
8161 {
8162 	return TcpConnectEx3(hostname, port, timeout, cancel_flag, hWnd, false, NULL, try_start_ssl, ssl_no_tls, NULL);
8163 }
TcpConnectEx3(char * hostname,UINT port,UINT timeout,bool * cancel_flag,void * hWnd,bool no_nat_t,UINT * nat_t_error_code,bool try_start_ssl,bool ssl_no_tls,IP * ret_ip)8164 SOCK *TcpConnectEx3(char *hostname, UINT port, UINT timeout, bool *cancel_flag, void *hWnd, bool no_nat_t, UINT *nat_t_error_code, bool try_start_ssl, bool ssl_no_tls, IP *ret_ip)
8165 {
8166 #ifdef	OS_WIN32
8167 	if (hWnd == NULL)
8168 	{
8169 #endif	// OS_WIN32
8170 		return ConnectEx4(hostname, port, timeout, cancel_flag, (no_nat_t ? NULL : VPN_RUDP_SVC_NAME), nat_t_error_code, try_start_ssl, ssl_no_tls, true, ret_ip);
8171 #ifdef	OS_WIN32
8172 	}
8173 	else
8174 	{
8175 		return WinConnectEx3((HWND)hWnd, hostname, port, timeout, 0, NULL, NULL, nat_t_error_code, (no_nat_t ? NULL : VPN_RUDP_SVC_NAME), try_start_ssl, ssl_no_tls);
8176 	}
8177 #endif	// OS_WIN32
8178 }
8179 
8180 // Connect with TCP/IP
TcpIpConnect(char * hostname,UINT port,bool try_start_ssl,bool ssl_no_tls)8181 SOCK *TcpIpConnect(char *hostname, UINT port, bool try_start_ssl, bool ssl_no_tls)
8182 {
8183 	return TcpIpConnectEx(hostname, port, NULL, NULL, NULL, false, try_start_ssl, ssl_no_tls, NULL);
8184 }
TcpIpConnectEx(char * hostname,UINT port,bool * cancel_flag,void * hWnd,UINT * nat_t_error_code,bool no_nat_t,bool try_start_ssl,bool ssl_no_tls,IP * ret_ip)8185 SOCK *TcpIpConnectEx(char *hostname, UINT port, bool *cancel_flag, void *hWnd, UINT *nat_t_error_code, bool no_nat_t, bool try_start_ssl, bool ssl_no_tls, IP *ret_ip)
8186 {
8187 	SOCK *s = NULL;
8188 	UINT dummy_int = 0;
8189 	// Validate arguments
8190 	if (nat_t_error_code == NULL)
8191 	{
8192 		nat_t_error_code = &dummy_int;
8193 	}
8194 	*nat_t_error_code = 0;
8195 	if (hostname == NULL || port == 0)
8196 	{
8197 		return NULL;
8198 	}
8199 
8200 	s = TcpConnectEx3(hostname, port, 0, cancel_flag, hWnd, no_nat_t, nat_t_error_code, try_start_ssl, ssl_no_tls, ret_ip);
8201 	if (s == NULL)
8202 	{
8203 		return NULL;
8204 	}
8205 
8206 	return s;
8207 }
8208 
8209 // Protocol routine initialization
InitProtocol()8210 void InitProtocol()
8211 {
8212 }
8213 
8214 // Release the protocol routine
FreeProtocol()8215 void FreeProtocol()
8216 {
8217 }
8218 
8219 // Create a Hello packet
PackHello(void * random,UINT ver,UINT build,char * server_str)8220 PACK *PackHello(void *random, UINT ver, UINT build, char *server_str)
8221 {
8222 	PACK *p;
8223 	// Validate arguments
8224 	if (random == NULL || server_str == NULL)
8225 	{
8226 		return NULL;
8227 	}
8228 
8229 	p = NewPack();
8230 	PackAddStr(p, "hello", server_str);
8231 	PackAddInt(p, "version", ver);
8232 	PackAddInt(p, "build", build);
8233 	PackAddData(p, "random", random, SHA1_SIZE);
8234 
8235 	return p;
8236 }
8237 
8238 // Interpret the Hello packet
GetHello(PACK * p,void * random,UINT * ver,UINT * build,char * server_str,UINT server_str_size)8239 bool GetHello(PACK *p, void *random, UINT *ver, UINT *build, char *server_str, UINT server_str_size)
8240 {
8241 	// Validate arguments
8242 	if (p == NULL || random == NULL || ver == NULL || server_str == NULL)
8243 	{
8244 		return false;
8245 	}
8246 
8247 	if (PackGetStr(p, "hello", server_str, server_str_size) == false)
8248 	{
8249 		return false;
8250 	}
8251 	*ver = PackGetInt(p, "version");
8252 	*build = PackGetInt(p, "build");
8253 	if (PackGetDataSize(p, "random") != SHA1_SIZE)
8254 	{
8255 		return false;
8256 	}
8257 	if (PackGetData(p, "random", random) == false)
8258 	{
8259 		return false;
8260 	}
8261 
8262 	return true;
8263 }
8264 
8265 // Get the authentication method from PACK
GetAuthTypeFromPack(PACK * p)8266 UINT GetAuthTypeFromPack(PACK *p)
8267 {
8268 	// Validate arguments
8269 	if (p == NULL)
8270 	{
8271 		return 0;
8272 	}
8273 
8274 	return PackGetInt(p, "authtype");
8275 }
8276 
8277 // Get the HUB name and the user name from the PACK
GetHubnameAndUsernameFromPack(PACK * p,char * username,UINT username_size,char * hubname,UINT hubname_size)8278 bool GetHubnameAndUsernameFromPack(PACK *p, char *username, UINT username_size,
8279 								   char *hubname, UINT hubname_size)
8280 {
8281 	// Validate arguments
8282 	if (p == NULL || username == NULL || hubname == NULL)
8283 	{
8284 		return false;
8285 	}
8286 
8287 	if (PackGetStr(p, "username", username, username_size) == false)
8288 	{
8289 		return false;
8290 	}
8291 	if (PackGetStr(p, "hubname", hubname, hubname_size) == false)
8292 	{
8293 		return false;
8294 	}
8295 	return true;
8296 }
8297 
8298 // Get the protocol from PACK
GetProtocolFromPack(PACK * p)8299 UINT GetProtocolFromPack(PACK *p)
8300 {
8301 	// Validate arguments
8302 	if (p == NULL)
8303 	{
8304 		return 0;
8305 	}
8306 
8307 #if	0
8308 	return PackGetInt(p, "protocol");
8309 #else
8310 	// Limit to the TCP protocol in the current version
8311 	return CONNECTION_TCP;
8312 #endif
8313 }
8314 
8315 // Get the method from the PACK
GetMethodFromPack(PACK * p,char * method,UINT size)8316 bool GetMethodFromPack(PACK *p, char *method, UINT size)
8317 {
8318 	// Validate arguments
8319 	if (p == NULL || method == NULL || size == 0)
8320 	{
8321 		return false;
8322 	}
8323 
8324 	return PackGetStr(p, "method", method, size);
8325 }
8326 
8327 // Generate a packet of certificate authentication login
PackLoginWithCert(char * hubname,char * username,X * x,void * sign,UINT sign_size)8328 PACK *PackLoginWithCert(char *hubname, char *username, X *x, void *sign, UINT sign_size)
8329 {
8330 	PACK *p;
8331 	BUF *b;
8332 	// Validate arguments
8333 	if (hubname == NULL || username == NULL)
8334 	{
8335 		return NULL;
8336 	}
8337 
8338 	p = NewPack();
8339 	PackAddStr(p, "method", "login");
8340 	PackAddStr(p, "hubname", hubname);
8341 	PackAddStr(p, "username", username);
8342 	PackAddInt(p, "authtype", CLIENT_AUTHTYPE_CERT);
8343 
8344 	// Certificate
8345 	b = XToBuf(x, false);
8346 	PackAddData(p, "cert", b->Buf, b->Size);
8347 	FreeBuf(b);
8348 
8349 	// Signature data
8350 	PackAddData(p, "sign", sign, sign_size);
8351 
8352 	return p;
8353 }
8354 
8355 // Generate a packet of plain text password authentication login
PackLoginWithPlainPassword(char * hubname,char * username,void * plain_password)8356 PACK *PackLoginWithPlainPassword(char *hubname, char *username, void *plain_password)
8357 {
8358 	PACK *p;
8359 	// Validate arguments
8360 	if (hubname == NULL || username == NULL)
8361 	{
8362 		return NULL;
8363 	}
8364 
8365 	p = NewPack();
8366 	PackAddStr(p, "method", "login");
8367 	PackAddStr(p, "hubname", hubname);
8368 	PackAddStr(p, "username", username);
8369 	PackAddInt(p, "authtype", CLIENT_AUTHTYPE_PLAIN_PASSWORD);
8370 	PackAddStr(p, "plain_password", plain_password);
8371 
8372 	return p;
8373 }
8374 
8375 // Generate a packet of OpenVPN certificate login
PackLoginWithOpenVPNCertificate(char * hubname,char * username,X * x)8376 PACK *PackLoginWithOpenVPNCertificate(char *hubname, char *username, X *x)
8377 {
8378 	PACK *p;
8379 	char cn_username[128];
8380 	BUF *cert_buf = NULL;
8381 	// Validate arguments
8382 	if (hubname == NULL || username == NULL || x == NULL)
8383 	{
8384 		return NULL;
8385 	}
8386 
8387 	p = NewPack();
8388 	PackAddStr(p, "method", "login");
8389 	PackAddStr(p, "hubname", hubname);
8390 
8391 	if (IsEmptyStr(username))
8392 	{
8393 		if (x->subject_name == NULL)
8394 		{
8395 			return NULL;
8396 		}
8397 		UniToStr(cn_username, sizeof(cn_username), x->subject_name->CommonName);
8398 		PackAddStr(p, "username", cn_username);
8399 	}
8400 	else
8401 	{
8402 		PackAddStr(p, "username", username);
8403 	}
8404 
8405 	PackAddInt(p, "authtype", AUTHTYPE_OPENVPN_CERT);
8406 
8407 	cert_buf = XToBuf(x, false);
8408 	PackAddBuf(p, "cert", cert_buf);
8409 	FreeBuf(cert_buf);
8410 
8411 	return p;
8412 }
8413 
8414 // Create a packet of password authentication login
PackLoginWithPassword(char * hubname,char * username,void * secure_password)8415 PACK *PackLoginWithPassword(char *hubname, char *username, void *secure_password)
8416 {
8417 	PACK *p;
8418 	// Validate arguments
8419 	if (hubname == NULL || username == NULL)
8420 	{
8421 		return NULL;
8422 	}
8423 
8424 	p = NewPack();
8425 	PackAddStr(p, "method", "login");
8426 	PackAddStr(p, "hubname", hubname);
8427 	PackAddStr(p, "username", username);
8428 	PackAddInt(p, "authtype", CLIENT_AUTHTYPE_PASSWORD);
8429 	PackAddData(p, "secure_password", secure_password, SHA1_SIZE);
8430 
8431 	return p;
8432 }
8433 
8434 // Create a packet for anonymous login
PackLoginWithAnonymous(char * hubname,char * username)8435 PACK *PackLoginWithAnonymous(char *hubname, char *username)
8436 {
8437 	PACK *p;
8438 	// Validate arguments
8439 	if (hubname == NULL || username == NULL)
8440 	{
8441 		return NULL;
8442 	}
8443 
8444 	p = NewPack();
8445 	PackAddStr(p, "method", "login");
8446 	PackAddStr(p, "hubname", hubname);
8447 	PackAddStr(p, "username", username);
8448 	PackAddInt(p, "authtype", CLIENT_AUTHTYPE_ANONYMOUS);
8449 
8450 	return p;
8451 }
8452 
8453 // Create a packet for the additional connection
PackAdditionalConnect(UCHAR * session_key)8454 PACK *PackAdditionalConnect(UCHAR *session_key)
8455 {
8456 	PACK *p;
8457 	// Validate arguments
8458 	if (session_key == NULL)
8459 	{
8460 		return NULL;
8461 	}
8462 
8463 	p = NewPack();
8464 	PackAddStr(p, "method", "additional_connect");
8465 	PackAddData(p, "session_key", session_key, SHA1_SIZE);
8466 
8467 	return p;
8468 }
8469 
8470 
8471 // Generate a RC4 key pair
GenerateRC4KeyPair(RC4_KEY_PAIR * k)8472 void GenerateRC4KeyPair(RC4_KEY_PAIR *k)
8473 {
8474 	// Validate arguments
8475 	if (k == NULL)
8476 	{
8477 		return;
8478 	}
8479 
8480 	Rand(k->ClientToServerKey, sizeof(k->ClientToServerKey));
8481 	Rand(k->ServerToClientKey, sizeof(k->ServerToClientKey));
8482 }
8483 
8484 // MVPN GET Procedure (WebSocket)
MvpnProcGet(CONNECTION * c,SOCK * s,HTTP_HEADER * h,char * url_target)8485 void MvpnProcGet(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target)
8486 {
8487 	HTTP_VALUE *req_upgrade;
8488 	HTTP_VALUE *req_version;
8489 	HTTP_VALUE *req_key;
8490 	char response_key[64];
8491 	UINT client_ws_version = 0;
8492 	char *bad_request_body = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\"http://www.w3.org/TR/html4/strict.dtd\">\r\n<HTML><HEAD><TITLE>Bad Request</TITLE>\r\n<META HTTP-EQUIV=\"Content-Type\" Content=\"text/html; charset=us-ascii\"></HEAD>\r\n<BODY><h2>Bad Request</h2>\r\n<hr><p>HTTP Error 400. The request is badly formed.</p>\r\n</BODY></HTML>";
8493 	if (c == NULL || s == NULL || h == NULL || url_target == NULL)
8494 	{
8495 		return;
8496 	}
8497 
8498 	req_upgrade = GetHttpValue(h, "Upgrade");
8499 	if (req_upgrade == NULL || StrCmpi(req_upgrade->Data, "websocket") != 0)
8500 	{
8501 		MvpnSendReply(s, 400, "Bad Request", bad_request_body, StrLen(bad_request_body),
8502 			NULL, NULL, NULL, h);
8503 		return;
8504 	}
8505 
8506 	req_version = GetHttpValue(h, "Sec-WebSocket-Version");
8507 	if (req_version != NULL) client_ws_version = ToInt(req_version->Data);
8508 	if (client_ws_version != 13)
8509 	{
8510 		MvpnSendReply(s, 400, "Bad Request", NULL, 0,
8511 			NULL, "Sec-WebSocket-Version", "13", h);
8512 		return;
8513 	}
8514 
8515 	Zero(response_key, sizeof(response_key));
8516 	req_key = GetHttpValue(h, "Sec-WebSocket-Key");
8517 	if (req_key != NULL)
8518 	{
8519 		char tmp[MAX_SIZE];
8520 		UCHAR hash[SHA1_SIZE];
8521 		StrCpy(tmp, sizeof(tmp), req_key->Data);
8522 		StrCat(tmp, sizeof(tmp), "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
8523 		HashSha1(hash, tmp, StrLen(tmp));
8524 		B64_Encode(response_key, hash, SHA1_SIZE);
8525 	}
8526 	else
8527 	{
8528 		MvpnSendReply(s, 400, "Bad Request", NULL, 0,
8529 			NULL, "Sec-WebSocket-Version", "13", h);
8530 		return;
8531 	}
8532 
8533 	MvpnSendReply(s, 101, "Switching Protocols", NULL, 0, NULL,
8534 		"Sec-WebSocket-Accept", response_key, h);
8535 
8536 	MvpnAccept(c, s);
8537 }
8538 
8539 // MVPN Send Reply
MvpnSendReply(SOCK * s,UINT status_code,char * status_string,UCHAR * data,UINT data_size,char * content_type,char * add_header_name,char * add_header_value,HTTP_HEADER * request_headers)8540 bool MvpnSendReply(SOCK *s, UINT status_code, char *status_string, UCHAR *data, UINT data_size, char *content_type,
8541 				   char *add_header_name, char *add_header_value, HTTP_HEADER *request_headers)
8542 {
8543 	HTTP_HEADER *h;
8544 	char date_str[MAX_SIZE];
8545 	char error_code_str[16];
8546 	bool ret = false;
8547 	HTTP_VALUE *origin;
8548 	HTTP_VALUE *upgrade;
8549 	HTTP_VALUE *req_connection;
8550 	if (s == NULL || status_string == NULL || (data_size != 0 && data == NULL) || request_headers == NULL)
8551 	{
8552 		return false;
8553 	}
8554 	if (content_type == NULL)
8555 	{
8556 		content_type = "text/html; charset=utf-8";
8557 	}
8558 
8559 	req_connection = GetHttpValue(request_headers, "Connection");
8560 
8561 	ToStr(error_code_str, status_code);
8562 	GetHttpDateStr(date_str, sizeof(date_str), SystemTime64());
8563 
8564 	h = NewHttpHeader("HTTP/1.1", error_code_str, status_string);
8565 
8566 	AddHttpValue(h, NewHttpValue("Cache-Control", "no-cache"));
8567 	if (data_size != 0)
8568 	{
8569 		AddHttpValue(h, NewHttpValue("Content-Type", content_type));
8570 	}
8571 	AddHttpValue(h, NewHttpValue("Date", date_str));
8572 	if (req_connection != NULL)
8573 	{
8574 		AddHttpValue(h, NewHttpValue("Connection", req_connection->Data));
8575 	}
8576 	else
8577 	{
8578 		AddHttpValue(h, NewHttpValue("Connection", "Keep-Alive"));
8579 	}
8580 	AddHttpValue(h, NewHttpValue("Access-Control-Allow-Headers", "content-type"));
8581 	AddHttpValue(h, NewHttpValue("Access-Control-Allow-Headers", "authorization"));
8582 	AddHttpValue(h, NewHttpValue("Access-Control-Allow-Headers", "x-websocket-extensions"));
8583 	AddHttpValue(h, NewHttpValue("Access-Control-Allow-Headers", "x-websocket-version"));
8584 	AddHttpValue(h, NewHttpValue("Access-Control-Allow-Headers", "x-websocket-protocol"));
8585 	AddHttpValue(h, NewHttpValue("Access-Control-Allow-Credentials", "true"));
8586 
8587 	origin = GetHttpValue(request_headers, "Origin");
8588 	if (origin != NULL)
8589 	{
8590 		AddHttpValue(h, NewHttpValue("Access-Control-Allow-Origin", origin->Data));
8591 	}
8592 
8593 	upgrade = GetHttpValue(request_headers, "Upgrade");
8594 	if (upgrade != NULL)
8595 	{
8596 		AddHttpValue(h, NewHttpValue("Upgrade", upgrade->Data));
8597 	}
8598 
8599 	if (add_header_name != NULL && add_header_value != NULL)
8600 	{
8601 		AddHttpValue(h, NewHttpValue(add_header_name, add_header_value));
8602 	}
8603 
8604 	ret = PostHttp(s, h, data, data_size);
8605 
8606 	FreeHttpHeader(h);
8607 
8608 	return ret;
8609 }
8610 
8611 // MVPN Accept
MvpnAccept(CONNECTION * c,SOCK * s)8612 void MvpnAccept(CONNECTION *c, SOCK *s)
8613 {
8614 	WS *w;
8615 	UINT err;
8616 	if (c == NULL || s == NULL)
8617 	{
8618 		return;
8619 	}
8620 
8621 	w = NewWs(s);
8622 
8623 	err = MvpnDoAccept(c, w);
8624 
8625 	//while (true)
8626 	//{
8627 	//	UINT r;
8628 	//	Zero(data, sizeof(data));
8629 	//	r = WsRecvSyncAll(w, data, 7);
8630 	//	if (!r)
8631 	//	{
8632 	//		break;
8633 	//	}
8634 	//	Print("WS_Recv: %s\n", data);
8635 	//	r = WsSendSync(w, data, 7);
8636 	//	if (!r)
8637 	//	{
8638 	//		break;
8639 	//	}
8640 	//	Print("WS_Send: %s\n", data);
8641 	//}
8642 
8643 	ReleaseWs(w);
8644 }
8645 
8646 // New WebSocket
NewWs(SOCK * s)8647 WS *NewWs(SOCK *s)
8648 {
8649 	WS *w;
8650 	if (s == NULL)
8651 	{
8652 		return NULL;
8653 	}
8654 
8655 	w = ZeroMalloc(sizeof(WS));
8656 
8657 	w->Ref = NewRef();
8658 
8659 	w->MaxBufferSize = MAX_BUFFERING_PACKET_SIZE;
8660 	w->Sock = s;
8661 	AddRef(w->Sock->ref);
8662 
8663 	w->Wsp = NewWsp();
8664 
8665 	return w;
8666 }
8667 
8668 // Release WebSocket
ReleaseWs(WS * w)8669 void ReleaseWs(WS *w)
8670 {
8671 	if (w == NULL)
8672 	{
8673 		return;
8674 	}
8675 
8676 	if (Release(w->Ref) == 0)
8677 	{
8678 		CleanupWs(w);
8679 	}
8680 }
8681 
CleanupWs(WS * w)8682 void CleanupWs(WS *w)
8683 {
8684 	if (w == NULL)
8685 	{
8686 		return;
8687 	}
8688 
8689 	if (w->Sock != NULL)
8690 	{
8691 		Disconnect(w->Sock);
8692 		ReleaseSock(w->Sock);
8693 	}
8694 
8695 	FreeWsp(w->Wsp);
8696 
8697 	Free(w);
8698 }
8699 
8700 // WebSocket: Send a frame in sync mode
WsSendSync(WS * w,void * data,UINT size)8701 bool WsSendSync(WS *w, void *data, UINT size)
8702 {
8703 	UCHAR *send_buf;
8704 	UINT send_buf_size;
8705 	if (size == 0)
8706 	{
8707 		return !w->Disconnected;
8708 	}
8709 	if (w == NULL || data == NULL)
8710 	{
8711 		return false;
8712 	}
8713 	if (w->Disconnected || w->Wsp->HasError)
8714 	{
8715 		Disconnect(w->Sock);
8716 		return false;
8717 	}
8718 
8719 	WriteFifo(w->Wsp->AppSendFifo, data, size);
8720 	WspTry(w->Wsp);
8721 	if (w->Wsp->HasError == false)
8722 	{
8723 		send_buf = FifoPtr(w->Wsp->PhysicalSendFifo);
8724 		send_buf_size = FifoSize(w->Wsp->PhysicalSendFifo);
8725 		if (SendAll(w->Sock, send_buf, send_buf_size, w->Sock->SecureMode))
8726 		{
8727 			ReadFifo(w->Wsp->PhysicalSendFifo, NULL, send_buf_size);
8728 			return true;
8729 		}
8730 	}
8731 
8732 	w->Disconnected = true;
8733 	Disconnect(w->Sock);
8734 
8735 	return false;
8736 }
8737 
8738 // WebSocket: Send a frame in async mode
WsSendAsync(WS * w,void * data,UINT size)8739 UINT WsSendAsync(WS *w, void *data, UINT size)
8740 {
8741 	bool disconnected = false;
8742 	UINT ret = 0;
8743 	if (size == 0)
8744 	{
8745 		return !w->Disconnected;
8746 	}
8747 	if (w == NULL || data == NULL)
8748 	{
8749 		return 0;
8750 	}
8751 	if (w->Disconnected || w->Wsp->HasError)
8752 	{
8753 		Disconnect(w->Sock);
8754 		return 0;
8755 	}
8756 
8757 	if (FifoSize(w->Wsp->PhysicalSendFifo) > w->Wsp->MaxBufferSize)
8758 	{
8759 		return INFINITE;
8760 	}
8761 
8762 	WriteFifo(w->Wsp->AppSendFifo, data, size);
8763 
8764 	if (WsTrySendAsync(w) == false)
8765 	{
8766 		ret = 0;
8767 	}
8768 	else
8769 	{
8770 		ret = size;
8771 	}
8772 
8773 	if (ret == 0)
8774 	{
8775 		w->Disconnected = true;
8776 		Disconnect(w->Sock);
8777 	}
8778 
8779 	return ret;
8780 }
8781 
8782 // WebSocket: Send buffered streams in async mode
WsTrySendAsync(WS * w)8783 bool WsTrySendAsync(WS *w)
8784 {
8785 	bool ret = false;
8786 	if (w == NULL)
8787 	{
8788 		return false;
8789 	}
8790 	if (w->Disconnected || w->Wsp->HasError)
8791 	{
8792 		Disconnect(w->Sock);
8793 		return false;
8794 	}
8795 
8796 	WspTry(w->Wsp);
8797 
8798 	if (w->Wsp->HasError == false)
8799 	{
8800 		while (true)
8801 		{
8802 			UINT send_size = FifoSize(w->Wsp->PhysicalSendFifo);
8803 			UINT r;
8804 			if (send_size == 0)
8805 			{
8806 				ret = true;
8807 				break;
8808 			}
8809 
8810 			r = Send(w->Sock, FifoPtr(w->Wsp->PhysicalSendFifo), send_size, w->Sock->SecureMode);
8811 
8812 			if (r == INFINITE)
8813 			{
8814 				ret = true;
8815 				break;
8816 			}
8817 			else if (r == 0)
8818 			{
8819 				ret = false;
8820 				break;
8821 			}
8822 			else
8823 			{
8824 				ReadFifo(w->Wsp->PhysicalSendFifo, NULL, r);
8825 			}
8826 		}
8827 	}
8828 	else
8829 	{
8830 		ret = false;
8831 	}
8832 
8833 	if (ret == 0)
8834 	{
8835 		w->Disconnected = true;
8836 		Disconnect(w->Sock);
8837 	}
8838 
8839 	return ret;
8840 }
8841 
8842 // WebSocket: Receive a frame in async mode
WsRecvAsync(WS * w,void * data,UINT size)8843 UINT WsRecvAsync(WS *w, void *data, UINT size)
8844 {
8845 	bool disconnected = false;
8846 	UINT ret = 0;
8847 	if (w == NULL || data == NULL || size == 0)
8848 	{
8849 		return 0;
8850 	}
8851 	if (w->Disconnected || w->Wsp->HasError)
8852 	{
8853 		Disconnect(w->Sock);
8854 		return 0;
8855 	}
8856 
8857 	// Receive all arrived data from the socket
8858 	while (FifoSize(w->Wsp->PhysicalRecvFifo) < w->MaxBufferSize)
8859 	{
8860 		UINT r;
8861 
8862 		r = Recv(w->Sock, w->TmpBuf, sizeof(w->TmpBuf), w->Sock->SecureMode);
8863 		if (r == 0)
8864 		{
8865 			// Disconnected
8866 			disconnected = true;
8867 			break;
8868 		}
8869 		else if (r == INFINITE)
8870 		{
8871 			// Pending
8872 			break;
8873 		}
8874 		else
8875 		{
8876 			// Received some data
8877 			WriteFifo(w->Wsp->PhysicalRecvFifo, w->TmpBuf, r);
8878 		}
8879 	}
8880 
8881 	if (disconnected == false)
8882 	{
8883 		UINT sz;
8884 		WspTry(w->Wsp);
8885 		if (w->Wsp->HasError)
8886 		{
8887 			disconnected = true;
8888 		}
8889 		else
8890 		{
8891 			sz = FifoSize(w->Wsp->AppRecvFifo);
8892 			if (sz >= 1)
8893 			{
8894 				if (sz > size)
8895 				{
8896 					sz = size;
8897 				}
8898 				ReadFifo(w->Wsp->AppRecvFifo, data, sz);
8899 				ret = sz;
8900 			}
8901 			else
8902 			{
8903 				ret = INFINITE;
8904 			}
8905 		}
8906 	}
8907 
8908 	if (disconnected)
8909 	{
8910 		w->Disconnected = true;
8911 		Disconnect(w->Sock);
8912 		ret = 0;
8913 	}
8914 
8915 	return ret;
8916 }
8917 
8918 // WebSocket: Receive a frame in sync mode until fulfill the buffer
WsRecvSyncAll(WS * w,void * data,UINT size)8919 bool WsRecvSyncAll(WS *w, void *data, UINT size)
8920 {
8921 	UINT recv_size;
8922 	if (w == NULL || data == NULL || size == 0)
8923 	{
8924 		return false;
8925 	}
8926 
8927 	recv_size = 0;
8928 
8929 	while (true)
8930 	{
8931 		UINT sz, ret;
8932 
8933 		sz = size - recv_size;
8934 		ret = WsRecvSync(w, (UCHAR *)data + recv_size, sz);
8935 		if (ret == 0)
8936 		{
8937 			return false;
8938 		}
8939 		recv_size += ret;
8940 		if (recv_size >= size)
8941 		{
8942 			return true;
8943 		}
8944 	}
8945 }
8946 
8947 // WebSocket: Receive a frame in sync mode
WsRecvSync(WS * w,void * data,UINT size)8948 UINT WsRecvSync(WS *w, void *data, UINT size)
8949 {
8950 	if (w == NULL || data == NULL || size == 0)
8951 	{
8952 		return 0;
8953 	}
8954 	if (w->Disconnected || w->Wsp->HasError)
8955 	{
8956 		Disconnect(w->Sock);
8957 		return 0;
8958 	}
8959 
8960 	while (w->Disconnected == false || w->Wsp->HasError == false)
8961 	{
8962 		UINT r;
8963 		UINT sz;
8964 		WspTry(w->Wsp);
8965 		if (w->Wsp->HasError)
8966 		{
8967 			break;
8968 		}
8969 		sz = FifoSize(w->Wsp->AppRecvFifo);
8970 		if (sz >= 1)
8971 		{
8972 			if (sz > size)
8973 			{
8974 				sz = size;
8975 			}
8976 			ReadFifo(w->Wsp->AppRecvFifo, data, sz);
8977 			return sz;
8978 		}
8979 		r = Recv(w->Sock, w->TmpBuf, sizeof(w->TmpBuf), w->Sock->SecureMode);
8980 		if (r == 0)
8981 		{
8982 			break;
8983 		}
8984 		WriteFifo(w->Wsp->PhysicalRecvFifo, w->TmpBuf, r);
8985 	}
8986 
8987 	w->Disconnected = true;
8988 	Disconnect(w->Sock);
8989 
8990 	return 0;
8991 }
8992 
8993 // New WebSocket protocol
NewWsp()8994 WSP *NewWsp()
8995 {
8996 	WSP *p = ZeroMalloc(sizeof(WSP));
8997 
8998 	p->AppRecvFifo = NewFifo();
8999 	p->AppSendFifo = NewFifo();
9000 	p->PhysicalRecvFifo = NewFifo();
9001 	p->PhysicalSendFifo = NewFifo();
9002 
9003 	p->MaxBufferSize = MAX_BUFFERING_PACKET_SIZE;
9004 
9005 	return p;
9006 }
9007 
9008 // Free WebSocket protocol
FreeWsp(WSP * p)9009 void FreeWsp(WSP *p)
9010 {
9011 	if (p == NULL)
9012 	{
9013 		return;
9014 	}
9015 
9016 	ReleaseFifo(p->AppRecvFifo);
9017 	ReleaseFifo(p->AppSendFifo);
9018 	ReleaseFifo(p->PhysicalRecvFifo);
9019 	ReleaseFifo(p->PhysicalSendFifo);
9020 
9021 	Free(p);
9022 }
9023 
9024 // WebSocket protocol: Try to interpret send/recv buffers
WspTry(WSP * p)9025 void WspTry(WSP *p)
9026 {
9027 	if (p == NULL)
9028 	{
9029 		return;
9030 	}
9031 
9032 	// Physical -> App
9033 	while (p->HasError == false)
9034 	{
9035 		UINT read_buffer_size;
9036 		BLOCK *b = WspTryRecvNextFrame(p, &read_buffer_size);
9037 		if (b == NULL)
9038 		{
9039 			// No more frames
9040 			break;
9041 		}
9042 
9043 		if (b->Param1 == WS_OPCODE_CONTINUE || b->Param1 == WS_OPCODE_TEXT || b->Param1 == WS_OPCODE_BIN)
9044 		{
9045 			WriteFifo(p->AppRecvFifo, b->Buf, b->Size);
9046 		}
9047 		else if (b->Param1 == WS_OPCODE_PING)
9048 		{
9049 			if (FifoSize(p->PhysicalSendFifo) <= p->MaxBufferSize)
9050 			{
9051 				WspTrySendFrame(p, WS_OPCODE_PONG, b->Buf, b->Size);
9052 			}
9053 		}
9054 		else if (b->Param1 == WS_OPCODE_PONG)
9055 		{
9056 		}
9057 		else
9058 		{
9059 			// Error: disconnect
9060 			p->HasError = true;
9061 		}
9062 
9063 		ReadFifo(p->PhysicalRecvFifo, NULL, read_buffer_size);
9064 
9065 		FreeBlock(b);
9066 	}
9067 
9068 	// App -> Physical
9069 	while (p->HasError == false)
9070 	{
9071 		UINT size;
9072 		UCHAR *data;
9073 
9074 		size = FifoSize(p->AppSendFifo);
9075 		if (size == 0)
9076 		{
9077 			// No more data
9078 			break;
9079 		}
9080 
9081 		if (size > WS_SEND_SINGLE_FRAGMENT_SIZE)
9082 		{
9083 			size = WS_SEND_SINGLE_FRAGMENT_SIZE;
9084 		}
9085 		data = FifoPtr(p->AppSendFifo);
9086 
9087 		WspTrySendFrame(p, WS_OPCODE_BIN, data, size);
9088 
9089 		ReadFifo(p->AppSendFifo, NULL, size);
9090 	}
9091 }
9092 
9093 // WebSocket protocol: Try to send a single frame
WspTrySendFrame(WSP * p,UCHAR opcode,void * data,UINT size)9094 void WspTrySendFrame(WSP *p, UCHAR opcode, void *data, UINT size)
9095 {
9096 	BUF *b;
9097 	UCHAR flag_and_opcode;
9098 	if (p == NULL || (size != 0 && data == NULL))
9099 	{
9100 		return;
9101 	}
9102 	if (p->HasError)
9103 	{
9104 		return;
9105 	}
9106 
9107 	b = NewBuf();
9108 
9109 	flag_and_opcode = 0x80 | (opcode & 0x0F);
9110 	WriteBufChar(b, flag_and_opcode);
9111 
9112 	if (size <= 125)
9113 	{
9114 		WriteBufChar(b, size);
9115 	}
9116 	else if (size <= 65536)
9117 	{
9118 		WriteBufChar(b, 126);
9119 		WriteBufShort(b, size);
9120 	}
9121 	else
9122 	{
9123 		WriteBufChar(b, 127);
9124 		WriteBufInt64(b, size);
9125 	}
9126 
9127 	WriteBuf(b, data, size);
9128 
9129 	WriteFifo(p->PhysicalSendFifo, b->Buf, b->Size);
9130 
9131 	FreeBuf(b);
9132 }
9133 
9134 // WebSocket protocol: Try to receive a single frame
WspTryRecvNextFrame(WSP * p,UINT * read_buffer_size)9135 BLOCK *WspTryRecvNextFrame(WSP *p, UINT *read_buffer_size)
9136 {
9137 	BLOCK *b;
9138 	UCHAR *buf;
9139 	UCHAR *buf_pos0;
9140 	UINT sz;
9141 	UCHAR flag_and_opcode;
9142 	UCHAR mask_and_payload_len;
9143 	UCHAR mask_flag;
9144 	UINT payload_len;
9145 	UCHAR mask_key[4];
9146 	UCHAR *ret_data;
9147 	if (p == NULL || read_buffer_size == NULL)
9148 	{
9149 		return NULL;
9150 	}
9151 	if (p->HasError)
9152 	{
9153 		return NULL;
9154 	}
9155 
9156 	buf = buf_pos0 = FifoPtr(p->PhysicalRecvFifo);
9157 	sz = FifoSize(p->PhysicalRecvFifo);
9158 
9159 	if (sz < 1)
9160 	{
9161 		return NULL;
9162 	}
9163 	flag_and_opcode = *buf;
9164 	buf += 1;
9165 	sz -= 1;
9166 
9167 	if (sz < 1)
9168 	{
9169 		return NULL;
9170 	}
9171 	mask_and_payload_len = *buf;
9172 	buf += 1;
9173 	sz -= 1;
9174 
9175 	mask_flag = mask_and_payload_len & 0x80;
9176 	payload_len = mask_and_payload_len & 0x7F;
9177 	if (payload_len == 126)
9178 	{
9179 		if (sz < sizeof(USHORT))
9180 		{
9181 			return NULL;
9182 		}
9183 		payload_len = READ_USHORT(buf);
9184 		buf += sizeof(USHORT);
9185 		sz -= sizeof(USHORT);
9186 	}
9187 	else if (payload_len == 127)
9188 	{
9189 		UINT64 u64;
9190 		if (sz < sizeof(UINT64))
9191 		{
9192 			return NULL;
9193 		}
9194 		u64 = READ_UINT64(buf);
9195 		buf += sizeof(UINT64);
9196 		sz -= sizeof(UINT64);
9197 		if (u64 > 0x7FFFFFFF)
9198 		{
9199 			p->HasError = true;
9200 			return NULL;
9201 		}
9202 		payload_len = (UINT)u64;
9203 	}
9204 
9205 	if (payload_len > WS_MAX_PAYLOAD_LEN_PER_FRAME)
9206 	{
9207 		p->HasError = true;
9208 		return NULL;
9209 	}
9210 
9211 	if (mask_flag)
9212 	{
9213 		if (sz < 4)
9214 		{
9215 			return NULL;
9216 		}
9217 		Copy(mask_key, buf, 4);
9218 		buf += 4;
9219 		sz -= 4;
9220 	}
9221 
9222 	if (payload_len >= 1 && sz < payload_len)
9223 	{
9224 		return NULL;
9225 	}
9226 
9227 	ret_data = Clone(buf, payload_len);
9228 	sz -= payload_len;
9229 	buf += payload_len;
9230 
9231 	if (mask_flag)
9232 	{
9233 		UINT i;
9234 		for (i = 0;i < payload_len;i++)
9235 		{
9236 			ret_data[i] ^= mask_key[i % 4];
9237 		}
9238 	}
9239 
9240 	b = NewBlock(ret_data, payload_len, 0);
9241 	b->Param1 = (flag_and_opcode & 0xF);
9242 
9243 	*read_buffer_size = (UINT)(buf - buf_pos0);
9244 
9245 	return b;
9246 }
9247 
9248 // WebSocket: Receive a PACK serialized with JSON
WsRecvPack(WS * w)9249 PACK *WsRecvPack(WS *w)
9250 {
9251 	USHORT us;
9252 	UINT size;
9253 	UCHAR *buf;
9254 	PACK *p = NULL;
9255 	if (w == NULL)
9256 	{
9257 		return NULL;
9258 	}
9259 
9260 	if (WsRecvSyncAll(w, &us, sizeof(us)))
9261 	{
9262 		size = Endian16(us);
9263 
9264 		buf = ZeroMalloc(size + 1);
9265 
9266 		if (WsRecvSyncAll(w, buf, size))
9267 		{
9268 			p = JsonStrToPack(buf);
9269 		}
9270 
9271 		Free(buf);
9272 	}
9273 
9274 	return p;
9275 }
9276 
9277 // WebSocket: Send a PACK serialized with JSON
WsSendPack(WS * w,PACK * p)9278 bool WsSendPack(WS *w, PACK *p)
9279 {
9280 	BUF *b;
9281 	char *json_str;
9282 	bool ret = false;
9283 	if (w == NULL || p == NULL)
9284 	{
9285 		return false;
9286 	}
9287 
9288 	json_str = PackToJsonStr(p);
9289 	if (json_str == NULL)
9290 	{
9291 		return false;
9292 	}
9293 
9294 	b = NewBuf();
9295 
9296 	WriteBufShort(b, StrLen(json_str));
9297 	WriteBuf(b, json_str, StrLen(json_str));
9298 
9299 	ret = WsSendSync(w, b->Buf, b->Size);
9300 
9301 	FreeBuf(b);
9302 
9303 	Free(json_str);
9304 
9305 	return ret;
9306 }
9307 
9308 // WebSocket: new error pack
WsNewErrorPack(UINT err)9309 PACK *WsNewErrorPack(UINT err)
9310 {
9311 	PACK *p = NewPack();
9312 	char *error_code_str = WsErrorCodeToString(err);
9313 	wchar_t *error_message = _E(err);
9314 
9315 	PackAddStr(p, "Error", error_code_str);
9316 	PackAddUniStr(p, "ErrorMessage", error_message);
9317 
9318 	return p;
9319 }
9320 
9321 // MVPN: convert error code to string
WsErrorCodeToString(UINT err)9322 char *WsErrorCodeToString(UINT err)
9323 {
9324 	char *ret = "e_unknown";
9325 	switch (err)
9326 	{
9327 	case ERR_NO_ERROR:
9328 		ret = "ok";
9329 		break;
9330 	case ERR_PROTOCOL_ERROR:
9331 		ret = "e_protocol";
9332 		break;
9333 	case ERR_INTERNAL_ERROR:
9334 		ret = "e_internal";
9335 		break;
9336 	case ERR_DISCONNECTED:
9337 	case ERR_AUTO_DISCONNECTED:
9338 		ret = "e_disconnected";
9339 		break;
9340 	case ERR_ACCESS_DENIED:
9341 		ret = "e_access_denied";
9342 		break;
9343 	case ERR_HUB_NOT_FOUND:
9344 		ret = "e_network_not_found";
9345 		break;
9346 	case ERR_HUB_STOPPING:
9347 		ret = "e_network_disabled";
9348 		break;
9349 	case ERR_AUTH_FAILED:
9350 		ret = "e_auth_failed";
9351 		break;
9352 	case ERR_SESSION_TIMEOUT:
9353 		ret = "e_timeout";
9354 		break;
9355 	case ERR_USER_CANCEL:
9356 		ret = "e_user_cancel";
9357 		break;
9358 	case ERR_AUTHTYPE_NOT_SUPPORTED:
9359 		ret = "e_auth_method_not_supported";
9360 		break;
9361 	case ERR_TOO_MANY_CONNECTION:
9362 		ret = "e_too_many_connection";
9363 		break;
9364 	case ERR_HUB_IS_BUSY:
9365 		ret = "e_too_many_session";
9366 		break;
9367 	case ERR_TOO_MANY_USER_SESSION:
9368 		ret = "e_too_many_user_session";
9369 		break;
9370 	case ERR_OBJECT_NOT_FOUND:
9371 		ret = "e_object_not_found";
9372 		break;
9373 	case ERR_NOT_SUPPORTED:
9374 	case ERR_NOT_SUPPORTED_AUTH_ON_OPENSOURCE:
9375 		ret = "e_not_supported";
9376 		break;
9377 	case ERR_INVALID_PARAMETER:
9378 		ret = "e_invalid_parameter";
9379 		break;
9380 	case ERR_NULL_PASSWORD_LOCAL_ONLY:
9381 		ret = "e_empty_password_local_only";
9382 		break;
9383 	case ERR_MONITOR_MODE_DENIED:
9384 		ret = "e_mirror_mode_denied";
9385 		break;
9386 	case ERR_BRIDGE_MODE_DENIED:
9387 		ret = "e_bridge_mode_denied";
9388 		break;
9389 	case ERR_IP_ADDRESS_DENIED:
9390 		ret = "e_client_ip_address_denied";
9391 		break;
9392 	case ERR_MSCHAP2_PASSWORD_NEED_RESET:
9393 		ret = "e_user_password_must_reset";
9394 		break;
9395 
9396 	case ERR_DHCP_SERVER_NOT_RUNNING:
9397 		ret = "e_dhcp_server_not_running";
9398 		break;
9399 	}
9400 	return ret;
9401 }
9402 
9403 // MVPN processing a client
MvpnDoAccept(CONNECTION * c,WS * w)9404 UINT MvpnDoAccept(CONNECTION *c, WS *w)
9405 {
9406 	UINT ret = ERR_INTERNAL_ERROR;
9407 	PACK *client_hello = NULL;
9408 	UINT client_ver = 0;
9409 	char client_impl[256];
9410 	UCHAR client_nonce[128];
9411 	char client_hub_name[MAX_HUBNAME_LEN + 1];
9412 	UINT server_ver = 0;
9413 	char server_impl[256];
9414 	UCHAR server_nonce[128];
9415 	PACK *server_hello = NULL;
9416 	UINT auth_ret = ERR_INTERNAL_ERROR;
9417 	IPC *ipc = NULL;
9418 	UINT i;
9419 	UINT heartbeat_interval = 0;
9420 	UINT disconnect_timeout = 0;
9421 	bool use_udp_acceleration = false;
9422 	IP client_udp_acceleration_ip = {0};
9423 	UINT client_udp_acceleration_port = 0;
9424 	UCHAR client_udp_acceleration_key[UDP_ACCELERATION_COMMON_KEY_SIZE_V2] = {0};
9425 	UDP_ACCEL *udp_accel = NULL;
9426 	bool l3_ipv4_enable = false;
9427 	bool l3_ipv4_dynamic = false;
9428 	IP l3_ipv4_ip = {0};
9429 	IP l3_ipv4_mask = {0};
9430 	IP l3_ipv4_gw = {0};
9431 	IP l3_ipv4_dns1 = {0};
9432 	IP l3_ipv4_dns2 = {0};
9433 	IP l3_ipv4_wins1 = {0};
9434 	IP l3_ipv4_wins2 = {0};
9435 	IP l3_ipv4_dhcp_server = {0};
9436 	char l3_ipv4_classless_routes[4096] = {0};
9437 	bool l3_ipv4_dhcp_allocated = false;
9438 
9439 	if (c == NULL || w == NULL)
9440 	{
9441 		return ERR_INTERNAL_ERROR;
9442 	}
9443 
9444 	Rand(server_nonce, sizeof(server_nonce));
9445 
9446 	// Phase 1: Receive a Client Hello packet
9447 	client_hello = WsRecvPack(w);
9448 	if (client_hello == NULL)
9449 	{
9450 		ret = ERR_PROTOCOL_ERROR;
9451 		goto LABEL_CLEANUP;
9452 	}
9453 	client_ver = PackGetInt(client_hello, "MvpnProtocolVersion");
9454 	if (client_ver < MVPN_VERSION_MIN)
9455 	{
9456 		ret = ERR_PROTOCOL_ERROR;
9457 		goto LABEL_CLEANUP;
9458 	}
9459 	server_ver = MIN(MVPN_VERSION_CURRENT, client_ver);
9460 	if (PackGetData2(client_hello, "Nonce", client_nonce, 128) == false)
9461 	{
9462 		ret = ERR_PROTOCOL_ERROR;
9463 		goto LABEL_CLEANUP;
9464 	}
9465 	if (PackGetStr(client_hello, "Implementation", client_impl, sizeof(client_impl)) == false)
9466 	{
9467 		ret = ERR_PROTOCOL_ERROR;
9468 		goto LABEL_CLEANUP;
9469 	}
9470 	heartbeat_interval = PackGetInt(client_hello, "HeartBeatInterval");
9471 
9472 	if (heartbeat_interval == 0) heartbeat_interval = MVPN_HEARTBEAT_INTERVAL_DEFAULT;
9473 	heartbeat_interval = MAKESURE(heartbeat_interval, MVPN_HEARTBEAT_INTERVAL_MIN, MVPN_HEARTBEAT_INTERVAL_MAX);
9474 
9475 	disconnect_timeout = PackGetInt(client_hello, "DisconnectTimeout");
9476 	if (disconnect_timeout == 0) disconnect_timeout = MVPN_DISCONNECT_TIMEOUT_DEFAULT;
9477 	disconnect_timeout = MAKESURE(disconnect_timeout, MVPN_DISCONNECT_TIMEOUT_MIN, MVPN_DISCONNECT_TIMEOUT_MAX);
9478 
9479 	heartbeat_interval = MIN(heartbeat_interval, disconnect_timeout / 2);
9480 
9481 	use_udp_acceleration = PackGetBool(client_hello, "UseUdpAcceleration");
9482 	if (use_udp_acceleration)
9483 	{
9484 		client_udp_acceleration_port = PackGetInt(client_hello, "UdpAccelerationClientPort");
9485 		if (client_udp_acceleration_port == 0 ||
9486 			PackGetIp(client_hello, "UdpAccelerationClientIp", &client_udp_acceleration_ip) == false ||
9487 			PackGetData2(client_hello, "UdpAccelerationClientKey", client_udp_acceleration_key, sizeof(client_udp_acceleration_key)) == false)
9488 		{
9489 			use_udp_acceleration = false;
9490 		}
9491 	}
9492 
9493 
9494 	Zero(client_hub_name, sizeof(client_hub_name));
9495 	PackGetStr(client_hello, "NetworkName", client_hub_name, sizeof(client_hub_name));
9496 
9497 	l3_ipv4_enable = PackGetBool(client_hello, "L3HelperIPv4Enable");
9498 	if (l3_ipv4_enable)
9499 	{
9500 		char tmp[256];
9501 		bool ok = false;
9502 
9503 		PackGetStr(client_hello, "L3HelperIPv4AddressType", tmp, sizeof(tmp));
9504 
9505 		if (StrCmpi(tmp, MVPN_ADDRESS_TYPE_STATIC) == 0)
9506 		{
9507 			// Static IP address
9508 			l3_ipv4_dynamic = false;
9509 
9510 			if (PackGetIp(client_hello, "L3HelperIPv4Address", &l3_ipv4_ip) &&
9511 				PackGetIp(client_hello, "L3HelperIPv4SubnetMask", &l3_ipv4_mask) &&
9512 				PackGetIp(client_hello, "L3HelperIPv4Gateway", &l3_ipv4_gw))
9513 			{
9514 				ok = true;
9515 			}
9516 		}
9517 		else if (StrCmpi(tmp, MVPN_ADDRESS_TYPE_DYNAMIC) == 0)
9518 		{
9519 			// Dynamic IP address
9520 			l3_ipv4_dynamic = true;
9521 			ok = true;
9522 		}
9523 
9524 		if (ok == false)
9525 		{
9526 			ret = ERR_PROTOCOL_ERROR;
9527 			goto LABEL_CLEANUP;
9528 		}
9529 	}
9530 
9531 	// Phase 2: Send a Server Hello packet
9532 	server_hello = WsNewErrorPack(ERR_NO_ERROR);
9533 	StrCpy(server_impl, sizeof(server_impl), "Test Server");
9534 	PackAddInt(server_hello, "MvpnProtocolVersion", server_ver);
9535 	PackAddData(server_hello, "Nonce", server_nonce, 128);
9536 	PackAddStr(server_hello, "Implementation", server_impl);
9537 	PackAddStr(server_hello, "SupportedAuthMethod", MVPN_AUTHTYPE_ALL_SUPPORTED);
9538 	if (WsSendPack(w, server_hello) == false)
9539 	{
9540 		ret = ERR_DISCONNECTED;
9541 		goto LABEL_CLEANUP;
9542 	}
9543 
9544 	// Phase 3: Receive a Client Auth packet
9545 	for (i = 0;i < MVPN_MAX_AUTH_RETRY;i++)
9546 	{
9547 		bool auth_finish = false;
9548 		PACK *client_auth = NULL;
9549 		char auth_method[64] = {0};
9550 		char auth_username[MAX_USERNAME_LEN + 1];
9551 		IPC *ipc_tmp = NULL;
9552 		IPC_PARAM ipc_param;
9553 		UINT ipc_error_code = 0;
9554 		UINT mss = INFINITE;
9555 
9556 		auth_ret = ERR_INTERNAL_ERROR;
9557 
9558 		client_auth = WsRecvPack(w);
9559 		if (client_auth == NULL)
9560 		{
9561 			auth_ret = ERR_PROTOCOL_ERROR;
9562 			goto LABEL_EXIT_AUTH_RETRY;
9563 		}
9564 
9565 		PackGetStr(client_auth, "AuthMethod", auth_method, sizeof(auth_method));
9566 		if (IsEmptyStr(auth_method))
9567 		{
9568 			auth_ret = ERR_PROTOCOL_ERROR;
9569 			goto LABEL_EXIT_AUTH_RETRY;
9570 		}
9571 
9572 		PackGetStr(client_auth, "AuthUsername", auth_username, sizeof(auth_username));
9573 		if (IsEmptyStr(auth_method))
9574 		{
9575 			auth_ret = ERR_PROTOCOL_ERROR;
9576 			goto LABEL_EXIT_AUTH_RETRY;
9577 		}
9578 
9579 		Zero(&ipc_param, sizeof(ipc_param));
9580 		StrCpy(ipc_param.ClientName, sizeof(ipc_param.ClientName), MVPN_CLIENT_NAME);
9581 
9582 		if (IsEmptyStr(client_impl) == false)
9583 		{
9584 			StrCat(ipc_param.ClientName, sizeof(ipc_param.ClientName), " - ");
9585 			StrCat(ipc_param.ClientName, sizeof(ipc_param.ClientName), client_impl);
9586 		}
9587 
9588 		StrCpy(ipc_param.Postfix, sizeof(ipc_param.Postfix), NVPN_POSTFIX);
9589 		StrCpy(ipc_param.HubName, sizeof(ipc_param.HubName), client_hub_name);
9590 		StrCpy(ipc_param.UserName, sizeof(ipc_param.UserName), auth_username);
9591 		CopyIP(&ipc_param.ClientIp, &w->Sock->RemoteIP);
9592 		ipc_param.ClientPort, w->Sock->RemotePort;
9593 		CopyIP(&ipc_param.ServerIp, &w->Sock->LocalIP);
9594 		ipc_param.ServerPort, w->Sock->LocalPort;
9595 		StrCpy(ipc_param.ClientHostname, sizeof(ipc_param.ClientHostname), w->Sock->RemoteHostname);
9596 		StrCpy(ipc_param.CryptName, sizeof(ipc_param.CryptName), w->Sock->CipherName);
9597 		ipc_param.Layer = IPC_LAYER_3; // TODO
9598 		ipc_param.BridgeMode = false; // TODO
9599 
9600 		// MSS
9601 		if (udp_accel != NULL) mss = MIN(mss, UdpAccelCalcMss(udp_accel));
9602 		if (mss == INFINITE)
9603 		{
9604 			mss = 0;
9605 		}
9606 		ipc_param.Mss = mss;
9607 
9608 		if (StrCmpi(auth_method, MVPN_AUTHTYPE_ANONYMOUS) == 0)
9609 		{
9610 			// Anonymous
9611 		}
9612 		else if (StrCmpi(auth_method, MVPN_AUTHTYPE_PASSWORD_PLAIN) == 0)
9613 		{
9614 			// Plaintext
9615 			char pw[MAX_PASSWORD_LEN + 1];
9616 			PackGetStr(client_auth, "AuthPlainPassword", pw, sizeof(pw));
9617 			StrCpy(ipc_param.Password, sizeof(ipc_param.Password), pw);
9618 		}
9619 		else
9620 		{
9621 			// Unknown auth method
9622 			auth_ret = ERR_AUTHTYPE_NOT_SUPPORTED;
9623 			goto LABEL_EXIT_AUTH_RETRY;
9624 		}
9625 
9626 		ipc_tmp = NewIPCByParam(c->Cedar, &ipc_param, &ipc_error_code);
9627 
9628 		if (ipc_tmp == NULL)
9629 		{
9630 			auth_ret = ipc_error_code;
9631 			goto LABEL_EXIT_AUTH_RETRY;
9632 		}
9633 		else
9634 		{
9635 			ipc = ipc_tmp;
9636 			auth_finish = true;
9637 		}
9638 
9639 		auth_ret = ERR_NO_ERROR;
9640 
9641 LABEL_EXIT_AUTH_RETRY:
9642 		if (auth_ret != ERR_NO_ERROR)
9643 		{
9644 			// Phase 4: Send a Server Auth Response
9645 			PACK *error_pack = WsNewErrorPack(auth_ret);
9646 			UINT remain_retry = MVPN_MAX_AUTH_RETRY - 1 - i;
9647 			PackAddInt(error_pack, "RetryAllowedCount", remain_retry);
9648 			WsSendPack(w, error_pack);
9649 			FreePack(error_pack);
9650 		}
9651 		FreePack(client_auth);
9652 		if (auth_finish)
9653 		{
9654 			break;
9655 		}
9656 	}
9657 
9658 	if (ipc != NULL)
9659 	{
9660 		AddProtocolDetailsStr(ipc->IpcSessionShared->ProtocolDetails, sizeof(ipc->IpcSessionShared->ProtocolDetails),
9661 			"ModernVPN");
9662 		AddProtocolDetailsKeyValueStr(ipc->IpcSessionShared->ProtocolDetails, sizeof(ipc->IpcSessionShared->ProtocolDetails),
9663 			"Transport", "TCP_WebSocket");
9664 	}
9665 
9666 	if (ipc != NULL && l3_ipv4_enable)
9667 	{
9668 		// L3 IPv4 helper is enabled
9669 		if (l3_ipv4_dynamic == false)
9670 		{
9671 			// Static IP
9672 			IPCSetIPv4Parameters(ipc, &l3_ipv4_ip, &l3_ipv4_mask,
9673 				&l3_ipv4_gw, NULL);
9674 		}
9675 		else
9676 		{
9677 			// Dynamic IP
9678 			DHCP_OPTION_LIST cao;
9679 
9680 			Zero(&cao, sizeof(cao));
9681 
9682 			if (IPCDhcpAllocateIP(ipc, &cao, NULL) == false)
9683 			{
9684 				// DHCP alloc failed
9685 				ret = ERR_DHCP_SERVER_NOT_RUNNING;
9686 				goto LABEL_CLEANUP;
9687 			}
9688 
9689 			l3_ipv4_dhcp_allocated = true;
9690 
9691 			UINTToIP(&l3_ipv4_dhcp_server, cao.ServerAddress);
9692 
9693 			UINTToIP(&l3_ipv4_ip, cao.ClientAddress);
9694 			UINTToIP(&l3_ipv4_mask, cao.SubnetMask);
9695 			UINTToIP(&l3_ipv4_gw, cao.Gateway);
9696 			UINTToIP(&l3_ipv4_dns1, cao.DnsServer);
9697 			UINTToIP(&l3_ipv4_dns2, cao.DnsServer2);
9698 			UINTToIP(&l3_ipv4_wins1, cao.WinsServer);
9699 			UINTToIP(&l3_ipv4_wins2, cao.WinsServer2);
9700 
9701 			BuildClasslessRouteTableStr(l3_ipv4_classless_routes, sizeof(l3_ipv4_classless_routes),
9702 				&cao.ClasslessRoute);
9703 
9704 			IPCSetIPv4Parameters(ipc, &l3_ipv4_ip, &l3_ipv4_mask,
9705 				&l3_ipv4_gw, &cao.ClasslessRoute);
9706 		}
9707 	}
9708 
9709 	if (ipc != NULL && use_udp_acceleration)
9710 	{
9711 		udp_accel = NewUdpAccel(c->Cedar, (c->FirstSock->IsRUDPSocket ? NULL : &c->FirstSock->LocalIP),
9712 			false, false, false);
9713 
9714 		udp_accel->Version = 2;
9715 
9716 		udp_accel->FastDetect = true;
9717 		udp_accel->ReadRawFlagMode = true;
9718 
9719 		if (UdpAccelInitServer(udp_accel, client_udp_acceleration_key,
9720 			&client_udp_acceleration_ip, client_udp_acceleration_port, NULL) == false)
9721 		{
9722 			FreeUdpAccel(udp_accel);
9723 			udp_accel = NULL;
9724 		}
9725 	}
9726 
9727 	if (ipc != NULL)
9728 	{
9729 		// Phase 4: Send auth OK response
9730 		PACK *ok_pack = WsNewErrorPack(ERR_NO_ERROR);
9731 		PackAddInt(ok_pack, "HeartBeatInterval", heartbeat_interval);
9732 		PackAddInt(ok_pack, "DisconnectTimeout", disconnect_timeout);
9733 		PackAddStr(ok_pack, "NetworkName", ipc->HubName);
9734 
9735 		if (udp_accel != NULL)
9736 		{
9737 			PackAddBool(ok_pack, "UseUdpAcceleration", true);
9738 			PackAddIp(ok_pack, "UdpAccelerationServerIp", &udp_accel->MyIp);
9739 			PackAddInt(ok_pack, "UdpAccelerationServerPort", udp_accel->MyPort);
9740 			PackAddData(ok_pack, "UdpAccelerationServerKey", udp_accel->MyKey_V2, sizeof(udp_accel->MyKey_V2));
9741 			PackAddInt(ok_pack, "UdpAccelerationServerCookie", udp_accel->MyCookie);
9742 			PackAddInt(ok_pack, "UdpAccelerationClientCookie", udp_accel->YourCookie);
9743 		}
9744 		else
9745 		{
9746 			PackAddBool(ok_pack, "UseUdpAcceleration", false);
9747 		}
9748 
9749 		PackAddBool(ok_pack, "L3HelperIPv4Enable", l3_ipv4_enable);
9750 
9751 		if (l3_ipv4_enable)
9752 		{
9753 			PackAddStr(ok_pack, "L3HelperIPv4AddressType",
9754 				l3_ipv4_dynamic ? MVPN_ADDRESS_TYPE_DYNAMIC : MVPN_ADDRESS_TYPE_STATIC);
9755 			PackAddIp(ok_pack, "L3HelperIPv4Address", &l3_ipv4_ip);
9756 			PackAddIp(ok_pack, "L3HelperIPv4SubnetMask", &l3_ipv4_mask);
9757 			PackAddIp(ok_pack, "L3HelperIPv4Gateway", &l3_ipv4_gw);
9758 			PackAddIp(ok_pack, "L3HelperIPv4DnsServer1", &l3_ipv4_dns1);
9759 			PackAddIp(ok_pack, "L3HelperIPv4DnsServer2", &l3_ipv4_dns2);
9760 			PackAddIp(ok_pack, "L3HelperIPv4WinsServer1", &l3_ipv4_wins1);
9761 			PackAddIp(ok_pack, "L3HelperIPv4WinsServer2", &l3_ipv4_wins2);
9762 			PackAddStr(ok_pack, "L3HelperIPv4PushedStaticRoutes", l3_ipv4_classless_routes);
9763 		}
9764 
9765 		WsSendPack(w, ok_pack);
9766 		FreePack(ok_pack);
9767 
9768 		// Session main loop
9769 		if (true)
9770 		{
9771 			SOCK *sock = w->Sock;
9772 			SOCK_EVENT *sock_event = NewSockEvent();
9773 			FIFO *send_fifo = NewFifo();
9774 			FIFO *recv_fifo = NewFifo();
9775 			bool has_error = false;
9776 			UINT magic_number = Endian32(MVPN_PACKET_MAGIC_NUMBER);
9777 			UINT64 last_sent_heartbeat = 0;
9778 			UINT tmp_buf_size = 256000;
9779 			UCHAR *tmp_buf = ZeroMalloc(tmp_buf_size);
9780 			UINT64 last_comm_recv = Tick64();
9781 
9782 			SetTimeout(sock, TIMEOUT_INFINITE);
9783 			JoinSockToSockEvent(sock, sock_event);
9784 			if (udp_accel != NULL)
9785 			{
9786 				JoinSockToSockEvent(udp_accel->UdpSock, sock_event);
9787 			}
9788 			IPCSetSockEventWhenRecvL2Packet(ipc, sock_event);
9789 
9790 			while (true)
9791 			{
9792 				UINT next_interval = INFINITE;
9793 				UINT send_ret = 0;
9794 				UINT64 now = Tick64();
9795 				UINT r;
9796 
9797 				if (udp_accel != NULL)
9798 				{
9799 					UdpAccelSetTick(udp_accel, now);
9800 					UdpAccelPoll(udp_accel);
9801 					ipc->IpcSessionShared->EnableUdpAccel = true;
9802 					ipc->IpcSessionShared->UsingUdpAccel = UdpAccelIsSendReady(udp_accel, true);
9803 				}
9804 				else
9805 				{
9806 					ipc->IpcSessionShared->EnableUdpAccel = false;
9807 					ipc->IpcSessionShared->UsingUdpAccel = false;
9808 				}
9809 
9810 				// Send heartbeat
9811 				if (last_sent_heartbeat == 0 || (last_sent_heartbeat + (UINT64)heartbeat_interval) <= now)
9812 				{
9813 					last_sent_heartbeat = now;
9814 					if (FifoSize(send_fifo) <= MAX_BUFFERING_PACKET_SIZE)
9815 					{
9816 						UCHAR packet_type = MVPN_PACKET_TYPE_HEARTBEAT;
9817 						USHORT packet_size = 0;
9818 						WriteFifo(send_fifo, &magic_number, 4);
9819 						WriteFifo(send_fifo, &packet_type, 1);
9820 						WriteFifo(send_fifo, &packet_size, 2);
9821 					}
9822 				}
9823 
9824 				// IPC --> send_fifo or UDP accelerator
9825 				if (l3_ipv4_enable == false)
9826 				{
9827 					// Ethernet
9828 					while (true)
9829 					{
9830 						BLOCK *l2_packet = IPCRecvL2(ipc);
9831 						UCHAR packet_type;
9832 						USHORT packet_size;
9833 						if (l2_packet == NULL)
9834 						{
9835 							break;
9836 						}
9837 						if (UdpAccelIsSendReady(udp_accel, true))
9838 						{
9839 							// Send via UDP accelerator
9840 							UdpAccelSend(udp_accel, l2_packet->Buf, l2_packet->Size,
9841 								MVPN_PACKET_TYPE_ETHERNET, udp_accel->MaxUdpPacketSize,
9842 								false);
9843 						}
9844 						else
9845 						{
9846 							// Send via WebSocket
9847 							if (FifoSize(send_fifo) <= MAX_BUFFERING_PACKET_SIZE)
9848 							{
9849 								packet_size = Endian16(l2_packet->Size);
9850 								packet_type = MVPN_PACKET_TYPE_ETHERNET;
9851 								WriteFifo(send_fifo, &magic_number, 4);
9852 								WriteFifo(send_fifo, &packet_type, 1);
9853 								WriteFifo(send_fifo, &packet_size, 2);
9854 								WriteFifo(send_fifo, l2_packet->Buf, (USHORT)l2_packet->Size);
9855 							}
9856 						}
9857 						FreeBlock(l2_packet);
9858 					}
9859 				}
9860 				else
9861 				{
9862 					UINT num = 0;
9863 
9864 L_V4_RETRY:
9865 					// IPv4
9866 					IPCProcessL3Events(ipc);
9867 
9868 					while (true)
9869 					{
9870 						BLOCK *l3_packet = IPCRecvIPv4(ipc);
9871 						UCHAR packet_type;
9872 						USHORT packet_size;
9873 						if (l3_packet == NULL)
9874 						{
9875 							num++;
9876 							if (num <= 1)
9877 							{
9878 								goto L_V4_RETRY;
9879 							}
9880 							break;
9881 						}
9882 						if (UdpAccelIsSendReady(udp_accel, true))
9883 						{
9884 							// Send via UDP accelerator
9885 							UdpAccelSend(udp_accel, l3_packet->Buf, l3_packet->Size,
9886 								MVPN_PACKET_TYPE_IPV4, udp_accel->MaxUdpPacketSize,
9887 								false);
9888 						}
9889 						else
9890 						{
9891 							// Send via WebSocket
9892 							if (FifoSize(send_fifo) <= MAX_BUFFERING_PACKET_SIZE)
9893 							{
9894 								packet_size = Endian16(l3_packet->Size);
9895 								packet_type = MVPN_PACKET_TYPE_IPV4;
9896 								WriteFifo(send_fifo, &magic_number, 4);
9897 								WriteFifo(send_fifo, &packet_type, 1);
9898 								WriteFifo(send_fifo, &packet_size, 2);
9899 								WriteFifo(send_fifo, l3_packet->Buf, (USHORT)l3_packet->Size);
9900 							}
9901 						}
9902 						FreeBlock(l3_packet);
9903 					}
9904 				}
9905 
9906 				// send_fifo --> MVPN Client
9907 				while (FifoSize(send_fifo) >= 1)
9908 				{
9909 					UINT r = WsSendAsync(w, ((UCHAR *)send_fifo->p) + send_fifo->pos, send_fifo->size);
9910 					if (r == 0)
9911 					{
9912 						has_error = true;
9913 						break;
9914 					}
9915 					else if (r == INFINITE)
9916 					{
9917 						break;
9918 					}
9919 					else
9920 					{
9921 						ReadFifo(send_fifo, NULL, r);
9922 					}
9923 				}
9924 
9925 				if (WsTrySendAsync(w) == false)
9926 				{
9927 					has_error = true;
9928 				}
9929 
9930 				// MVPN Client --> recv_fifo
9931 				while (FifoSize(recv_fifo) <= MAX_BUFFERING_PACKET_SIZE)
9932 				{
9933 					r = WsRecvAsync(w, tmp_buf, tmp_buf_size);
9934 					if (r == 0)
9935 					{
9936 						has_error = true;
9937 						break;
9938 					}
9939 					else if (r == INFINITE)
9940 					{
9941 						break;
9942 					}
9943 					else
9944 					{
9945 						//Debug("recv %u\n", r);
9946 						WriteFifo(recv_fifo, tmp_buf, r);
9947 					}
9948 				}
9949 
9950 				// recv_fifo --> IPC
9951 				while (true)
9952 				{
9953 					UINT u32;
9954 					UINT packet_size;
9955 					UCHAR packet_type;
9956 					UCHAR *packet_data;
9957 					if (FifoSize(recv_fifo) < 7)
9958 					{
9959 						break;
9960 					}
9961 					packet_size = READ_USHORT(FifoPtr(recv_fifo) + 5);
9962 					if (FifoSize(recv_fifo) < (7 + packet_size))
9963 					{
9964 						break;
9965 					}
9966 
9967 					ReadFifo(recv_fifo, &u32, 4);
9968 					if (u32 != magic_number)
9969 					{
9970 						break;
9971 					}
9972 
9973 					ReadFifo(recv_fifo, &packet_type, 1);
9974 					ReadFifo(recv_fifo, NULL, 2);
9975 
9976 					packet_data = Malloc(packet_size);
9977 
9978 					ReadFifo(recv_fifo, packet_data, packet_size);
9979 
9980 					if (packet_type == MVPN_PACKET_TYPE_ETHERNET)
9981 					{
9982 						if (l3_ipv4_enable == false)
9983 						{
9984 							IPCSendL2(ipc, packet_data, packet_size);
9985 						}
9986 					}
9987 					else if (packet_type == MVPN_PACKET_TYPE_IPV4)
9988 					{
9989 						if (l3_ipv4_enable)
9990 						{
9991 							IPCSendIPv4(ipc, packet_data, packet_size);
9992 						}
9993 					}
9994 
9995 					Free(packet_data);
9996 
9997 					last_comm_recv = now;
9998 				}
9999 
10000 				// UDP Accel --> IPC
10001 				if (udp_accel != NULL)
10002 				{
10003 					while (true)
10004 					{
10005 						UINT packet_size;
10006 						UCHAR packet_type;
10007 						UCHAR *packet_data;
10008 						BLOCK *b = GetNext(udp_accel->RecvBlockQueue);
10009 						if (b == NULL)
10010 						{
10011 							break;
10012 						}
10013 
10014 						packet_type = b->RawFlagRetUdpAccel;
10015 						packet_data = b->Buf;
10016 						packet_size = b->Size;
10017 
10018 						if (packet_type == MVPN_PACKET_TYPE_ETHERNET)
10019 						{
10020 							if (l3_ipv4_enable == false)
10021 							{
10022 								IPCSendL2(ipc, packet_data, packet_size);
10023 							}
10024 						}
10025 						else if (packet_type == MVPN_PACKET_TYPE_IPV4)
10026 						{
10027 							if (l3_ipv4_enable)
10028 							{
10029 								IPCSendIPv4(ipc, packet_data, packet_size);
10030 							}
10031 						}
10032 
10033 						FreeBlock(b);
10034 					}
10035 				}
10036 
10037 				if (IsIPCConnected(ipc) == false)
10038 				{
10039 					has_error = true;
10040 				}
10041 
10042 				if (now > (last_comm_recv + (UINT64)disconnect_timeout))
10043 				{
10044 					has_error = true;
10045 				}
10046 
10047 				IPCProcessInterrupts(ipc);
10048 
10049 				if (has_error)
10050 				{
10051 					break;
10052 				}
10053 
10054 				// Wait until the next event occurs
10055 				next_interval = GetNextIntervalForInterrupt(ipc->Interrupt);
10056 				next_interval = MIN(next_interval, SELECT_TIME);
10057 				next_interval = MIN(next_interval, (UINT)((last_sent_heartbeat + (UINT64)heartbeat_interval) - now));
10058 				WaitSockEvent(sock_event, next_interval);
10059 			}
10060 
10061 			ReleaseSockEvent(sock_event);
10062 			ReleaseFifo(send_fifo);
10063 			ReleaseFifo(recv_fifo);
10064 			Free(tmp_buf);
10065 		}
10066 	}
10067 
10068 	if (l3_ipv4_dhcp_allocated)
10069 	{
10070 		IPCDhcpFreeIP(ipc, &l3_ipv4_dhcp_server);
10071 		IPCProcessL3Events(ipc);
10072 	}
10073 
10074 LABEL_CLEANUP:
10075 	if (ret != ERR_NO_ERROR)
10076 	{
10077 		PACK *ret_pack = WsNewErrorPack(ret);
10078 		WsSendPack(w, ret_pack);
10079 		FreePack(ret_pack);
10080 	}
10081 	FreeUdpAccel(udp_accel);
10082 	FreeIPC(ipc);
10083 	FreePack(client_hello);
10084 	FreePack(server_hello);
10085 
10086 	return 0;
10087 }
10088 
10089 
10090 
10091 
10092 
10093 
10094 
10095 
10096