source: lab.git/Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Pack.c @ 86521dd

trunk
Last change on this file since 86521dd was a1bae3e, checked in by mitty <mitty@…>, 12 years ago
  • copy vendor drop to trunk

git-svn-id: https://lab.mitty.jp/svn/lab/trunk@147 7d2118f6-f56c-43e7-95a2-4bb3031d96e7

  • Property mode set to 100644
File size: 16.2 KB
Line 
1// SoftEther UT-VPN SourceCode
2//
3// Copyright (C) 2004-2010 SoftEther Corporation.
4// Copyright (C) 2004-2010 University of Tsukuba, Japan.
5// Copyright (C) 2003-2010 Daiyuu Nobori.
6// All Rights Reserved.
7//
8// http://utvpn.tsukuba.ac.jp/
9//
10// This program is free software; you can redistribute it and/or
11// modify it under the terms of the GNU General Public License
12// version 2 as published by the Free Software Foundation.
13//
14// This program is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17// GNU General Public License for more details.
18//
19// You should have received a copy of the GNU General Public License version 2
20// along with this program; if not, write to the Free Software
21// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22//
23// このファイルは GPL バージョン 2 ライセンスで公開されています。
24// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
25// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
26// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
27// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
28//
29// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
30// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
31// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
32// ホストされています。
33// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
34// および、試験または研究のために利用が行われることを想定して配布
35// しています。
36// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
37// あります。
38// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
39// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
40// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
41// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
42// に組み込みさせていただきます。
43//
44// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
45// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
46//
47// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
48// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
49// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
50// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
51// ください。
52//
53// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
54// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
55// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
56// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
57// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
58// 公益保護にご協力いただきますようお願い申し上げます。
59//
60// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
61// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
62// を保護するための努力を行います。
63//
64// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
65// 日本国内の脆弱性情報届出受付公的機関:
66//         独立行政法人 情報処理推進機構
67//         http://www.ipa.go.jp/security/vuln/report/
68//
69// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
70// 連絡先: http://www.softether.co.jp/jp/contact/
71
72// -----------------------------------------------
73// [ChangeLog]
74// 2010.05.20
75//  新規リリース by SoftEther
76// -----------------------------------------------
77
78// Pack.c
79// データパッケージコード
80
81#include <stdio.h>
82#include <stdlib.h>
83#include <string.h>
84#include <wchar.h>
85#include <stdarg.h>
86#include <time.h>
87#include <errno.h>
88#include <Mayaqua/Mayaqua.h>
89
90// BUF を PACK に変換
91PACK *BufToPack(BUF *b)
92{
93    PACK *p;
94    // 引数チェック
95    if (b == NULL)
96    {
97        return NULL;
98    }
99
100    p = NewPack();
101    if (ReadPack(b, p) == false)
102    {
103        FreePack(p);
104        return NULL;
105    }
106
107    return p;
108}
109
110// PACK を BUF に変換
111BUF *PackToBuf(PACK *p)
112{
113    BUF *b;
114    // 引数チェック
115    if (p == NULL)
116    {
117        return NULL;
118    }
119
120    b = NewBuf();
121    WritePack(b, p);
122
123    return b;
124}
125
126// PACK を読み込む
127bool ReadPack(BUF *b, PACK *p)
128{
129    UINT i, num;
130    // 引数チェック
131    if (b == NULL || p == NULL)
132    {
133        return false;
134    }
135
136    // ELEMENT 数
137    num = ReadBufInt(b);
138    if (num > MAX_ELEMENT_NUM)
139    {
140        // 個数オーバー
141        return false;
142    }
143
144    // ELEMENT を読み込む
145    for (i = 0;i < num;i++)
146    {
147        ELEMENT *e;
148        e = ReadElement(b);
149        if (AddElement(p, e) == false)
150        {
151            // 追加エラー
152            return false;
153        }
154    }
155
156    return true;
157}
158
159// PACK を書き出す
160void WritePack(BUF *b, PACK *p)
161{
162    UINT i;
163    // 引数チェック
164    if (b == NULL || p == NULL)
165    {
166        return;
167    }
168
169    // ELEMENT 数
170    WriteBufInt(b, LIST_NUM(p->elements));
171
172    // ELEMENT を書き出す
173    for (i = 0;i < LIST_NUM(p->elements);i++)
174    {
175        ELEMENT *e = LIST_DATA(p->elements, i);
176        WriteElement(b, e);
177    }
178}
179
180// ELEMENT を読み込む
181ELEMENT *ReadElement(BUF *b)
182{
183    UINT i;
184    char name[MAX_ELEMENT_NAME_LEN + 1];
185    UINT type, num_value;
186    VALUE **values;
187    ELEMENT *e;
188    // 引数チェック
189    if (b == NULL)
190    {
191        return NULL;
192    }
193
194    // 名前
195    if (ReadBufStr(b, name, sizeof(name)) == false)
196    {
197        return NULL;
198    }
199
200    // 項目の種類
201    type = ReadBufInt(b);
202
203    // 項目数
204    num_value = ReadBufInt(b);
205    if (num_value > MAX_VALUE_NUM)
206    {
207        // 個数オーバー
208        return NULL;
209    }
210
211    // VALUE
212    values = (VALUE **)Malloc(sizeof(VALUE *) * num_value);
213    for (i = 0;i < num_value;i++)
214    {
215        values[i] = ReadValue(b, type);
216    }
217
218    // ELEMENT を作成
219    e = NewElement(name, type, num_value, values);
220
221    Free(values);
222
223    return e;
224}
225
226// ELEMENT を書き出す
227void WriteElement(BUF *b, ELEMENT *e)
228{
229    UINT i;
230    // 引数チェック
231    if (b == NULL || e == NULL)
232    {
233        return;
234    }
235
236    // 名前
237    WriteBufStr(b, e->name);
238    // 項目の種類
239    WriteBufInt(b, e->type);
240    // 項目数
241    WriteBufInt(b, e->num_value);
242    // VALUE
243    for (i = 0;i < e->num_value;i++)
244    {
245        VALUE *v = e->values[i];
246        WriteValue(b, v, e->type);
247    }
248}
249
250// VALUE を読み込む
251VALUE *ReadValue(BUF *b, UINT type)
252{
253    UINT len;
254    BYTE *u;
255    void *data;
256    char *str;
257    wchar_t *unistr;
258    UINT unistr_size;
259    UINT size;
260    UINT u_size;
261    VALUE *v = NULL;
262    // 引数チェック
263    if (b == NULL)
264    {
265        return NULL;
266    }
267
268    // データ項目
269    switch (type)
270    {
271    case VALUE_INT:         // 整数
272        v = NewIntValue(ReadBufInt(b));
273        break;
274    case VALUE_INT64:
275        v = NewInt64Value(ReadBufInt64(b));
276        break;
277    case VALUE_DATA:        // データ
278        size = ReadBufInt(b);
279        if (size > MAX_VALUE_SIZE)
280        {
281            // サイズオーバー
282            break;
283        }
284        data = Malloc(size);
285        if (ReadBuf(b, data, size) != size)
286        {
287            // 読み込み失敗
288            Free(data);
289            break;
290        }
291        v = NewDataValue(data, size);
292        Free(data);
293        break;
294    case VALUE_STR:         // ANSI 文字列
295        len = ReadBufInt(b);
296        if ((len + 1) > MAX_VALUE_SIZE)
297        {
298            // サイズオーバー
299            break;
300        }
301        str = Malloc(len + 1);
302        // 文字列本体
303        if (ReadBuf(b, str, len) != len)
304        {
305            // 読み込み失敗
306            Free(str);
307            break;
308        }
309        str[len] = 0;
310        v = NewStrValue(str);
311        Free(str);
312        break;
313    case VALUE_UNISTR:      // Unicode 文字列
314        u_size = ReadBufInt(b);
315        if (u_size > MAX_VALUE_SIZE)
316        {
317            // サイズオーバー
318            break;
319        }
320        // UTF-8 の読み込み
321        u = ZeroMalloc(u_size + 1);
322        if (ReadBuf(b, u, u_size) != u_size)
323        {
324            // 読み込み失敗
325            Free(u);
326            break;
327        }
328        // Unicode 文字列に変換
329        unistr_size = CalcUtf8ToUni(u, u_size);
330        if (unistr_size == 0)
331        {
332            Free(u);
333            break;
334        }
335        unistr = Malloc(unistr_size);
336        Utf8ToUni(unistr, unistr_size, u, u_size);
337        Free(u);
338        v = NewUniStrValue(unistr);
339        Free(unistr);
340        break;
341    }
342
343    return v;
344}
345
346// VALUE を書き出す
347void WriteValue(BUF *b, VALUE *v, UINT type)
348{
349    UINT len;
350    BYTE *u;
351    UINT u_size;
352    // 引数チェック
353    if (b == NULL || v == NULL)
354    {
355        return;
356    }
357
358    // データ項目
359    switch (type)
360    {
361    case VALUE_INT:         // 整数
362        WriteBufInt(b, v->IntValue);
363        break;
364    case VALUE_INT64:       // 64 bit 整数
365        WriteBufInt64(b, v->Int64Value);
366        break;
367    case VALUE_DATA:        // データ
368        // サイズ
369        WriteBufInt(b, v->Size);
370        // 本体
371        WriteBuf(b, v->Data, v->Size);
372        break;
373    case VALUE_STR:         // ANSI 文字列
374        len = StrLen(v->Str);
375        // 長さ
376        WriteBufInt(b, len);
377        // 文字列本体
378        WriteBuf(b, v->Str, len);
379        break;
380    case VALUE_UNISTR:      // Unicode 文字列
381        // UTF-8 に変換する
382        u_size = CalcUniToUtf8(v->UniStr) + 1;
383        u = ZeroMalloc(u_size);
384        UniToUtf8(u, u_size, v->UniStr);
385        // サイズ
386        WriteBufInt(b, u_size);
387        // UTF-8 文字列本体
388        WriteBuf(b, u, u_size);
389        Free(u);
390        break;
391    }
392}
393
394// データサイズの取得
395UINT GetDataValueSize(ELEMENT *e, UINT index)
396{
397    // 引数チェック
398    if (e == NULL)
399    {
400        return 0;
401    }
402    if (e->values == NULL)
403    {
404        return 0;
405    }
406    if (index >= e->num_value)
407    {
408        return 0;
409    }
410    if (e->values[index] == NULL)
411    {
412        return 0;
413    }
414
415    return e->values[index]->Size;
416}
417
418// データの取得
419void *GetDataValue(ELEMENT *e, UINT index)
420{
421    // 引数チェック
422    if (e == NULL)
423    {
424        return NULL;
425    }
426    if (e->values == NULL)
427    {
428        return NULL;
429    }
430    if (index >= e->num_value)
431    {
432        return NULL;
433    }
434    if (e->values[index] == NULL)
435    {
436        return NULL;
437    }
438
439    return e->values[index]->Data;
440}
441
442// Unicode 文字列型の取得
443wchar_t *GetUniStrValue(ELEMENT *e, UINT index)
444{
445    // 引数チェック
446    if (e == NULL)
447    {
448        return 0;
449    }
450    if (index >= e->num_value)
451    {
452        return 0;
453    }
454
455    return e->values[index]->UniStr;
456}
457
458// ANSI 文字列型の取得
459char *GetStrValue(ELEMENT *e, UINT index)
460{
461    // 引数チェック
462    if (e == NULL)
463    {
464        return 0;
465    }
466    if (index >= e->num_value)
467    {
468        return 0;
469    }
470
471    return e->values[index]->Str;
472}
473
474// 64 bit 整数型値の取得
475UINT64 GetInt64Value(ELEMENT *e, UINT index)
476{
477    // 引数チェック
478    if (e == NULL)
479    {
480        return 0;
481    }
482    if (index >= e->num_value)
483    {
484        return 0;
485    }
486
487    return e->values[index]->Int64Value;
488}
489
490// 整数型値の取得
491UINT GetIntValue(ELEMENT *e, UINT index)
492{
493    // 引数チェック
494    if (e == NULL)
495    {
496        return 0;
497    }
498    if (index >= e->num_value)
499    {
500        return 0;
501    }
502
503    return e->values[index]->IntValue;
504}
505
506// PACK のソート関数
507int ComparePackName(void *p1, void *p2)
508{
509    ELEMENT *o1, *o2;
510    if (p1 == NULL || p2 == NULL)
511    {
512        return 0;
513    }
514    o1 = *(ELEMENT **)p1;
515    o2 = *(ELEMENT **)p2;
516    if (o1 == NULL || o2 == NULL)
517    {
518        return 0;
519    }
520
521    return StrCmpi(o1->name, o2->name);
522}
523
524// VALUE の削除
525void FreeValue(VALUE *v, UINT type)
526{
527    // 引数チェック
528    if (v == NULL)
529    {
530        return;
531    }
532
533    switch (type)
534    {
535    case VALUE_INT:
536    case VALUE_INT64:
537        break;
538    case VALUE_DATA:
539        Free(v->Data);
540        break;
541    case VALUE_STR:
542        Free(v->Str);
543        break;
544    case VALUE_UNISTR:
545        Free(v->UniStr);
546        break;
547    }
548
549    // メモリ解放
550    Free(v);
551}
552
553// Unicode 文字列型の VALUE の作成
554VALUE *NewUniStrValue(wchar_t *str)
555{
556    VALUE *v;
557    // 引数チェック
558    if (str == NULL)
559    {
560        return NULL;
561    }
562
563    // メモリ確保
564    v = Malloc(sizeof(VALUE));
565
566    // 文字列コピー
567    v->Size = UniStrSize(str);
568    v->UniStr = Malloc(v->Size);
569    UniStrCpy(v->UniStr, v->Size, str);
570
571    UniTrim(v->UniStr);
572
573    return v;
574}
575
576// ANSI 文字列型の VALUE の作成
577VALUE *NewStrValue(char *str)
578{
579    VALUE *v;
580    // 引数チェック
581    if (str == NULL)
582    {
583        return NULL;
584    }
585
586    // メモリ確保
587    v = Malloc(sizeof(VALUE));
588
589    // 文字列コピー
590    v->Size = StrLen(str) + 1;
591    v->Str = Malloc(v->Size);
592    StrCpy(v->Str, v->Size, str);
593
594    Trim(v->Str);
595
596    return v;
597}
598
599// データ型の VALUE の作成
600VALUE *NewDataValue(void *data, UINT size)
601{
602    VALUE *v;
603    // 引数チェック
604    if (data == NULL)
605    {
606        return NULL;
607    }
608
609    // メモリ確保
610    v = Malloc(sizeof(VALUE));
611
612    // データコピー
613    v->Size = size;
614    v->Data = Malloc(v->Size);
615    Copy(v->Data, data, size);
616
617    return v;
618}
619
620// 64 bit 整数型の VALUE の作成
621VALUE *NewInt64Value(UINT64 i)
622{
623    VALUE *v;
624
625    v = Malloc(sizeof(VALUE));
626    v->Int64Value = i;
627    v->Size = sizeof(UINT64);
628
629    return v;
630}
631
632// 整数型の VALUE の作成
633VALUE *NewIntValue(UINT i)
634{
635    VALUE *v;
636
637    // メモリ確保
638    v = Malloc(sizeof(VALUE));
639    v->IntValue = i;
640    v->Size = sizeof(UINT);
641
642    return v;
643}
644
645// ELEMENT の削除
646void FreeElement(ELEMENT *e)
647{
648    UINT i;
649    // 引数チェック
650    if (e == NULL)
651    {
652        return;
653    }
654
655    for (i = 0;i < e->num_value;i++)
656    {
657        FreeValue(e->values[i], e->type);
658    }
659    Free(e->values);
660
661    Free(e);
662}
663
664// ELEMENT の作成
665ELEMENT *NewElement(char *name, UINT type, UINT num_value, VALUE **values)
666{
667    ELEMENT *e;
668    UINT i;
669    // 引数チェック
670    if (name == NULL || num_value == 0 || values == NULL)
671    {
672        return NULL;
673    }
674
675    // メモリ確保
676    e = Malloc(sizeof(ELEMENT));
677    StrCpy(e->name, sizeof(e->name), name);
678    e->num_value = num_value;
679    e->type = type;
680
681    // 要素へのポインタリストのコピー
682    e->values = (VALUE **)Malloc(sizeof(VALUE *) * num_value);
683    for (i = 0;i < e->num_value;i++)
684    {
685        e->values[i] = values[i];
686    }
687
688    return e;
689}
690
691// PACK から ELEMENT を検索して取得
692ELEMENT *GetElement(PACK *p, char *name, UINT type)
693{
694    ELEMENT t;
695    ELEMENT *e;
696    // 引数チェック
697    if (p == NULL || name == NULL)
698    {
699        return NULL;
700    }
701
702    // 検索
703    StrCpy(t.name, sizeof(t.name), name);
704    e = Search(p->elements, &t);
705
706    if (e == NULL)
707    {
708        return NULL;
709    }
710
711    // 型検査
712    if (type != INFINITE)
713    {
714        if (e->type != type)
715        {
716            return NULL;
717        }
718    }
719
720    return e;
721}
722
723// PACK から ELEMENT を削除
724void DelElement(PACK *p, char *name)
725{
726    ELEMENT *e;
727    // 引数チェック
728    if (p == NULL || name == NULL)
729    {
730        return;
731    }
732
733    e = GetElement(p, name, INFINITE);
734    if (e != NULL)
735    {
736        Delete(p->elements, e);
737
738        FreeElement(e);
739    }
740}
741
742// PACK に ELEMENT を追加
743bool AddElement(PACK *p, ELEMENT *e)
744{
745    // 引数チェック
746    if (p == NULL || e == NULL)
747    {
748        return false;
749    }
750
751    // サイズチェック
752    if (LIST_NUM(p->elements) >= MAX_ELEMENT_NUM)
753    {
754        // これ以上追加できない
755        FreeElement(e);
756        return false;
757    }
758
759    // 同じ名前が存在しないかどうかチェック
760    if (GetElement(p, e->name, INFINITE))
761    {
762        // 存在している
763        FreeElement(e);
764        return false;
765    }
766
767    if (e->num_value == 0)
768    {
769        // 項目が 1 つも存在していない VALUE は追加できない
770        FreeElement(e);
771        return false;
772    }
773
774    // 追加
775    Add(p->elements, e);
776    return true;
777}
778
779// PACK オブジェクトの解放
780void FreePack(PACK *p)
781{
782    UINT i;
783    ELEMENT **elements;
784    // 引数チェック
785    if (p == NULL)
786    {
787        return;
788    }
789
790    elements = ToArray(p->elements);
791    for (i = 0;i < LIST_NUM(p->elements);i++)
792    {
793        FreeElement(elements[i]);
794    }
795    Free(elements);
796
797    ReleaseList(p->elements);
798    Free(p);
799}
800
801// PACK オブジェクトの作成
802PACK *NewPack()
803{
804    PACK *p;
805
806    // メモリ確保
807    p = MallocEx(sizeof(PACK), true);
808
809    // リスト作成
810    p->elements = NewListFast(ComparePackName);
811
812    return p;
813}
814
815
Note: See TracBrowser for help on using the repository browser.