1 // SoftEther UT-VPN SourceCode
\r
3 // Copyright (C) 2004-2010 SoftEther Corporation.
\r
4 // Copyright (C) 2004-2010 University of Tsukuba, Japan.
\r
5 // Copyright (C) 2003-2010 Daiyuu Nobori.
\r
6 // All Rights Reserved.
\r
8 // http://utvpn.tsukuba.ac.jp/
\r
10 // This program is free software; you can redistribute it and/or
\r
11 // modify it under the terms of the GNU General Public License
\r
12 // version 2 as published by the Free Software Foundation.
\r
14 // This program is distributed in the hope that it will be useful,
\r
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
17 // GNU General Public License for more details.
\r
19 // You should have received a copy of the GNU General Public License version 2
\r
20 // along with this program; if not, write to the Free Software
\r
21 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\r
23 // このファイルは GPL バージョン 2 ライセンスで公開されています。
\r
24 // 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
\r
25 // することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
\r
26 // を除去することはできません。改変した著作物を配布する場合は、改変実施者の
\r
27 // 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
\r
29 // この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
\r
30 // ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
\r
31 // および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
\r
33 // 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
\r
34 // および、試験または研究のために利用が行われることを想定して配布
\r
36 // SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
\r
38 // 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
\r
39 // の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
\r
40 // いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
\r
41 // ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
\r
44 // GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
\r
45 // 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
\r
47 // 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
\r
48 // (SoftEther Corporation) およびその他の著作権保持者が保有しています。
\r
49 // ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
\r
50 // 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
\r
53 // お願い: どのような通信ソフトウェアにも通常は必ず未発見の
\r
54 // セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
\r
55 // UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
\r
56 // 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
\r
57 // および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
\r
58 // 公益保護にご協力いただきますようお願い申し上げます。
\r
60 // ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
\r
61 // 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
\r
64 // ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
\r
65 // 日本国内の脆弱性情報届出受付公的機関:
\r
67 // http://www.ipa.go.jp/security/vuln/report/
\r
69 // 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
\r
70 // 連絡先: http://www.softether.co.jp/jp/contact/
\r
72 // -----------------------------------------------
\r
75 // 新規リリース by SoftEther
\r
76 // -----------------------------------------------
\r
79 // 文字列テーブル読み込み & 管理ルーチン
\r
88 #include <Mayaqua/Mayaqua.h>
\r
91 static LIST *TableList = NULL;
\r
92 static wchar_t old_table_name[MAX_SIZE] = {0}; // 古いテーブル名
\r
94 // エラー文字列を Unicode で取得する
\r
95 wchar_t *GetUniErrorStr(UINT err)
\r
98 char name[MAX_SIZE];
\r
99 Format(name, sizeof(name), "ERR_%u", err);
\r
101 ret = GetTableUniStr(name);
\r
102 if (UniStrLen(ret) != 0)
\r
108 return _UU("ERR_UNKNOWN");
\r
113 char *GetErrorStr(UINT err)
\r
116 char name[MAX_SIZE];
\r
117 Format(name, sizeof(name), "ERR_%u", err);
\r
119 ret = GetTableStr(name);
\r
120 if (StrLen(ret) != 0)
\r
126 return _SS("ERR_UNKNOWN");
\r
131 UINT GetTableInt(char *name)
\r
140 str = GetTableStr(name);
\r
144 // テーブルから Unicode 文字列をロードする
\r
145 wchar_t *GetTableUniStr(char *name)
\r
151 // Debug("%s: ************\n", name);
\r
156 t = FindTable(name);
\r
159 // Debug("%s: UNICODE STRING NOT FOUND\n", name);
\r
167 char *GetTableStr(char *name)
\r
177 if (StrCmpi(name, "DEFAULT_FONT") == 0)
\r
179 if (_II("LANG") == 2)
\r
181 UINT os_type = GetOsType();
\r
182 if (OS_IS_WINDOWS_9X(os_type) ||
\r
183 GET_KETA(os_type, 100) <= 4)
\r
185 // Windows 9x, Windows NT 4.0, Windows 2000, Windows XP, Windows Server 2003 の場合は SimSun フォントを利用する
\r
193 t = FindTable(name);
\r
196 // Debug("%s: ANSI STRING NOT FOUND\n", name);
\r
203 // 指定した名前で始まる文字列名を取得する
\r
204 TOKEN_LIST *GetTableNameStartWith(char *str)
\r
210 char tmp[MAX_SIZE];
\r
214 return NullToken();
\r
217 StrCpy(tmp, sizeof(tmp), str);
\r
222 o = NewListFast(NULL);
\r
224 for (i = 0;i < LIST_NUM(TableList);i++)
\r
226 TABLE *t = LIST_DATA(TableList, i);
\r
227 UINT len2 = StrLen(t->name);
\r
231 if (Cmp(t->name, tmp, len) == 0)
\r
233 Insert(o, CopyStr(t->name));
\r
238 t = ZeroMalloc(sizeof(TOKEN_LIST));
\r
239 t->NumTokens = LIST_NUM(o);
\r
240 t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
\r
242 for (i = 0;i < t->NumTokens;i++)
\r
244 t->Token[i] = LIST_DATA(o, i);
\r
253 TABLE *FindTable(char *name)
\r
257 if (name == NULL || TableList == NULL)
\r
262 tt.name = CopyStr(name);
\r
263 t = Search(TableList, &tt);
\r
270 int CmpTableName(void *p1, void *p2)
\r
273 if (p1 == NULL || p2 == NULL)
\r
277 t1 = *(TABLE **)p1;
\r
278 t2 = *(TABLE **)p2;
\r
279 if (t1 == NULL || t2 == NULL)
\r
284 return StrCmpi(t1->name, t2->name);
\r
288 TABLE *ParseTableLine(char *line, char *prefix, UINT prefix_size)
\r
298 UINT unistr_size, str_size;
\r
301 if (line == NULL || prefix == NULL)
\r
308 len = StrLen(line);
\r
315 if (line[0] == '#' || (line[0] == '/' && line[1] == '/'))
\r
329 if (line[i] == ' ' || line[i] == '\t')
\r
336 name = Malloc(len_name + 1);
\r
337 StrCpy(name, len_name + 1, line);
\r
339 string_start = len_name;
\r
340 for (i = len_name;i < len;i++)
\r
342 if (line[i] != ' ' && line[i] != '\t')
\r
355 UnescapeStr(&line[string_start]);
\r
358 unistr_size = CalcUtf8ToUni(&line[string_start], StrLen(&line[string_start]));
\r
359 if (unistr_size == 0)
\r
364 unistr = Malloc(unistr_size);
\r
365 Utf8ToUni(unistr, unistr_size, &line[string_start], StrLen(&line[string_start]));
\r
368 str_size = CalcUniToStr(unistr);
\r
377 str = Malloc(str_size);
\r
378 UniToStr(str, str_size, unistr);
\r
381 if (StrCmpi(name, "PREFIX") == 0)
\r
384 StrCpy(prefix, prefix_size, str);
\r
387 if (StrCmpi(prefix, "$") == 0 || StrCmpi(prefix, "NULL") == 0)
\r
399 name2_size = StrLen(name) + StrLen(prefix) + 2;
\r
400 name2 = ZeroMalloc(name2_size);
\r
402 if (prefix[0] != 0)
\r
404 StrCat(name2, name2_size, prefix);
\r
405 StrCat(name2, name2_size, "@");
\r
408 StrCat(name2, name2_size, name);
\r
413 t = Malloc(sizeof(TABLE));
\r
417 t->unistr = unistr;
\r
423 void UnescapeStr(char *src)
\r
434 tmp = Malloc(len + 1);
\r
436 for (i = 0;i < len;i++)
\r
438 if (src[i] == '\\')
\r
467 tmp[wp++] = src[i];
\r
472 StrCpy(src, 0, tmp);
\r
481 if (TableList == NULL)
\r
488 num = LIST_NUM(TableList);
\r
489 tables = ToArray(TableList);
\r
490 for (i = 0;i < num;i++)
\r
492 TABLE *t = tables[i];
\r
498 ReleaseList(TableList);
\r
502 Zero(old_table_name, sizeof(old_table_name));
\r
507 // バッファから文字列テーブルを読み込む
\r
508 bool LoadTableFromBuf(BUF *b)
\r
511 char prefix[MAX_SIZE];
\r
518 // すでにテーブルがある場合は削除する
\r
522 TableList = NewList(CmpTableName);
\r
524 Zero(prefix, sizeof(prefix));
\r
526 // バッファの内容を 1 行ずつ読んでいく
\r
530 tmp = CfgReadNextLine(b);
\r
535 t = ParseTableLine(tmp, prefix, sizeof(prefix));
\r
539 Insert(TableList, t);
\r
547 // Unicode 文字列キャッシュファイル名の生成
\r
548 void GenerateUnicodeCacheFileName(wchar_t *name, UINT size, wchar_t *strfilename, UINT strfilesize, UCHAR *filehash)
\r
550 wchar_t tmp[MAX_SIZE];
\r
551 wchar_t hashstr[64];
\r
552 wchar_t hashtemp[MAX_SIZE];
\r
553 wchar_t exe[MAX_SIZE];
\r
554 UCHAR hash[SHA1_SIZE];
\r
556 if (name == NULL || strfilename == NULL || filehash == NULL)
\r
561 GetExeDirW(exe, sizeof(exe));
\r
562 UniStrCpy(hashtemp, sizeof(hashtemp), strfilename);
\r
563 BinToStrW(tmp, sizeof(tmp), filehash, MD5_SIZE);
\r
564 UniStrCat(hashtemp, sizeof(hashtemp), tmp);
\r
565 UniStrCat(hashtemp, sizeof(hashtemp), exe);
\r
566 UniStrLower(hashtemp);
\r
568 Hash(hash, hashtemp, UniStrLen(hashtemp) * sizeof(wchar_t), true);
\r
569 BinToStrW(hashstr, sizeof(hashstr), hash, 4);
\r
570 UniFormat(tmp, sizeof(tmp), UNICODE_CACHE_FILE, hashstr);
\r
574 UniStrCpy(exe, sizeof(exe), L"/tmp");
\r
576 StrToUni(exe, sizeof(exe), MsGetTempDir());
\r
579 UniFormat(name, size, L"%s/%s", exe, tmp);
\r
580 NormalizePathW(name, size, name);
\r
583 // Unicode キャッシュの保存
\r
584 void SaveUnicodeCache(wchar_t *strfilename, UINT strfilesize, UCHAR *hash)
\r
590 wchar_t name[MAX_PATH];
\r
591 UCHAR binhash[MD5_SIZE];
\r
593 if (strfilename == NULL || hash == NULL)
\r
598 Zero(&c, sizeof(c));
\r
599 UniToStr(c.StrFileName, sizeof(c.StrFileName), strfilename);
\r
600 c.StrFileSize = strfilesize;
\r
601 GetMachineName(c.MachineName, sizeof(c.MachineName));
\r
602 c.OsType = GetOsInfo()->OsType;
\r
603 Copy(c.hash, hash, MD5_SIZE);
\r
606 GetCurrentCharSet(c.CharSet, sizeof(c.CharSet));
\r
609 UINT id = MsGetThreadLocale();
\r
610 Copy(c.CharSet, &id, sizeof(id));
\r
615 WriteBuf(b, &c, sizeof(c));
\r
617 WriteBufInt(b, LIST_NUM(TableList));
\r
618 for (i = 0;i < LIST_NUM(TableList);i++)
\r
620 TABLE *t = LIST_DATA(TableList, i);
\r
621 WriteBufInt(b, StrLen(t->name));
\r
622 WriteBuf(b, t->name, StrLen(t->name));
\r
623 WriteBufInt(b, StrLen(t->str));
\r
624 WriteBuf(b, t->str, StrLen(t->str));
\r
625 WriteBufInt(b, UniStrLen(t->unistr));
\r
626 WriteBuf(b, t->unistr, UniStrLen(t->unistr) * sizeof(wchar_t));
\r
629 Hash(binhash, b->Buf, b->Size, false);
\r
630 WriteBuf(b, binhash, MD5_SIZE);
\r
632 GenerateUnicodeCacheFileName(name, sizeof(name), strfilename, strfilesize, hash);
\r
634 io = FileCreateW(name);
\r
645 // Unicode キャッシュの読み込み
\r
646 bool LoadUnicodeCache(wchar_t *strfilename, UINT strfilesize, UCHAR *hash)
\r
648 UNICODE_CACHE c, t;
\r
652 wchar_t name[MAX_PATH];
\r
653 UCHAR binhash[MD5_SIZE];
\r
654 UCHAR binhash_2[MD5_SIZE];
\r
656 if (strfilename == NULL || hash == NULL)
\r
661 GenerateUnicodeCacheFileName(name, sizeof(name), strfilename, strfilesize, hash);
\r
663 io = FileOpenW(name, false);
\r
679 Hash(binhash, b->Buf, b->Size >= MD5_SIZE ? (b->Size - MD5_SIZE) : 0, false);
\r
680 Copy(binhash_2, ((UCHAR *)b->Buf) + (b->Size >= MD5_SIZE ? (b->Size - MD5_SIZE) : 0), MD5_SIZE);
\r
681 if (Cmp(binhash, binhash_2, MD5_SIZE) != 0)
\r
687 Zero(&c, sizeof(c));
\r
688 UniToStr(c.StrFileName, sizeof(c.StrFileName), strfilename);
\r
689 c.StrFileSize = strfilesize;
\r
690 DisableNetworkNameCache();
\r
691 GetMachineName(c.MachineName, sizeof(c.MachineName));
\r
692 EnableNetworkNameCache();
\r
693 c.OsType = GetOsInfo()->OsType;
\r
694 Copy(c.hash, hash, MD5_SIZE);
\r
697 GetCurrentCharSet(c.CharSet, sizeof(c.CharSet));
\r
700 UINT id = MsGetThreadLocale();
\r
701 Copy(c.CharSet, &id, sizeof(id));
\r
705 Zero(&t, sizeof(t));
\r
706 ReadBuf(b, &t, sizeof(t));
\r
708 if (Cmp(&c, &t, sizeof(UNICODE_CACHE)) != 0)
\r
714 num = ReadBufInt(b);
\r
717 TableList = NewList(CmpTableName);
\r
719 for (i = 0;i < num;i++)
\r
722 TABLE *t = ZeroMalloc(sizeof(TABLE));
\r
724 len = ReadBufInt(b);
\r
725 t->name = ZeroMalloc(len + 1);
\r
726 ReadBuf(b, t->name, len);
\r
728 len = ReadBufInt(b);
\r
729 t->str = ZeroMalloc(len + 1);
\r
730 ReadBuf(b, t->str, len);
\r
732 len = ReadBufInt(b);
\r
733 t->unistr = ZeroMalloc((len + 1) * sizeof(wchar_t));
\r
734 ReadBuf(b, t->unistr, len * sizeof(wchar_t));
\r
747 bool LoadTableMain(wchar_t *filename)
\r
751 UCHAR hash[MD5_SIZE];
\r
753 if (filename == NULL)
\r
758 if (MayaquaIsMinimalMode())
\r
763 if (UniStrCmpi(old_table_name, filename) == 0)
\r
772 b = ReadDumpW(filename);
\r
775 char tmp[MAX_SIZE];
\r
776 StrCpy(tmp, sizeof(tmp), "Error: Can't read string tables (file not found).\r\nPlease check hamcore.utvpn.\r\n\r\n(First, reboot the computer. If this problem occurs again, please reinstall VPN software files.)");
\r
782 Hash(hash, b->Buf, b->Size, false);
\r
784 if (LoadUnicodeCache(filename, b->Size, hash) == false)
\r
786 if (LoadTableFromBuf(b) == false)
\r
792 SaveUnicodeCache(filename, b->Size, hash);
\r
794 Debug("Unicode Source: strtable.stb\n");
\r
798 Debug("Unicode Source: unicode_cache\n");
\r
803 SetLocale(_UU("DEFAULE_LOCALE"));
\r
805 UniStrCpy(old_table_name, sizeof(old_table_name), filename);
\r
809 if (StrCmpi(_SS("STRTABLE_ID"), STRTABLE_ID) != 0)
\r
811 char tmp[MAX_SIZE];
\r
812 StrCpy(tmp, sizeof(tmp), "Error: Can't read string tables (invalid version).\r\nPlease check hamcore.utvpn.\r\n\r\n(First, reboot the computer. If this problem occurs again, please reinstall VPN software files.)");
\r
818 Debug("Unicode File Read Cost: %u (%u Lines)\n", (UINT)(t2 - t1), LIST_NUM(TableList));
\r
822 bool LoadTable(char *filename)
\r
824 wchar_t *filename_a = CopyStrToUni(filename);
\r
825 bool ret = LoadTableW(filename_a);
\r
831 bool LoadTableW(wchar_t *filename)
\r
835 wchar_t replace_name[MAX_PATH];
\r
837 Zero(replace_name, sizeof(replace_name));
\r
841 b = ReadDump("@table_name.txt");
\r
844 char *s = CfgReadNextLine(b);
\r
847 if (IsEmptyStr(s) == false)
\r
849 StrToUni(replace_name, sizeof(replace_name), s);
\r
850 filename = replace_name;
\r
858 ret = LoadTableMain(filename);
\r