1 // CoreUtil 2 // 3 // Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved. 4 // Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved. 5 // 6 // License: The Apache License, Version 2.0 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // DISCLAIMER 10 // ========== 11 // 12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 // SOFTWARE. 19 // 20 // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER 21 // JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH, 22 // DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY 23 // JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS, 24 // AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER 25 // SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND 26 // OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, 27 // AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND 28 // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE 29 // JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE 30 // ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS. 31 // PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE 32 // LAW OR COURT RULE. 33 // 34 // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE 35 // A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL 36 // RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS 37 // COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND 38 // DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING 39 // CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER 40 // COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES. 41 // WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR 42 // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES 43 // AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH 44 // DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS 45 // AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE 46 // PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A 47 // PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE 48 // LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL 49 // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A 50 // STATEMENT FOR WARNING AND DISCLAIMER. 51 // 52 // READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE. 53 // SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH 54 // LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE. 55 // 56 // 57 // SOURCE CODE CONTRIBUTION 58 // ------------------------ 59 // 60 // Your contribution to SoftEther VPN Project is much appreciated. 61 // Please send patches to us through GitHub. 62 // Read the SoftEther VPN Patch Acceptance Policy in advance: 63 // http://www.softether.org/5-download/src/9.patch 64 // 65 // 66 // DEAR SECURITY EXPERTS 67 // --------------------- 68 // 69 // If you find a bug or a security vulnerability please kindly inform us 70 // about the problem immediately so that we can fix the security problem 71 // to protect a lot of users around the world as soon as possible. 72 // 73 // Our e-mail address for security reports is: 74 // softether-vpn-security [at] softether.org 75 // 76 // Please note that the above e-mail address is not a technical support 77 // inquiry address. If you need technical assistance, please visit 78 // http://www.softether.org/ and ask your question on the users forum. 79 // 80 // Thank you for your cooperation. 81 // 82 // 83 // NO MEMORY OR RESOURCE LEAKS 84 // --------------------------- 85 // 86 // The memory-leaks and resource-leaks verification under the stress 87 // test has been passed before release this source code. 88 89 90 using System; 91 using System.Threading; 92 using System.Data; 93 using System.Data.Sql; 94 using System.Data.SqlClient; 95 using System.Data.SqlTypes; 96 using System.Text; 97 using System.Configuration; 98 using System.Collections; 99 using System.Collections.Generic; 100 using System.Security.Cryptography; 101 using System.Web; 102 using System.Web.Security; 103 using System.Web.UI; 104 using System.Web.UI.WebControls; 105 using System.Web.UI.WebControls.WebParts; 106 using System.Web.UI.HtmlControls; 107 using System.IO; 108 using System.Drawing; 109 using System.Drawing.Imaging; 110 using System.Drawing.Drawing2D; 111 using System.Runtime.InteropServices; 112 113 namespace CoreUtil 114 { 115 [StructLayout(LayoutKind.Sequential, Pack = 1)] 116 public struct ZipDataHeader 117 { 118 public uint Signature; 119 public ushort NeedVer; 120 public ushort Option; 121 public ushort CompType; 122 public ushort FileTime; 123 public ushort FileDate; 124 public uint Crc32; 125 public uint CompSize; 126 public uint UncompSize; 127 public ushort FileNameLen; 128 public ushort ExtraLen; 129 } 130 131 [StructLayout(LayoutKind.Sequential, Pack = 1)] 132 public struct ZipDataFooter 133 { 134 public uint Signature; 135 public uint Crc32; 136 public uint CompSize; 137 public uint UncompSize; 138 } 139 140 [StructLayout(LayoutKind.Sequential, Pack = 1)] 141 public struct ZipDirHeader 142 { 143 public uint Signature; 144 public ushort MadeVer; 145 public ushort NeedVer; 146 public ushort Option; 147 public ushort CompType; 148 public ushort FileTime; 149 public ushort FileDate; 150 public uint Crc32; 151 public uint CompSize; 152 public uint UncompSize; 153 public ushort FileNameLen; 154 public ushort ExtraLen; 155 public ushort CommentLen; 156 public ushort DiskNum; 157 public ushort InAttr; 158 public uint OutAttr; 159 public uint HeaderPos; 160 } 161 162 [StructLayout(LayoutKind.Sequential, Pack = 1)] 163 public struct ZipEndHeader 164 { 165 public uint Signature; 166 public ushort DiskNum; 167 public ushort StartDiskNum; 168 public ushort DiskDirEntry; 169 public ushort DirEntry; 170 public uint DirSize; 171 public uint StartPos; 172 public ushort CommentLen; 173 } 174 175 public static class ZipUtil 176 { ZipUtil()177 static ZipUtil() 178 { 179 initCrc32(); 180 } 181 182 static uint[] table; 183 const int crcTableSize = 256; 184 initCrc32()185 static void initCrc32() 186 { 187 table = new uint[crcTableSize]; 188 189 uint poly = 0xEDB88320; 190 uint u, i, j; 191 192 for (i = 0; i < 256; i++) 193 { 194 u = i; 195 196 for (j = 0; j < 8; j++) 197 { 198 if ((u & 0x1) != 0) 199 { 200 u = (u >> 1) ^ poly; 201 } 202 else 203 { 204 u >>= 1; 205 } 206 } 207 208 table[i] = u; 209 } 210 } 211 Crc32(byte[] buf)212 public static uint Crc32(byte[] buf) 213 { 214 return Crc32(buf, 0, buf.Length); 215 } Crc32(byte[] buf, int pos, int len)216 public static uint Crc32(byte[] buf, int pos, int len) 217 { 218 return Crc32Finish(Crc32First(buf, pos, len)); 219 } Crc32First(byte[] buf, int pos, int len)220 public static uint Crc32First(byte[] buf, int pos, int len) 221 { 222 return Crc32Next(buf, pos, len, 0xffffffff); 223 } Crc32Next(byte[] buf, int pos, int len, uint lastCrc32)224 public static uint Crc32Next(byte[] buf, int pos, int len, uint lastCrc32) 225 { 226 uint ret = lastCrc32; 227 for (uint i = 0; i < len; i++) 228 { 229 ret = (ret >> 8) ^ table[buf[pos + i] ^ (ret & 0xff)]; 230 } 231 return ret; 232 } Crc32Finish(uint lastCrc32)233 public static uint Crc32Finish(uint lastCrc32) 234 { 235 return ~lastCrc32; 236 } 237 } 238 239 public class ZipPacker 240 { 241 public const uint Signature = 0x04034B50; 242 public const uint SignatureEnd = 0x06054B50; 243 public const ushort Version = 10; 244 public const ushort VersionWithCompress = 20; 245 public Encoding Encoding = Str.ShiftJisEncoding; 246 247 class File 248 { 249 public string Name; 250 public long Size; 251 public DateTime DateTime; 252 public FileAttributes Attributes; 253 public long CurrentSize; 254 public long CompressSize; 255 public uint Crc32; 256 public uint HeaderPos; 257 public Encoding Encoding; 258 public bool Compress; 259 public CoreUtil.Internal.ZStream ZStream; 260 WriteZipDataHeader(ref ZipDataHeader h, bool writeSizes)261 public void WriteZipDataHeader(ref ZipDataHeader h, bool writeSizes) 262 { 263 h.Signature = Signature; 264 h.NeedVer = Version; 265 h.CompType = 0; 266 h.FileTime = Util.DateTimeToDosTime(this.DateTime); 267 h.FileDate = Util.DateTimeToDosDate(this.DateTime); 268 h.Option = 8; 269 270 if (writeSizes == false) 271 { 272 h.CompSize = h.UncompSize = 0; 273 h.Crc32 = 0; 274 275 if (this.Compress) 276 { 277 h.NeedVer = VersionWithCompress; 278 h.CompType = 8; 279 } 280 } 281 else 282 { 283 h.CompSize = h.UncompSize = (uint)this.Size; 284 if (this.Compress) 285 { 286 h.CompSize = (uint)this.CompressSize; 287 h.CompType = 8; 288 } 289 h.Crc32 = this.Crc32; 290 } 291 292 h.FileNameLen = (ushort)this.Encoding.GetByteCount(this.Name); 293 h.ExtraLen = 0; 294 } 295 WriteZipDataFooter(ref ZipDataFooter h)296 public void WriteZipDataFooter(ref ZipDataFooter h) 297 { 298 h.Signature = 0x08074B50; 299 300 if (this.Compress == false) 301 { 302 h.CompSize = h.UncompSize = (uint)this.Size; 303 } 304 else 305 { 306 h.CompSize = (uint)this.CompressSize; 307 h.UncompSize = (uint)this.Size; 308 } 309 h.Crc32 = this.Crc32; 310 } 311 } 312 313 Fifo fifo; 314 List<File> fileList; 315 316 public Fifo GeneratedData 317 { 318 get 319 { 320 return this.fifo; 321 } 322 } 323 ZipPacker()324 public ZipPacker() 325 { 326 fifo = new Fifo(); 327 fileList = new List<File>(); 328 } 329 330 File currentFile = null; 331 AddFileSimple(string name, DateTime dt, FileAttributes attribute, byte[] data)332 public void AddFileSimple(string name, DateTime dt, FileAttributes attribute, byte[] data) 333 { 334 AddFileSimple(name, dt, attribute, data, false); 335 } AddFileSimple(string name, DateTime dt, FileAttributes attribute, byte[] data, bool compress)336 public void AddFileSimple(string name, DateTime dt, FileAttributes attribute, byte[] data, bool compress) 337 { 338 AddFileStart(name, data.Length, dt, attribute, compress); 339 AddFileData(data, 0, data.Length); 340 } 341 AddFileStart(string name, long size, DateTime dt, FileAttributes attribute)342 public void AddFileStart(string name, long size, DateTime dt, FileAttributes attribute) 343 { 344 AddFileStart(name, size, dt, attribute, false); 345 } AddFileStart(string name, long size, DateTime dt, FileAttributes attribute, bool compress)346 public void AddFileStart(string name, long size, DateTime dt, FileAttributes attribute, bool compress) 347 { 348 if (currentFile != null) 349 { 350 throw new ApplicationException("currentFile != null"); 351 } 352 353 name = name.Replace("/", "\\"); 354 355 File f = new File(); 356 357 f.Encoding = this.Encoding; 358 f.Name = name; 359 f.Size = size; 360 f.DateTime = dt; 361 f.Attributes = attribute; 362 f.Compress = compress; 363 364 this.fileList.Add(f); 365 366 ZipDataHeader h = new ZipDataHeader(); 367 f.HeaderPos = (uint)fifo.TotalWriteSize; 368 f.WriteZipDataHeader(ref h, false); 369 fifo.Write(Util.StructToByte(h)); 370 fifo.Write(this.Encoding.GetBytes(f.Name)); 371 f.Crc32 = 0xffffffff; 372 373 if (compress) 374 { 375 f.ZStream = new CoreUtil.Internal.ZStream(); 376 f.ZStream.deflateInit(-1, -15); 377 } 378 379 currentFile = f; 380 } 381 AddFileData(byte[] data, int pos, int len)382 public long AddFileData(byte[] data, int pos, int len) 383 { 384 long totalSize = currentFile.CurrentSize + len; 385 386 if (totalSize > currentFile.Size) 387 { 388 throw new ApplicationException("totalSize > currentFile.Size"); 389 } 390 391 if (currentFile.Compress == false) 392 { 393 fifo.Write(data, pos, len); 394 } 395 else 396 { 397 CoreUtil.Internal.ZStream zs = currentFile.ZStream; 398 399 byte[] srcData = Util.ExtractByteArray(data, pos, len); 400 byte[] dstData = new byte[srcData.Length * 2 + 100]; 401 402 zs.next_in = srcData; 403 zs.avail_in = srcData.Length; 404 zs.next_in_index = 0; 405 406 zs.next_out = dstData; 407 zs.avail_out = dstData.Length; 408 zs.next_out_index = 0; 409 410 if (currentFile.Size == (currentFile.CurrentSize + len)) 411 { 412 zs.deflate(CoreUtil.Internal.zlibConst.Z_FINISH); 413 } 414 else 415 { 416 zs.deflate(CoreUtil.Internal.zlibConst.Z_SYNC_FLUSH); 417 } 418 419 fifo.Write(dstData, 0, dstData.Length - zs.avail_out); 420 421 currentFile.CompressSize += dstData.Length - zs.avail_out; 422 423 Util.NoOP(); 424 } 425 426 currentFile.CurrentSize += len; 427 428 currentFile.Crc32 = ZipUtil.Crc32Next(data, pos, len, currentFile.Crc32); 429 430 long ret = currentFile.Size - currentFile.CurrentSize; 431 432 if (ret == 0) 433 { 434 currentFile.Crc32 = ~currentFile.Crc32; 435 addFileFooter(); 436 437 currentFile = null; 438 } 439 440 return ret; 441 } 442 addFileFooter()443 void addFileFooter() 444 { 445 ZipDataFooter f = new ZipDataFooter(); 446 currentFile.WriteZipDataFooter(ref f); 447 fifo.Write(Util.StructToByte(f)); 448 } 449 Finish()450 public void Finish() 451 { 452 long posStart = fifo.TotalWriteSize; 453 foreach (File f in this.fileList) 454 { 455 ZipDirHeader d = new ZipDirHeader(); 456 d.Signature = 0x02014B50;// ZipPacker.Signature; 457 d.MadeVer = Version; 458 ZipDataHeader dh = new ZipDataHeader(); 459 f.WriteZipDataHeader(ref dh, true); 460 if (f.Compress) 461 { 462 dh.CompType = 8; 463 dh.CompSize = (uint)f.CompressSize; 464 dh.NeedVer = ZipPacker.VersionWithCompress; 465 } 466 d.NeedVer = dh.NeedVer; 467 d.Option = dh.Option; 468 d.CompType = dh.CompType; 469 d.FileTime = dh.FileTime; 470 d.FileDate = dh.FileDate; 471 d.Crc32 = dh.Crc32; 472 d.CompSize = dh.CompSize; 473 d.UncompSize = dh.UncompSize; 474 d.FileNameLen = dh.FileNameLen; 475 d.ExtraLen = dh.ExtraLen; 476 d.CommentLen = 0; 477 d.DiskNum = 0; 478 d.InAttr = 0; 479 d.OutAttr = (ushort)f.Attributes; 480 d.HeaderPos = f.HeaderPos; 481 482 fifo.Write(Util.StructToByte(d)); 483 fifo.Write(this.Encoding.GetBytes(f.Name)); 484 } 485 long posEnd = fifo.TotalWriteSize; 486 487 ZipEndHeader e = new ZipEndHeader(); 488 e.Signature = ZipPacker.SignatureEnd; 489 e.DiskNum = e.StartDiskNum = 0; 490 e.DiskDirEntry = e.DirEntry = (ushort)this.fileList.Count; 491 e.DirSize = (uint)(posEnd - posStart); 492 e.StartPos = (uint)posStart; 493 e.CommentLen = 0; 494 fifo.Write(Util.StructToByte(e)); 495 } 496 } 497 } 498